class Bird {
  String name;
  Bird(String n) {
    name = n;
  }  public void fly() {
    System.out.println(name+" fly as bird");
  }
  
  public void shout() {
    System.out.println(name+" shout as bird");
  }
  public void shout(int number) {
    System.out.println(name+" shout "+number+" times as bird");
  }
}class Swan extends Bird {
  Swan(String n) {
    super(n);
  }  public void fly() {
    System.out.println(name+" fly as Swan");
  }  public void shout() {
    System.out.println(name+" shout as Swan");
  }  public void swim() {
    System.out.println(name+" swim as Swan");
  }
}class Duck extends Bird {
  Duck(String n) {
    super(n);
  }  public void fly() {
    System.out.println(name+" fly as Duck");
  }  public void shout() {
    System.out.println(name+" shout as Duck");
  }  public void swim() {
    System.out.println(name+" swim as Duck");
  }
}public class TestM {
  public static void main(String[] args) {
    Bird b1 = new Bird("小小鸟");
    Bird b2 = new Swan("小天鹅");
    Bird b3 = new Duck("唐老鸭");
    
    /*分析以下语句编译错误的原因*/
    //b1.swin();
    //b2.swin();
    //b3.swin();
    //(Duck)b3.swim();      
    /****************************/
    
    /*先分析以下语句的运行结果,再执行验证*/    
    b1.fly();
    b2.fly();
    b3.fly();
    
    b1.shout(1);
    b2.shout(2);
    b3.shout(3);
    
     Swan s2=(Swan)b2;
    s2.swim();    
    
    s2=(Swan)b1;
    s2.swim();
    
    s2=(Swan)b3;
    s2.swim();         ((Duck)b3).swim();
    /****************************/    
  }
}

解决方案 »

  1.   

    b1,b2,b3是Bird类型,Bird类型没有swim方法,所以编译时出错
    fly是运行期调用实际对象的方法,所以打印各自类型的fly内容
    子类没有重写shot(int)方法,所以调用的父类方法,name是各个子类对象的名字(因为构造方法有super(name))Swan s2=(Swan)b2;
        s2.swim();
    类型转换没问题,会打印Swan的swim内容 s2=(Swan)b1;
        s2.swim();
        
        s2=(Swan)b3;
        s2.swim();     
    强行转换失败,出异常 ((Duck)b3).swim();
    类型转换没问题,会打印Duck的swim内容(前提是上面的异常被捕捉,程序没有中断)
      

  2.   

    父类有fly,shout方法,意味着子类变量能调用这两个方法,但是你的bb是父类变量引用子类,不能用子类的方法,只能用父类方法,如果想用子类方法,应把父类强制转换为子类,并且是在父类变量引用子类的情况下。