【问题标题】:Java Inheritance: Why calling a method at the parent constructor level, calls the overridden child method?Java继承:为什么在父构造函数级别调用方法,调用覆盖的子方法?
【发布时间】:2015-11-21 15:51:36
【问题描述】:

在 Fruit 构造函数中调用 fruitName 方法,实际上是将调用委托给 Apple 子类的方法!

public class CallingParentMethodInInheritanceHierarchy {

abstract class Fruit {
    String fruitName;

    public Fruit(String fruitName) {
        this.fruitName = fruitName;

        /*
         * o/p - Inside constructor - Child: Fruit name is - Apple
         */
        System.out.println("Inside constructor - " + fruitName()); // doubt?
    }

    public String fruitName() {
        return "Parent: Fruit name is - " + fruitName;
    }

    public abstract String type();

}

class Apple extends Fruit {
    public Apple() {
        super("Apple");
    }

    public String fruitName() {
        /*
         * To call the super class method, only way is -
         * 
         * System.out.println(super.fruitName());
         */
        return "Child: Fruit name is - " + fruitName;
    }

    @Override
    public String type() {
        return "AllSeasonsFruit";
    }
}

public static void main(String[] args) {
    Fruit fruit = new CallingParentMethodInInheritanceHierarchy().new Apple();

    /*
     * o/p - Child: Fruit name is - Apple
     */
    System.out.println(fruit.fruitName());
}

}

这背后的主要尝试是,我试图调用父方法,而不使用子方法中的 super.fruitName() 调用这种简单的方式。

请帮助我@line #12

【问题讨论】:

  • 这不是微不足道的;这是唯一的方法。父母和孩子之间的行为没有区别 - 您正在打印名称。为什么要覆盖它?
  • 构造函数中调用的方法应该是最终的。
  • @duffymo - 我只是在检查,稍后我可以添加真正的功能:-)
  • 对不起,你要么了解多态,要么不了解。

标签: java inheritance constructor


【解决方案1】:

这是多态性 101。最具体的 - 即继承树上的最低 - 方法的版本在类层次结构中调用。如果您没有重写fruitName() 方法根本,那么将调用基类方法。

【讨论】:

  • 但是我在父构造函数内部调用,此时子对象不会被完全实例化。如果我错了,请帮忙。
  • 这是一个不同的问题 - 它不会按照您尝试的方式工作。你说得对,孩子还没有空。但这并没有改变调用该方法会尝试调用子级的情况。所以你需要重新考虑你的层次结构。
  • @53by97 考虑一下:您已经可以在其构造函数中调用Fruit 的抽象方法,因此将调用Apple 的代码。同样,Apple 的代码将代替被覆盖的方法运行。
  • @53by97 如果你想发明自己的编程范式,那就去做吧。我们只是在说明现有的 OO(用 Java 实现)是如何工作的。
  • @53by97 如果还没有成功,你可以尝试研究一下Java中OOP是如何在底层实现的。特别是,您可能想了解虚拟方法表。
【解决方案2】:

因为这就是多态性的工作原理。子类可以覆盖任何非最终方法,而父代码将无法区分。这就是为什么通常不鼓励非抽象非最终公共方法的原因。

【讨论】:

  • 为什么不鼓励非抽象的非最终公共方法?这是面向对象设计的基础:提供实现,但在需要时允许专门化。
  • @javadba 因为这违反了Open-closed principle。实现抽象方法而不是覆盖非抽象方法也可用于实现专业化,并且以更不容易出错的方式。
  • 考虑需要一个默认的可公开访问的行为(即方法)但应该允许在子类中覆盖该行为的情况。请说明如何实现。
  • @javadba 通过在父类之外具有该默认行为。 Dude 不应该有任何默认行为,而是应该有一些DefaultDude 通过实现Dude 的抽象方法来提供行为。如果需要修改DefaultDude,请使用装饰器模式。
  • 好的,我明白了。我会买那个。
猜你喜欢
  • 2014-01-31
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 2014-05-22
  • 2015-04-04
  • 1970-01-01
相关资源
最近更新 更多