简体   繁体   English

超类不会调用重写方法吗?

[英]Does the super class not call the overridden method?

I have the following classes: 我有以下课程:

class foo {
    public void a() {
        print("a");
    }
    public void b() {
        a();
    }
}

class bar extends foo {
    public void a() {
        print("overwritten a");
    }
}

When I now call bar.b() I want it to call the overridden method a() in foo. 当我现在调用bar.b()时,我希望它在foo中调用重写的方法a()。 It does, however, print "a". 但是,它会打印“a”。

Are your two classes in different packages? 你的两个班级是不同的包吗? And is your foo class methods declared public, protected, or private or package local? 你的foo类方法是公共的,受保护的,私有的还是包本地的? Obviously if they are private, this won't work. 显然,如果它们是私有的,这将不起作用。 Perhaps less obvious, is if they are package local (ie no public/protected/private scope) then you can only override them if you are in the same package as the original class. 也许不那么明显,如果它们是本地包(即没有公共/受保护/私有范围),那么只有在与原始类位于同一包中时才能覆盖它们。

For example: 例如:

package original;
public class Foo {
  void a() { System.out.println("A"); }
  public void b() { a(); }
}

package another;
public class Bar extends original.Foo {
  void a() { System.out.println("Overwritten A"); }
}

package another;
public class Program {
  public static void main(String[] args) {
    Bar bar = new Bar();
    bar.b();
  }
}

In this case, you will still get 'A'. 在这种情况下,你仍然会得到'A'。 If you declare the original a() method in Foo public or protected, you will get the result you expected. 如果在Foo public或protected中声明原始的a()方法,您将获得预期的结果。

It may be that you are trying to use static methods, which won't work as they don't get overridden. 可能是您正在尝试使用静态方法,这些方法无法正常工作,因为它们不会被覆盖。

A good way of checking is to add the @Override annotation to bar.a() and see if the compiler gives you an error that a() isn't actually overidding anything 一个好的检查方法是将@Override注释添加到bar.a()并查看编译器是否给出了一个错误,即a()实际上没有覆盖任何东西

When I run the following: 当我运行以下内容时:

public class Program {
    public static void main(String[] args) {
        bar b = new bar();
        b.b();
    }
}

class foo {
    public void a() {
       System.out.printf("a");
    }
    public void b() {
        a();
    }
}

class bar extends foo {
    public void a() {
        System.out.printf("overwritten a");
    }
}

I get the following output: 我得到以下输出:

overwritten a

which is what I would expect to see. 这是我期望看到的。

Are the methods defined as static? 方法是否定义为静态? That's the only way I could see getting that result. 这是我能看到得到这个结果的唯一方法。 I found a good explanation about that here: http://faq.javaranch.com/view?OverridingVsHiding 我在这里找到了一个很好的解释: http//faq.javaranch.com/view?OverridingVsHiding

From the horse's mouth: 从马的嘴里:

http://download.oracle.com/javase/tutorial/java/IandI/override.html http://download.oracle.com/javase/tutorial/java/IandI/override.html

"The version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked depends on whether it is invoked from the superclass or the subclass." “被调用的被重写方法的版本是子类中的一个。被调用的隐藏方法的版本取决于它是从超类还是从子类调用的。”

So if they are both static methods and you invoke the method from the super class, then the super class method is invoked, not the subclass method. 因此,如果它们都是静态方法并且您从超类调用该方法,则调用超类方法,而不是子类方法。 So really, no overriding is taking place. 所以真的,没有压倒一切。

You may be confused if you are coming from C# or some other language where you have to explicitly declare virtual functions and/or overriding functions. 如果您来自C#或其他必须明确声明虚函数和/或覆盖函数的语言,您可能会感到困惑。

In Java, all instance functions are virtual, and can be overridden -- unless they are declared as private and/or final. 在Java中,所有实例函数都是虚拟的,并且可以被覆盖 - 除非它们被声明为私有和/或最终。

It is not necessary to specify the new @Override annotation to do so, adding the annotation just specifies that your intent is to override, and will cause a either a warning or error if it isn't an override. 没有必要指定新的@Override注释来执行此操作,添加注释只是指定您的意图将被覆盖,并且如果它不是覆盖,将导致警告或错误。 (If you accidentally misspelled the method name for example). (例如,如果您不小心拼错了方法名称)。

Andrew's example shows how this should work. 安德鲁的例子说明了这应该如何运作。

While I was working on an Android program, I had the same problem on my Java classes. 当我在开发Android程序时,我在Java类上遇到了同样的问题。 It turned out that the problem was not in the classes but the way Android framework processes screen output. 事实证明问题不在于类,而在于Android框架处理屏幕输出的方式。

for example if output was programmed in the onCreate() method in the parent class, Android failed to correctly fetch the output of overridden methods from child classes beyond first child. 例如,如果输出是在父类的onCreate()方法中编程的,则Android无法从第一个子节点之外的子类中正确获取重写方法的输出。 Honestly I don't understand whole method calling order. 老实说,我不懂整个方法的调用顺序。

To resolve the issue I simply programmed the output in the onResume() and now it seem to work fine. 为了解决这个问题,我只是简单地在onResume()中编写输出,现在它似乎工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM