【问题标题】:Should I use static binding?我应该使用静态绑定吗?
【发布时间】:2019-07-11 12:45:42
【问题描述】:

我正在学习后期绑定和静态绑定。现在我对这些代码感到困惑。

这是我的分析:

  1. hello() 是非静态方法,所以我们应该使用动态绑定,即 Child。
  2. 但是子类中没有hello()方法,所以转到它的超类。找到hello(),打印第一行“Hello from parent call calssMethod”。
  3. 由于classMethod()是静态的,所以我们应该使用c的静态绑定,也就是Child。所以输出是“classMethod in Child”。

所以输出应该是

来自父调用 calssMethod 的问候

子类中的类方法

class Parent{
    public static void classMethod() {
        System.out.println("classMethod in Parent");
    }
    public void instanceMethod() {
        System.out.println("InstanceMethod in Parent");
    }
    
    public void hello() {
        System.out.println("Hello from parent call calssMethod");
        classMethod();
    }
}

class Child extends Parent{
    public static void classMethod() {
        System.out.println("classMethod in Child");
    }
    public void instanceMethod() {
        System.out.println("InstanceMethod in Child");
    }
}
public class AA {
    public static void main(String[] args) {
        Child c = new Child();
        c.hello();
    }
}

现在,问题来了。 IDE显示输出为:

来自父调用 calssMethod 的问候

父类中的类方法

什么是正确的分析过程?

如果我将hello() 方法设为静态会怎样?

【问题讨论】:

  • 如果您想要不同的结果,只需覆盖该方法。我认为您并没有真正理解“静态”是什么以及它的用途。

标签: java binding static polymorphism


【解决方案1】:

类(静态)方法不会被重写为实例方法。当您调用方法“hello()”时,它将使用父方法。当您在此处引用类方法时,您指的是在“Parent”类中定义的方法。

除此之外,您应该将您的 Child 实例声明为“Parent c = new Child()”。因为您没有向子类添加新方法,而是更改了实现,所以您不会失去对子类方法的访问权限。如果你不得不返回一个 Parent 对象的方法,但你返回一个声明的 Child 对象,你会遇到问题。

编辑:除此之外,通常有两个原因使用继承:专业化和扩展。

对于专业化,您可以在超类中定义您的方法,而您的子类在实现这些方法的方式上有所不同。例如具有子类 Cat 和 Dog 的超类 Animal。 'Animal' 有一个方法makeSound()。您可以想象两个子类将有不同的实现。

对于扩展,您使用超类作为包含所有重叠内容的基类。除此之外,子类可能有非常不同的实现和用途。很多接口都有这种用途。

【讨论】:

  • 抱歉,我不太明白为什么要声明 Parent c = new Child()。因为我已经让 Child 类继承了 Parent 类,所以 hello() 方法已经继承自 Parent 类了。
  • 您明确表示 Child 也是 Parent。通过这样做,您可以让自己像对待父母一样处理那个孩子。在处理要返回列表或所有子类的多个子类时,这很重要。如果您要使用期望该超类 (List.add(element: Parent)) 的方法,您会遇到问题。在这种情况下,您没有利用多态性。看看这个 (stackoverflow.com/questions/10177523/…) 了解更多信息
【解决方案2】:

每当我们调用子类的对象时,首先它总是找到父类并执行它。由于您在两个类中都有静态 classMethod,因此它始终运行父类的 classMethod 而不是子类。您只能通过覆盖它来获得所需的答案。

即使你将 hello() 方法设为静态,它也会给你相同的输出。

【讨论】:

    猜你喜欢
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    相关资源
    最近更新 更多