继承和多态
作者:互联网
0 概念
.1 继承 关键字:extends 关系:is-a
- 概念:手机和iPhone就像是继承关系,iPhone is a mobile phone。
- 格式:public class Iphone extends Phone{}
- 子类的特点:可以有父类的内容,还可以有自己特有的内容。Iphone可以有电话都有的打电话发信息的功能,还有面部解锁、全景拍照等自己的功能。
- Java中只支持单继承
.2 super关键字和this关键字
- this:代表对本类对象的引用
- super:代表对父类对象的引用
.3 继承中的构造方法-ref:为何需要无参构造?
- 子类中所有构造方法默认都会访问父类中 无参的构造方法
因为子类会继承父类中的数据,还可能使用父类中的数据。 因此子类初始化之前,一定要先完成父类数据的初始化。所以每一个子类构造方法的第一句都是super()。根据关键词的意思,该语句的意思就是引用父类的无参构造。若父类没有无参构造,则编译时会发生错误。
如图所示,A类的有参构造override默认的无参构造,则不具备无参构造。而B想要调用super()是会编译报错的,这也是一个类需要无参构造的原因。(虽然也可以通过super父类有参构造,但是不推荐)
.3 多态
- 什么叫多态?
有继承或实现关系+此方法重写+有父类引用指向子类对象这三个条件是多态的前提。BTW,父类引用指向子类对象的行为又叫做向上转型
- 多态中成员访问的特点
- 成员变量,编译看左边,执行看左边
- 成员方法,编译看左边,执行看右边
成员方法有重写,成员变量没有,所以不一样。
例子:
父类A:成员变量a,一个无参构造,一个有参构造,一个get方法。
子类B:成员变量a,一个重写了父类的无参构造,一个自己仅有的方法onlyB。
测试一下多态的结果:
子类构造执行肯定先执行父类的构造。若没有写super,则默认使用父类的无参构造。
1 例子
通过一个例子加深对继承和多态的理解。
class Test {
public static void main(String[] args) {
System.out.println(new B().getValue());
}
static class A {
protected int value;
public A (int v) {
setValue(v);
}
public void setValue(int value) {
this.value= value;
}
public int getValue() {
try {
value ++;
return value;
} finally {
this.setValue(value);
System.out.println(value);
}
}
}
static class B extends A {
public B () {
super(5);
setValue(getValue()- 3);
}
public void setValue(int value) {
super.setValue(2 * value);
}
}
}
输出的结果应该是什么?
2 分析
我把两个类并排放在一起,这样看起来方便一点。
- 进入主函数,分析程序执行的顺序。 第一模块,执行new B(),创建对象。 第二模块,执行B.getValue(),调用对象的方法。第三模块,sout输出语句,输出函数的返回值。按照顺序进行分析。
- 第一模块:new B(),创建类B的对象。
2.1 进入B的构造。先执行super(5).已知B类继承A类,所以要先完成父类A的构造。B类继承了A类的有参构造super(A),传递了参数v=5.
2.2 进入A的构造,A的构造调用了方法setValue(5)。而子类B重写了父类A的该方法,调用B的setValue。
2.3 进入B的setValue(5),方法体内指向父类的setValue方法,参数v = 2 * value = 10
2.4 进入A的setValue(10),this.value = value = 10。B实例的value=10.
2.5 A的构造执行完毕。
2.6 再执行setValue(getValue()- 3); 先执行getValue()。B没有重写该方法,调用父类的getValue()
2.7 进入B的getValue()。执行try内语句。B.value++,B.value=11,return 11.getValue()返回11.
2.8 就算return,finally还是会执行。执行finally内语句。调用setValue(11),同理,进入子类重写的setValue(11).进入B的setValue(11),引用父类的setValue(11*2),进入A的setValue(22),此时B.value=22.输出22
,而前面11已经作为函数的返回值返回了。
2.9 再执行setValue(getValue()-3)即setValue(11-3)=setValue(8)。
2.10 进入B的setValue(8),super.setValue(16),进入A的setValue(16),B.value=16。
2.11 B的构造执行完毕。 - 第二模块,实例B.getValue(),继承A的getValue()
3.1 进入try内。value++,B.value=17。return value。返回值17.
3.2 进入finally内。this.setValue(17),调用B的setValue(17),进入A的setValue(17 * 2),B.value=34。输出34.
- 第三模块,输出返回值。之前已经返回了17,所以
输出17
.
所以输出的结果应该是22 34 17。
标签:setValue,继承,子类,多态,value,getValue,构造,父类 来源: https://www.cnblogs.com/80sVolxxxx/p/16562915.html