day04

2018-08-23  本文已影响0人  zhuofai

多态

8.3构造器和多态

  1. 尽管构造器并不具有多态性(它们实际上是static方法,只不过该static声明是隐式的)
  2. 构造器调用顺序:
    1. 调用基类构造器.
    2. 按声明顺序调用成员初始化方法.
    3. 调用导出类构造器主体.
  3. 上2初始化顺序并不完整
    1. 在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零.
    2. 如前所述的那样调用基类构造器.
    3. 按声明顺序调用成员初始化方法.
    4. 调用导出类构造器主体.
//本例中存在两个知识点
//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
  1. 因此编写构造器时有一条有效准则:"用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法".
  2. 在构造器内唯一能够安全调用的那些方法时基类汇总的final方法(也适用private方法,它们自动属于final方法).
  3. 用继承表达行为间的差异,并用字段表达状态上的变化.附代码
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抽象类和抽象方法

  1. 如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供定义.
  2. 这个题比较有意思我写下来.

    创建一个不包含任何方法的抽象类,从哪里导出一个类,并添加一个方法.创建一个静态方法,他可以接收指向基类的引用,将其向下转型到导出类,然后再调用该静态方法,在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);
    }  
}  
  1. 续接口,接口中在jdk1.8后可以default声明关键字
上一篇下一篇

猜你喜欢

热点阅读