【问题标题】:Subclass Reference by Superclass variable?超类变量的子类引用?
【发布时间】:2016-05-27 11:00:00
【问题描述】:

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

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

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? 
 }
}

【问题讨论】:

  • 了解方法覆盖
  • 什么理论会这样说?这完全是预期的行为。
  • 为什么要打印Class A?您只是将B 的实例存储在A 类型的变量中。事实上,该类仍然属于实例B,并且不会神奇地转换为A。而且由于它仍然是B 的一个实例,它将打印Class B.,因为该方法已被覆盖。
  • a1 是一个A 引用,但是一个B 具体实例。
  • 我对这个概念感到困惑,即当你使用超类引用来引用子类对象时,只能调用超类的成员。但相反,调用是在运行时解决的,因此会发生覆盖!

标签: java inheritance overloading method-hiding


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    你必须知道java中的覆盖概念。

    来自 oracle documentation 关于覆盖的页面:

    覆盖和隐藏方法

    实例方法

    子类中的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
    

    【讨论】:

      【解决方案3】:

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

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

      当你写作时

       A a1= new B();
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多