面向对象2
多态
向上转型
例如:
Bird bird = new Bird("圆圆"); 该代码也可以写成下面的形式: Bird bird = new Bird("圆圆"); Animal bird2 = bird; // 或者写成下面的方式 Animal bird2 = new Bird("圆圆"); 123456
此时 bird2 是一个父类 (Animal) 的引用, 指向一个子类 (Bird) 的实例. 这种写法称为 向上转型。
向上转型发生的时机:
1.直接赋值
2.方法传参
3.方法返回
方法传参
public class Test {public static void main(String[] args) {Bird bird = new Bird("圆圆");feed(bird);} public static void feed(Animal animal) {animal.eat("谷子"); } } // 执行结果 圆圆正在吃谷子 12345678910
方法返回
public class Test {public static void main(String[] args) {Animal animal = findMyAnimal();} public static Animal findMyAnimal() {Bird bird = new Bird("圆圆");return bird; } } 123456789
动态绑定
在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引 用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期),因此称为动态绑定。
方法重写
子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override).
关于重写的注意事项:
1.重写和重载完全不一样. 不要混淆(思考一下, 重载的规则是啥?)
2. 普通方法可以重写, static 修饰的静态方法不能重写.
3. 重写中子类的方法的访问权限不能低于父类的方法访问权限.
小结(重写和重载的区别):
重写/覆盖/复写:
1.函数名相同 子类的访问修饰限定符一定要大于等于父类的访问修饰限定符
2.参数列表相同 父类的方法不能是私有的
3.返回值也要相同
4.静态的方法和private不能被重写
重载(Overload):
1.函数名相同
2.参数列表不同(个数、类型)
3.返回值不做要求
理解多态
代码示例: 打印多种形状
//类的实现 class Shape {public void draw() {// 啥都不用干} } class Cycle extends Shape {@Overridepublic void draw() {System.out.println("○");} } class Rect extends Shape {@Overridepublic void draw() {System.out.println("□");} } class Flower extends Shape {@Overridepublic void draw() {System.out.println("♣");} } //类的调用 // Test.java public class Test {public static void main(String[] args) {Shape shape1 = new Flower();Shape shape2 = new Cycle();Shape shape3 = new Rect();drawMap(shape1);drawMap(shape2);drawMap(shape3); } // 打印单个图形public static void drawShape(Shape shape) {shape.draw();} }
1234567891011121314151617181920212223242526272829303132333435363738394041当类的调用者在编写 drawMap 这个方法的时候, 参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当 前的 shape 引用指向的是哪个类型(哪个子类)的实例. 此时 shape 这个引用调用 draw 方法可能会有多种不同的表现 (和 shape 对应的实例相关), 这种行为就称为 多态.
使用多态的好处:
类调用者对类的使用成本进一步降低.封装是让类的调用者不需要知道类的实现细节.
多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可.
因此, 多态可以理解成是封装的更进一步, 让类调用者对类的使用成本进一步降低.能够降低代码的 “圈复杂度”, 避免使用大量的 if - else可扩展能力更强.
如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.
向下转型
向上转型是子类对象转成父类对象, 向下转型就是父类对象转成子类对象. 相比于向上转型来说, 向下转型没那么常见, 但是也有一定的用途.
向下转型的前提条件是:父类已经引用了子类(向下转型后的类型)的对象
super 关键字
前面的代码中由于使用了重写机制, 调用到的是子类的方法. 如果需要在子类内部调用父类方法可以使用 super 关键字.
super 表示获取到父类实例的引用. 涉及到两种常见用法.
public Bird(String name) {super(name); } 123 使用 super 来调用父类的普通方法
public class Bird extends Animal {public Bird(String name) {super(name);} @Override public void eat(String food) {// 修改代码, 让子调用父类的接口.super.eat(food);System.out.println("我是一只小鸟");System.out.println(this.name + "正在吃" + food); } } 123456789101112
在这个代码中, 如果在子类的 eat 方法中直接调用 eat (不加super), 那么此时就认为是调用子类自己的 eat (也就是递 归了). 而加上 super 关键字, 才是调用父类的方法.
super 和 this 的区别:
1.概念:
this:访问本类中的属性和方法;
super:由子类访问父类中的属性、方法
2.查找范围:
this:先查找本类,如果本类没有就调用父类
super:不查找本类而直接调用父类
3.this表示当前对象
抽象类
语法规则
在刚才的打印图形例子中, 我们发现, 父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由 Shape 的各种子类的 draw 方法来完成的. 像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法(abstract method), 包含抽象方法的类我们称为 抽象类(abstract class).
abstract class Shape {abstract public void draw(); } 123
在 draw 方法前加上 abstract 关键字, 表示这是一个抽象方法.
同时抽象方法没有方法体(没有 { }, 不能执行具体代码). 对于包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.
注意事项
抽象类的作用
1.抽象类存在的最大意义就是为了被继承.
2.抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.
接口
接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含 静态常量.
语法规则
interface IShape {void draw(); } class Cycle implements IShape {@Overridepublic void draw() {System.out.println("○");} } public class Test {public static void main(String[] args) {IShape shape = new Rect();shape.draw();} } 123456789101112131415 使用 interface 定义一个接口接口中的方法一定是抽象方法, 因此可以省略 abstract接口中的方法一定是 public, 因此可以省略 publicCycle 使用 implements 继承接口. 此时表达的含义不再是 “扩展”, 而是 “实现”在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.接口不能单独被实例化
接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).
interface IShape {void draw();public static final int num = 10; } 1234
其中的 public, static, final 的关键字都可以省略. 省略后的 num 仍然表示 public 的静态常量
注意:
1.创建接口的时候, 接口的命名一般以大写字母 I 开头.
2.接口的命名一般使用 “形容词” 词性的单词.
3.阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性。
接口间的继承
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.
interface IRunning {void run(); } interface ISwimming {void swim(); } // 两栖的动物, 既能跑, 也能游 interface IAmphibious extends IRunning, ISwimming { } class Frog implements IAmphibious {... } 1234567891011121314
通过接口继承创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就继续要实现 run 方法, 也需要实现 swim 方法.
接口间的继承相当于把多个接口合并在一起。
总结
抽象类和接口的区别:
核心区别:抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不 能包含普通方法, 子类必须重写所有的抽象方法。
区别:
相关知识
面向对象基本思想:面向对象=对象+类+继承+通信
面向对象的病虫害数据库研究与建立
面向对象
【JAVA】Java基础—面向对象编程:类与对象
面向对象网上花店管理系统
html5 canvas绘制圆形、方形矩形、线段、图片等各种图形(面向对象版本)
面向对象网上花店管理系统设计图 流程图模板
类和对象(上)
js 面向对象方式 动画效果:花瓣雨
给对象的小惊喜c#玫瑰花
网址: 面向对象2 https://www.huajiangbk.com/newsview948926.html
上一篇: 基于vue 做了关于token验 |
下一篇: PHP自动售货发卡网源码 集成多 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039