day04
2018-08-23 本文已影响0人
zhuofai
多态
8.3构造器和多态
- 尽管构造器并不具有多态性(它们实际上是static方法,只不过该static声明是隐式的)
- 构造器调用顺序:
- 调用基类构造器.
- 按声明顺序调用成员初始化方法.
- 调用导出类构造器主体.
- 上2初始化顺序并不完整
- 在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零.
- 如前所述的那样调用基类构造器.
- 按声明顺序调用成员初始化方法.
- 调用导出类构造器主体.
//本例中存在两个知识点
//1. 如果要调用构造器内部的一个动态绑定的方法,就要用到那个方法的覆盖后的定义.
//2. 在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零.
//即初始化radius为0
class Glyph{
void draw(){
print("Glyph.draw()");
}
Glyph(){
print("Glyph() before draw()");
draw();
print("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph{
private int radius = 1;
RoundGlyph(int r){
radius = r;
print("RoundGlyph.draw(). radius = " + radius);
}
void draw(){
print("RoundGlyph.draw().radius" + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}/*Ouput:
Glyph() before, radius = 0
Glyph() after draw ()
RoundGlyph.RoundGlyph(), radius = 5
- 因此编写构造器时有一条有效准则:"用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法".
- 在构造器内唯一能够安全调用的那些方法时基类汇总的final方法(也适用private方法,它们自动属于final方法).
- 用继承表达行为间的差异,并用字段表达状态上的变化.附代码
class Actor{
public void act(){}
}
class HappyActor extends Actor{
public void act(){
print("HappyActor");
}
}
class SadActor extends Actor{
public void act(){
print("SadActor");
}
}
class Stage{
private Actor actor = new HappyActor();
public void change(){
actor = new SadActor();
}
public void performPlay(){
actor.act();
}
}
public class Transmogrify {
public static void main(String[] args) {
Stage stage = new Stage();
stage.performPlay();
stage.change();
stage.performPlay();
}
}
接口
9.1抽象类和抽象方法
- 如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供定义.
- 这个题比较有意思我写下来.
创建一个不包含任何方法的抽象类,从哪里导出一个类,并添加一个方法.创建一个静态方法,他可以接收指向基类的引用,将其向下转型到导出类,然后再调用该静态方法,在main()中,展现它的运行情况.然后,为基类中的方法加上abstract声明,这样就不再需要进行向下转型.
abstract class Dad {}
class Son extends Dad {
protected void print() { System.out.println("Son"); }
}
abstract class SecondDad {
abstract protected void print();
}
class SecondSon extends SecondDad {
protected void print() { System.out.println("SecondSon"); }
}
public class Ja9_1_4 {
public static void testPrint(Dad d) {
((Son)d).print();//it's necessary
}
public static void secondTestPrint(SecondDad sd) {
sd.print();//don't need ((SecondSon)sd)
}
public static void main(String[] args) {
Son s = new Son();
Ja9_1_4.testPrint(s);
SecondSon ss = new SecondSon();
Ja9_1_4.secondTestPrint(ss);
}
}
- 续接口,接口中在jdk1.8后可以default声明关键字