继承与多态、super和this
继承
定义
继承 extends: 类中公共的部分(成员变量\方法), 提取出来
好处:
1. 提高代码的复用性。
2. 类与类之间产生了关系,是多态的前提。
继承的特点
1.类和类的继承, 是单继承, 只能有一个父类
2.Object是所有类的超类
3.当类A继承另一个类B, 那么就意味着A拥有了B中"所有的"(不包括私有)属性和方法同时, A 还可以添加自己独特的内容
4.Java支持多层继承 继承的传递性。
继承中构造器的问题:
1.子类不能继承父类构造器!!!!!!!
2.子类默认调用父类的无参构造器 super() (父类成员变量初始化后才可以给子类使用)
继承后的特点 – – 成员变量
子类中有和父类中重名的属性, 在调用时, 是只会获得子类自己的属性,
父类的属性被隐藏。需要使用super.属性才能访问到子类和父类中有重名的属性。
继承后的特点 – – 成员方法
子类中有和父类中重名的方法: 方法的重写/覆盖
对象在调用方法时,会先在子类中查找有没有对应的方法,如果存在就会执行子类中的方法,否则执行父类中相应的方法
本质就是为了修改/增强 父类中的方法
Java语言规范(JLS)中是这么说的:
Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.(https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2)
被声明为私有的类的成员不由该类的子类继承。
只有被声明为受保护或公开的类的成员才由在声明类的包中声明的子类继承。
构造函数,静态初始化器,以及实例的初始化不是成员,所以不能被继承。
多态
定义
同一行为,具有多个不同表现形式
1.一种方法, 多种功能 -> 方法重载
2.一个对象, 多种类型/形态 -> Animal a = new Dog();
前提【重点】
1.继承或者实现
2.方法的重写【不重写,无意义】
3.父类引用指向子类对象【格式体现】
重载
同一个类中, 方法名相同, 参数列表不同(个数,类型,顺序), 和返回值类型与修饰符无关
重写/覆盖
父类A: protected Number method1(int a) throws IOException {}
子类B: protected/public -> 访问修饰符必须更开放
返回值: Number/Integer/Double 子类
方法名, 参数: 必须一样
throws IOException/FileNotFoundException 不能多于父类的异常
private default protected public
补: Number 是 Integer/Double/Short...数字类的包装类型的父类
向上转型
Animal a = new Dog(); 子类类型向父类类型向上转换的过程,这个过程是默认的。
当使用多态调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后的方法
1.编译器认为 a 是 Animal 类型 (编译时)
a 能调用的 是 Animal 里定义的内容
2.JVM判断出 a 是 Dog 对象 (运行时)
最终调用的是 Dog 里的方法
向下转型
Dog a = (Dog) a; 父类类型向子类类型向下转换的过程,这个过程是强制的。适用于已经向上转型的子类对象。
向下造型-强制类型转换: ClassCastException
避免错误: a instanceof Dog
问 a 是不是 Dog对象
super和this
super和this的含义
用法
super(..): 调用父类的构造器, 必须放在构造器的第一行
默认在子类的构造器第一行, 会添加 隐式的super()
为了保证子类在定义时不会出错, 通常父类中会添加一个无参构造器
super.属性: 子类和父类中有重名的属性
super.方法(): 子类和父类中有重名的方法
this(..): 本类的构造方法,也放在构造方法的第一行,所以和super()不能同时出现。
this.属性
this.方法()