一.继承
1.继承:就是对共性的抽取,从而达到对代码的复用(重复使用)
子类/派生类
父类/基类/超类
继承(extends)这个新的类
如上,子类是Dog和Cat,父类是Animal,则称作子类继承了父类。
当子类继承了父类之后,就会把父类属性和方法全部继承
语法: class 子类 extends 父类
注意:私有的成员(private)可以被继承,但是不能被访问。(访问用get())
2.通过子类对象访问成员
如果访问的成员变量子类中有,优先访问自己的成员变量。
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
如果访问的成员变量与父类中的成员变量同名,则优先访问自己的。
成员变量访问遵循就近原则,自己有优先自己,如果没有则向父类中找。
在子类中访问父类:super.父类成员变量
super.a=10; 是给父类Base中的a赋值,而子类中的a没有赋值,a为0。 就近原则举例:
注意:当子类和父类有同名的方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法传递的参数确定对应的方法。
子类中访问子类直接访问eg:访问子类的name
在子类中访问父类时,加上super.访问名
super.与this.的区别
super.data;访问父类的普通成员变量
super.func();调用父类的普通成员方法
super();调用父类的构造方法
注意:static相关不建议用super或者this访问,所有的静态变量都建议用(类名.)访问
构造方法需要注意的问题:
1.父类构造含参,则子类接收也要含参数
2.初始化时必须先给父类初始化,super()必须放在第一行
super()虽然执行了父类的构造方法,但是没有生成父类的对象,这里只是帮助子类初始化从父类继承过来的属性。
总结:
1.父类显示定义无参或者默认的构造方法时,子类构造方法编译器自动默认第一行是super()
2.若父类构造方法带有参数,此时需要显式定义构造方法
3.子类构造方法时,super()调用父类构造时,必须是子类构造中的第一条。
4.super()只能在子类构造中出现一次,并且不能和this同时出现。
this和super的相同点:
1.只能在非静态方法中使用,用来访问非静态成员方法和字段。
2.在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在。
this和super的不同点:
1.this访问本类的方法和属性,super访问父类继承下来的方法和属性
2.super不写编译器也默认增加,this不写就没有。
打印顺序问题:
分析打印顺序:
观察可得:打印顺序是 静态代码块+实例代码块+构造方法
观察可得:当父类下的子类大于一时,父类的静态代码块只打印一次,提高了效率。
当子类变量对象大于一时,子类的静态代码块也只打印一次
protected关键字
1.同一个包中的同一类
2.同一个包中的不同类
类1
类2
运行类2,可以得到类1中的a
3.不同包中的子类
Java中的几种继承方式
注意:一般不建议三层以上的继承关系
final关键字:当是继承的最后一层时,可以用关键字final提醒后面代码,若再出现继承关系时,编译器会报错。
final修饰的称为密封类
当final修饰一个变量时,表示该变量不能再被赋值。(类比C语言中的const)
继承与组合
继承:可以看作是is --a的关系
class Dog extends Animal --> Dog is a animal
组合:a part of / has-a
学生和老师是学校的一部分;学校有老师和学生
二.多态
多态的概念:多形态,不同的对象去完成时会产生出不同的状态。(对象不一样,行为可能不一样)
实现多态的条件:
1.必须在继承体系下
2.子类必须要对父类中的方法进行重写
3.通过父类的引用调用重写的方法
重写:1.方法名称相同 2.参数列表相同
例如:Dog是Animal下的继承,Animal里有方法eat,现在要改变Dog的eat()方法,却不能影响继承Animal的其他类,此时我们对Dog类进行重写。
注意:1.子类的访问权限 要大于等于父类的访问权限
2. private,final,static修饰的方法不能重写
3.返回值可以不一样,但是父类和子类的返回值也要构成包含关系
4.在重新前添加上@override,可以帮助检查重新是否符合要求
private<default<projected<public,当访问父类权限没有写时,默认是default,此时子类权限可以为default projected public
重写的快捷方法
默认是父类的代码,需要改变的地方自己更改为自己需要的。
重写与重载的区别:
重载:方法名称相同,参数列表不同(数据类型,顺序,个数),返回值不做要求。
重写(一定发生在继承关系上):方法名相同,参数列表相同(数据类型,顺序,个数),返回值相同或者构成父子关系。
重载的使用目的:对于已经投入使用的类,不进行修改,重新定义一个类来添加新添加的东西。
静态绑定与动态绑定:
静态绑定:编译时,根据参数类型不同确定调用哪个方法
动态绑定:编译时不能确定方法的行为,程序运行的时候确定具体的类
向上转型:
1.直接赋值
2.方法的传参过程中,发生的向上转型。
一个引用animal.eat(),调用同一个方法,但是引用的对象不同,导致调用这个方法所表现的行为不一样。这种思想叫做多态。
运行结果:
再举例:
3.作为返回值的向上转型
举例:
向下转型:
向下转型使用较少,使用不当可能会出现类型转换异常。
编译报错:类型转换异常
更改代码,使编译不报错:添加判断条件判断是否是同类型(instanceof)
避免在构造方法中重写:
当在父类当中,调用父类中重写方法的时候,会调用子类的重写方法,但是并没有给子类对象赋值。