【问题标题】:How to access overridden method of parent class without using super()?如何在不使用 super() 的情况下访问父类的重写方法?
【发布时间】:2021-05-06 10:33:26
【问题描述】:

如下所示,我尝试将子类的对象转换为其父类的对象。那进展顺利。但是,当我尝试访问父类的重写方法时,它不会发生。而是调用子类中的覆盖方法。我知道我可以使用 super 关键字来做到这一点,但我只想知道为什么不能通过强制转换来做到这一点?

这是父类:

public class Parent {
    public void print() {
        System.out.println("In parent");
    }
}

这是从父类继承其属性的子类:

public class Child extends Parent{
    public void print() {
        System.out.println("In child");
    }
}

这是包含主要方法的类:

public class Main {

    public static void main(String[] args) {
        Child child = new Child();
        ((Parent)child).print();
    }

}

【问题讨论】:

  • 因为您不是在 class 上调用方法,而是在 instance 上调用方法。而且您使用的实例始终是Child 类型,无论您使用什么类型。
  • 你需要有另一个调用 super 的方法。
  • 一旦我将Child 对象转换为Parent 对象,它不会是父对象吗?如果不是,为什么?
  • "一旦我将 Child 对象转换为 Parent 对象,它就不是父对象了吗?"不,它不会。它应该如何成为另一个对象?它仍然是同一个对象!
  • @S.Tiss 因为Child 对象将始终是Child 对象。您可以将其转换为 parent 对象,因为它是从它扩展而来的。

标签: java oop inheritance overriding subclass


【解决方案1】:

澄清

在您的示例中,对象始终为Child。强制转换仅适用于引用变量。这种投射永远不会影响实际对象。

选项

  1. 正如其他人所提到的,添加一个单独的方法将调用super.() 或使用隐藏。隐藏实际上并不是覆盖。

小心隐藏的副作用

public class AccessParent {
    public static void main(String[] args) {
        Parent p = new Child();
        p.methodC();
        System.out.println(new String(new char[20]).replace("\0", "-"));
        p.methodD();
    }
}

class Parent {
    void methodA() {
        System.out.println("Parent.methodA");
    }

    private void methodB() {
        System.out.println("Parent.methodB");
        // this will still call Child.methodA
        // a hidden method can not control the scope of overridden method
        methodA();
    }

    void methodC() {
        System.out.println("Parent.methodC");
        methodB();
    }

    void methodD() {
        System.out.println("Parent.methodD");
        // hidden method will be called
        // technically Child.methodB() is not overridden
        methodB();
    }
}

class Child extends Parent {
    @Override
    void methodA() {
        System.out.println("Child.methodA");
    }

    // this not overridden
    void methodB() {
        System.out.println("Child.methodB");
    }
}

这将输出

Parent.methodC
Parent.methodB
Child.methodA
--------------------
Parent.methodD
Parent.methodB
Child.methodA```

【讨论】:

    【解决方案2】:

    您不能直接从子类访问被覆盖的方法。您可以做的最好的事情是向您的孩子添加另一个函数,该函数调用父 print 函数。

    public class Child extends Parent{
        public void print() {
            System.out.println("In child");
        }
        
        public void printParent() {
            super.print()
        }
    }
    

    那你就可以这样访问了,

    public class Main {
        public static void main(String[] args) {
            Child child = new Child();
            child.printParent();
        }
    }
    

    【讨论】:

      【解决方案3】:

      覆盖是一个赋予继承权重的原则。

      如果你有一个特定的要求来按照强制转换的行为,那么方法必须是类级别的“静态”而不是实例级别。

      你会失去真正继承的美丽,并更多地隐藏它。但是,在铸造方式上也可以实现同样的效果

      package com.company.language;
      
      public class InheritanceTrial {
          public static void main(String[] args) {
              Child child = new Child();
              child.print();
              ((Parent)child).print();
          }
      }
      class Parent {
          public static void print() {
              System.out.println("In parent");
          }
      }
      
      class Child extends Parent{
          public static void print() {
              System.out.println("In child");
          }
      }
      

      【讨论】:

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