Day12
方法的重写(override,overwrite)
-
在子类继承父类之后,可以对父类中的同名同参数的方法进行覆盖。
要求:方法名和形参列表都要一样,否则就是重载,而非重写
-
重写之后,当创建子类对象之后,通过子类对象调用子,父类中同名同参方法,世界上调用子类重写之后 的方法
-
重写的规定:
- 子类重写的方法名和形参列表和父类被重写的方法名和形参列表相同
- 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
- 子类不能重写父类中private的方法
- 返回值类型:
- 如果父类被重写的方法的返回值是void,则子类必须是void
- 父类被重写的方法的返回值是A类,则子类重写的方法的返回值可以是A类或A类的子类
- 父类被重写的方法的返回值为基本数据类型,则子类重写的方法的返回值必须是相同的基本数据类型
- 子类重写的方法抛出的异常的类型不大于父类被重写的方法抛出的异常的类型
-
子类和父类中同名同参的方法要么都为非static(考虑重写),要么都声明为static(不是重写)
super
-
理解为:父类的
-
可以用来调用:属性,方法,构造器
-
一般使用:
-
可以在子类的方法或构造器中,通过"super."的方式调用父类的属性或方法,通常情况下省略(属性在内存中不会像方法一样被覆盖,有两个同名属性,默认调用子类,this调用子类,super调用父类)
this.data;// 子类中的data super.data;//父类中的data //考虑 ID 和 身份证号 和 学生证号 等的 关系
-
子类父类中定义同名的属性时,默认调用子类的,使用super可以调用父类中声明的属性
-
当子类重写父类中的方法后,我们想在子类的方法中调用父类中被重写方法,必须使用super
-
-
调用构造器
- 我们可以在子类的构造器中显式地使用”super(参数列表)“的方式,调用父类中声明的指定的构造器
- ”super(形参列表)“的使用,必须声明在子类构造器的首行
- 在类的构造器中”this()”和“super()”只能二选一,不能同时出现
- 在构造器的首行没有显示地声明“this()”或“super()”,默认调用父类中无参构造器
子类对象实例化的过程
-
结果上看:(继承性)
子类继承父类后,自动获得父类定义的属性和方法
创建子类对象,在堆空间中就加载类父类定义的属性
-
从过程上看:
通过子类的构造器创建对象时,一定会直接或间接地调用其父类的构造器,从而调用父类的父类的构造器
直到调用java.lang.Object的无参构造器,因为加载过所有父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以调用
==虽然重建子类对象的时候调用过父类的构造器,但自始至终仅创建过一个对象,即为子类对象。
多态
理解:一个事物的多种形态。以下讲解什么时多态性。
对象的多态性
可以声明父类对象承载子类对象父类的引用指向子类的对象
Person p = new Man();
-
通过这种形式调用子父类同名同参的方法时,实际调用的时子类重写的方法——————虚拟方法调用
在编译期,只能调用父类声明的方法,在运行的 时候,实际执行的是子类重写的方法
让秘书去叫一个人,秘书可以叫一个男人或者一个女人。
- 但是无法调用子类特有的方法和属性
- 多态的使用前提
- 类的继承关系
- 方法重写
多态不适用于属性
### 虚拟方法调用
在子类中定义于父类同名同参的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它 的不同子类对象动态地调用子类的方法。这样的方法调用在编译期间时无法确定的,而是在运行时确定。——动态绑定
多态是运行时行为
证明如下:
用随机数进行选择子类,然后调用,只有运行时才能确定调用的是哪个子类的方法
对于重载,他们的调用地址在编译期间就已经绑定了,在调用之前,编译器就知道要调用的方法。这称为“早绑定”或“静态绑定”
对于多态,只有等方法调用的那一刻,编译器(?)才确定所要调用的方法。这称为“晚绑定”或“动态绑定”
不要犯傻,如果他不是晚绑定,他就不是多态——Bruce Eckel