继承和多态概念还有一些相关的细节,具体包括:
构造方法 now!
重名与静态绑定
重载和重写
父子类型转换
继承访问权限(protected)
可见性重写
防止继承(final)
cop.kujiale|owt.khrd|pdl.i18n|service.message-service
构造方法
构造方法与类同名且没有返回值。
构造方法的语句格式:
1 | public 构造方法名() { |
只能在对象实例化(new 对象)的时候被调用。
子类可以通过super(…)调用父类的构造方法。如果子类没有通过super(…)调用,则会自动调用父类的默认构造方法。
如果父类没有默认构造方法,如下所示:
1 | //父类 |
上方代码中的类只有一个带参数的构造函数,没有默认构造方法。
这个时候,它的任何子类都必须在构造方法中通过super(…)调用Base的带参数的构造方法。
如下所示,否则Java会提示编译错误。
1 | //子类 |
避免父类的构造方法调用可重写的方法
如果在父类构造方法中调用了可被重写的方法,则可能会出现意想不到的结果。
父类代码如下:
1 | //父类 |
子类代码如下:
1 | //子类 |
子类有一个实例变量a,a初始赋值为123。子类重写了test方法,要输出a的值。
使用代码如下:
1 | public static void main(String[] args) { |
输出结果:
1 | 0 |
第一次输出0,是在new过程中输出的。
new过程中,首先初始化父类Base,父类构造方法调用test(),test被子类重写了,就会调用子类的test方法。
子类方法访问子类实例变量a,这个时候子类的实例变量的赋值语句和构造方法还没有执行,所以输出的默认值是0。
通过上面的例子,可以得出结论——在父类构造方法中调用可被子类重写的方法,是一种不好的实践,容易引起混淆,应该只调用private的方法。