class Human {
public Human() {
speak();
}
public void speak() {
System.out.println("I am a human being.\n");
}
public static void main(String [] args) {
Human h = new Human();
}
}public class Teacher extends Human{
public Teacher() {
speak();
}
public void speak() {
System.out.println("I am a teacher.\n");
}
public static void main(String [] args) {
Teacher t = new Teacher();
}
}运行Teacher的main函数,发现输出
I am a teacher.
I am a teacher.为什么所继承的Human类的speak不会被执行呢?请详细解释一下好吗?谢谢!

解决方案 »

  1.   

    因为你在Teacher类中重写了父类里的speak方法
      

  2.   

    有了继承 也就有了向上类型转换(UpCast) 所以子类对象可以赋给父类引用 因为它们是Is-A的关系
    再有了方法的覆盖 就满足了多态的定义 java采用的是动态绑定 也就是在运用时才确定它所要调用的行为
      

  3.   

    原来是覆盖了,不过,从两次输出来看,第一次还是调用了父类的speak,是吧?只不过,内容也换成了Teacher的speak。请问如何实现调用父类的构造函数时使用的仍然是父类的speak呢?有没有办法做到?也就是说Teacher构造的时候首先输出I am a human being.然后再输出I am a teacher.
      

  4.   


    class Human { 
    public Human() { 
    speak();  //3.调用父类构造器

    public void speak() { 
    System.out.println("I am a human being.\n");  

    public static void main(String [] args) { 
    Human h = new Human(); 

    } public class Teacher extends Human{ 
    public Teacher() { 
    speak();  //2.再调用构造器。

    public void speak() { 
    System.out.println("I am a teacher.\n");    //4.子类覆盖了父类的方法所以调用这里的speak()。

    public static void main(String [] args) { 
    Teacher t = new Teacher();  //1.先运行这里。


      

  5.   


    class Human { 
    public Human() { 
    speak();  //3.调用父类构造器

    public void speak() { 
    System.out.println("I am a human being.\n");  

    public static void main(String [] args) { 
    Human h = new Human(); 

    } public class Teacher extends Human{ 
    public Teacher() { 
    speak();  //2.再调用构造器。

    public void speak(String str) { 
    System.out.println("I am a "+str+"\n.");    //注意这里!

    public static void main(String [] args) { 
    Teacher t = new Teacher();  //1.先运行这里。


    这样写就可以调用父类的了
      

  6.   

    请看我在7楼的话,我想知道如何才能令第一次调用的speak仍然是父类的speak?
      

  7.   

    想调用父类的speak 可以用 super.speak();
      

  8.   

    建议楼主以后尽量少写这样的代码!(个人意见)
    在构造函数也出现了多态的形为,因为你在构造函数里面调用了覆盖父类的方法
    在子类的构造方法中,如果你没有显性的调用父类的构造方法,
    那么JAVA里面会帮你自动调用父类的默认的(即无参的)构造方法。
    这是你写的:
    public Teacher() {
              speak();

    其实就相当于:
    public Teacher() {
              super();     //这里的super==this,这点需要注意!
              speak();
    }
    这样当然就出现你所说的结果。
      

  9.   

    避开构造函数的问题,我想知道如何令Teacher类执行speak方法时,首先会执行Human类的speak方法,然后再执行Teacher的speak方法?
      

  10.   


    在Teacher的构造函数里加句super.speak(); 就先执行Human的speak()了