目录
一、继承
1、继承的概念
继承是面向对象编程中的一个重要概念,是一种类与类之间的关系,子类可以获取父类的成员(包括属性和方法),并可以在此基础上添加自己的新成员属性和方法,还可以重写父类的方法。
继承的最大作用就是实现代码的复用
注意:
- 在java中的类只有单继承,没有多继承
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类,超类)
2、extends关键字
那么如何实现继承,我们需要借助extends关键字来实现。
例如我们定义4个类:Animal类、Dog类、Cat类、Test类,让Dog类和Cat类继承Animal类,Test类用来测试我们的代码。
如图我们可以通过引用加点的方式来访问父类的属性和方法,也可以访问子类自己的属性和方法。
二、父类的访问
1、访问变量
父类和子类的变量不同名
父类和子类中有同名的变量
在子类方法中或者子类对象访问成员时 :
- 如果访问的成员变量子类有,优先访问子类自己的
- 如果访问的成员变量子类没有,则访问父类的,如果父类中也没有,则会编译报错
- 如果同名优先访问子类自己的
2、访问方法
方法名不同:
方法名相同:
由此可知方法的访问和变量的访问结果一样。
3、super关键字
如果要在子类中访问和父类同名的成员,就要依靠super关键字来实现。
如图使用了super关键字,在同名的时候可以调用父类的成员。
super和this的区别:
相同点:
- 都是java中的关键字
- 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
- 在构造方法中调用时,必须是构造方法的第一条语句,不能同时存在
不同点:
- this是当前对象的引用,super相当于是子类继承父类下对父类部分成员的引用
-
在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
-
在构造方法中:this(···)用来调用本类的构造方法,super(···)用来调用父类的构造方法,不能同时出现
-
构造方法中一定会出现super(···)的调用,即使自己没写,编译器也会自己生成,而this(···)不写则不会有
4、继承关系上构造方法和成员方法访问特点
继承关系中构造方法:
如果父类没有写构造方法,子类中的构造方法默认都会访问父类中无参的构造方法。
子类会继承父类的数据,可能还会使用父类的数据,所以子类在初始化之前会先完成父类的初始化。
每个子类构造方法的第一句会默认为super();
继承关系中的成员方法:
先在子类中找,如果没有就在父类成员中找,没有则报错。
三、代码块在继承关系上的执行顺序
静态代码块,实例代码块与构造方法在继承关系上的执行顺序
根据以上运行结果可知:
- 静态代码块优先于实例代码块优先于构造方法
- 不管实例化几次对象静态代码块只会执行一次
- 父类的静态优先然后是子类的静态,之后是父类的实例、构造方法,最后是子类的实例、构造方法
四、protected关键字
被protected修饰的成员变量访问权限,上两个我们已经可以理解了,我们现在来理解第三个
操作:
首先创建两个包:demo1,demo2,在demo1中创建父类Fu,在demo2中创建Zi类继承Fu类
以上表明protected访问修饰限定符可以在不同包中的子类中访问。
五、多态
1、多态的概念
多态是指同一个行为具有多种不同表现形式或形态的能力,具体一点就是当不同对象去完成同一行为时会产生不同的状态。
eg:猫和狗吃食物,猫吃猫粮,狗吃狗粮
2、多态的实现条件
- 必须在继承体系下
- 子类必须对父类中的方法进行重写
- 通过父类引用调用重写的方法(动态绑定)
在上述代码中,Animal是父类,Dog
和 Cat
类是它的子类,通过将父类的引用变量分别指向子类对象,实现了多态性。
六、重写
1、重写的概念
重写是指在子类中重新定义父类已存在的方法,子类可以根据自身的需求对父类的方法进行不同的实现,从而实现多态性。
方法重写的规则:
- 子类在重写父类的方法时,一般要与父类的方法原型保持一致:返回值类型 方法名 (参数列表)要完全一致
- 被重写的方法返回值类型可以不同,但必须具有父子关系
- 子类的访问权限必须大于等于父类中被重写的方法的访问权限
- 父类被static、private修饰的方法、构造方法都不能被重写
2、重写和重载的区别
相同点:
方法名:重写和重载都允许在程序中存在多个同名的方法
不同点:
- 定义位置:重写发生在子类与父类之间,而重载在一个类中
- 参数列表:重写要求参数列表必须相同,重载要求参数列表不同
- 返回类型:重写的返回类型通常相同或返回其子类型,重载的返回类型可以不同
- 访问修饰符:重写时子类方法的访问修饰符访问权限必须大于等于父类的,重载的访问修饰符可以独立设置
- 异常声明:重写时子类方法抛出的异常不能更宽泛,重载方法可根据自身逻辑抛出不同异常
七、向上转型和向下转型
1、向上转型
向上转型:是指将子类对象转换为父类类型的过程
语法格式:父类类型 对象名 = new 子类类型();
向上转型的优点:让代码实现更简单灵活
缺点:不能调用到子类特有的方法
2、向下转型
向下转型:是指将父类类型的变量转化为子类类型的过程
注意:向下转型不安全,万一转换失败,运行时就会抛出异常,java中为了提高向下转型的安全性,引入了instanceof关键字,如果该表达式为true,则可以安全转换。
通过向下转型可以调用子类中自己的方法,不过要进行判断,确保安全性。
八、多态的优缺点
优点:
- 可维护性增强,可扩展性提高:当程序要求发生变化时,需要修改或添加新的子类行为时,不需要大规模修改,方便添加新子类来扩展功能
- 代码复用性更好,可读性提高:多态允许在父类中定义通用的方法和属性,子类可以继承并根据需要进行重写或扩展
缺点:
- 性能损耗:多态会进行动态绑定,会带来一定的性能开销
- 调试难度增加:由于动态性,在运行时才能确定具体调用的是哪个子类方法,很难快速定位哪个子类的方法实现出现了错误
- 理解成本上升
九、避免在构造方法中调用重写的方法
根据运行结果可知:
1、在构造D对象的同时,会调用B的构造方法
2、在B的构造方法中调用了func方法,会触发动态绑定,在运行时会调用到D中的func方法
3、此时D对象自身还没有构造,num未初始化所以为0
所以尽量不要在构造方法中调用重写的方法