个人对多态问题的一些理解

时间:2021-03-28 21:53:25
1.  Instrument flute = new Wind();  向上转型
public static void tune(Instrument i){
    i.play();
}
重点理解这个方法,在这个方法中传入乐器类型的对象,进行操作。试想假如没有多态的话,每一种乐器执行tune()方法时,都要添加不同参数的tune()方法,工程量太大而且毫无意义。由于有了多态机制,我们可以根据自己的需求对系统添加任意多的新类型,只要该类型是继承Instrument的,而不需要更改tune()方法。
public static void tune(Wind w){
    w.play();
}
public static void tune(Brass b){
    b.play();
}
public static void tune(Stringed s){
  s.play();
}
 
2在子类继承父类的过程中,只有非private方法才可以被覆盖。
只有普通的方法调用可以是多态的,域和静态方法都不能用多态,
所以当出现类似于 父类 引用 = new 子类();时,对于域和静态方法都会执行父类的。
代码如下:
Super sup = new Sub();  // Sub是Super的子类,field是它们的域。
sup.field到底是执行super.field,还是执行sub.field呢?  
当Sub对象转型为Super的引用时,对任何域的访问操作都将有编译器解析,因此不是多态的。执行的是super.field
 
而 Sub sub = new Sub();
sub.field执行的是哪个方法? 必定是sub.field
 
代码如下:

public class DuoTai {

  public static void main(String[] args) {
    Person p = new Student();
    System.out.println(p.name);
    System.out.println(p.age);
    p.study();
  }

}

class Student extends Person{
  public String name = "学生";
  public int age = 24;
  void study(){
    System.out.println("Student study");
  }
}
class Person{
  public String name = "人们";
  public int age = 100;
  void study(){
    System.out.println("Person study");
  }
}

 
输出结果是:

人们
100
Student study

总结下:

  1.指向子类的父类引用,可以调用父类的所有属性和方法,也可以调用子类继承父类的方法,但是对于仅在子类中存在的而父类中不存在的方法,该引用是不能使用的。
  2.只有普通方法的调用可以是多态的,域、静态方法都不算,当子类对象转型为父类引用时,任何域的访问操作都将由编译器解析,因此不是多态的。所以只会得到父类的域值,即使是public
 
3. 构造器和多态:关于构造器的调用顺序
 
当我们new出子类对象的时候,在这一过程中,应该先调用最最基类的构造函数。
  1.调用基类的构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,直到最低层的导出类。
  2.按声明顺序调用成员的初始化方法
  3.调用导出类构造器的主体
原因:在构造器内部,我们必须确保所要使用的成员都已经构建完毕。所以唯一的办法就是,首先调用基类构造器,那么在进入导出类构造器时,在基类中可供我们访问的成员都已经得到初始化了。
class Characteristic{
  private String s;
  Characteristic(String s){
    this.s = s;
    print("Creating Characteristic " + s);
  }
  protected void dispose(){
    print("disposing Charactisric " + s);
  }    
}
 
class Description{
  private String s;
  Description(String s){
    this.s = s;
    print("Creating Description" + s);
  }
  protected void dispose(){
    print("disposing Description" + s);
  }    
}
 
class LivingCreature{
  private Characteristic p = new Characteristic("is alive");
  private Description t = new Description("Basic Living Creature");
  LivingCreature(){
    print("LivingCreature() ");
  }
  protected void dispose(){
    print("LivingCreature dispose ");
    t.dispose();
    p.dispose();
  }    
}
 
class Animal extends LivingCreature{
  private Characteristic p = new Characteristic("has heart");
  private Description t = new Description("Animal not Vegetable");
  Animal (){
    print("Animal ()");
  }
  protected void dispose(){
    print("Animal dispose ");
    t.dispose();
    p.dispose();
    super.dispose();
  }    
}
 
class Amphibian extends Animal {
  private Characteristic p = new Characteristic("can live in water ");
  private Description t = new Description("Both water and land ");
  Amphibian (){
    print("Amphibian l ()");
  }
  protected void dispose(){
    print("Amphibian  dispose ");
    t.dispose();
    p.dispose();
    super.dispose();
  }    
}
 
public class Frog extends Amphibian{
        private Characteristic p = new Characteristic( "Croaks" );
        private Description t = new Description( "Eats Bugs" );
        public Frog(){
              print( "Frog()" );
       }
        protected void dispose(){
              print( "Frog dispose" );
              t .dispose();
              p .dispose();
              super .dispose();
       }
       
        public static void main(String[] args ){
             Frog frog = new Frog();
              print( "Bye!" );
              frog .dispose();
       }
}
 
输出如下:
Creating Characteristic is alive
Creating Description Basic Living Creature
LivingCreature()
 
Creating Characteristic has heart
Creating Description Animal not Vegetable
Animal()
 
Creating Characteristic can live in water
Creating Description Both water and land
Amphibian()
 
Creating Characteristic Croaks
Creating Description Eats Bugs
Frog()
Bye!
 
Frog dispose
disposing Description Eats Bugs
disposing Characteristic Croaks
 
Amphibian dispose
disposing Description Both water and land
disposing Characteristic can live in water
 
Animal dispose
disposing Description Animal not Vegetable
disposing Characteristic has heart
 
LivingCreature dispose
disposing Description Basic Living Creature
disposing Characteristic is alive
 
1.先执行main(其实是先执行静态方法的,在这个类中,只有main函数是静态的)
2.组合对象在构造器之前执行
3.销毁与继承顺序相反
 
构造:先执行父类的构造函数 LivingCreature--->Animal--->Amphibian--->Frog
销毁:先销毁子类的 Frog--->Amphibian--->Animal--->LivingCreature
 
注意点:
1.如果成员对象中存在于其他一个或多个对象共享的情况,就不能简单的dispose了,而是应该计数来跟踪访问共享对象的对象数量;
2.程序中打印对象的话,其实是调用对象的toString()方法。