1

当一个类扩展一个类时,我们可以在为子类对象分配内存的同时使用超类引用。到目前为止我的理解是可以这样做,因为子类继承了其父类的数据,但它无法访问子类的成员,因为它只是引用,因此不知道添加了什么由子类完成。

我的问题是当我将方法隐藏到上述概念中时,超类引用变量开始引用子类函数。这是为什么 ?为什么它没有像它应该的那样调用它自己的方法?

class A{
 void show(){ System.out.print("CLass A. \n"); }
}

class B extends A{
 void show(){System.out.print("Class B. \n");  }
}

class Main{
 public static void main(String[] args){
  A a= new A();
  B b= new B();
  a.show();   // prints Class A
  b.show();   // prints Class B

  A a1= new B();
  a1.show();   // print Class B. why is this ? it should be Class A as per theory? 
 }
}
4

3 回答 3

2

变量和方法是两个不同的东西。变量坚持它们的类型,因为方法根据提供的实现类型执行运行时。

多态性。方法动态绑定并在运行时选择。如果您覆盖它们的实现类,它们会被执行,否则类型类的实现会被执行。

当你写

 A a1= new B();

表示please call the implementations from the class B(在右侧)来自类型A

于 2016-02-16T09:00:07.723 回答
1

你必须了解java中的覆盖概念。

从关于覆盖的oracle文档页面:

覆盖和隐藏方法

实例方法

具有instance method相同签名(名称,加上其参数的编号和类型)和返回类型作为超类中的实例方法的子类中的一个覆盖超类的方法

子类重写方法的能力允许类从行为“足够接近”的超类继承,然后根据需要修改行为。

但是覆盖不同于隐藏。

静态方法

如果子类定义了与超类中的静态方法具有相同签名的静态方法,则子类中的方法会隐藏超类中的方法。

隐藏静态方法和覆盖实例方法之间的区别具有重要意义:

  1. 被调用的重写实例方法的版本是子类中的版本。
  2. 被调用的隐藏静态方法的版本取决于它是从超类调用还是从子类调用。

要理解的示例:

public class Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Animal");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Animal");
    }
}

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

输出:

The static method in Animal
The instance method in Cat
于 2016-02-16T09:46:24.433 回答
0

它总是从最具体的类中调用方法。

于 2016-02-16T16:55:59.837 回答