Java继承:重写或隐藏方法

Java继承:重写或隐藏方法,java,inheritance,overwrite,Java,Inheritance,Overwrite,当一个类扩展另一个类时,它继承该超类的所有方法和变量。如果在具有相同签名的子类中以不同的方式定义方法和变量,则可以在子类中以不同的方式使用方法和变量。 现在Oracle区分了覆盖和隐藏(http://docs.oracle.com/javase/tutorial/java/IandI/override.html). 它说实例方法覆盖其超类的方法,而类方法隐藏它。 “隐藏和重写之间的区别具有重要意义。被调用的被重写方法的版本是子类中的版本。被调用的隐藏方法的版本取决于它是从超类还是从子类调用。”

当一个类扩展另一个类时,它继承该超类的所有方法和变量。如果在具有相同签名的子类中以不同的方式定义方法和变量,则可以在子类中以不同的方式使用方法和变量。 现在Oracle区分了覆盖和隐藏(http://docs.oracle.com/javase/tutorial/java/IandI/override.html). 它说实例方法覆盖其超类的方法,而类方法隐藏它。 “隐藏和重写之间的区别具有重要意义。被调用的被重写方法的版本是子类中的版本。被调用的隐藏方法的版本取决于它是从超类还是从子类调用。”

假设我有两门课,是的,也许吧。是的,也许吧。 也许有一根绳子

class Maybe {
    String a;
    public static void printOut() {
        System.out.println("Maybe");
    }
    public void printAndSet() {
        a = "Maybe";
        System.out.println(a);
    }

}
class Yes extends Maybe {
    public static void printOut() {
        System.out.println("Yes");
    }
    pubilc void printAndSet() {
         a = "Yes";
    }
}
class Print{
    public static void mail(String[] args) {
        Maybe m = new Maybe();
        Yes y = new Yes();
        Maybe.printOut();
        Yes.printOut();
        m.printAndSet();
        y.printAndSet();
}
我说:它会打印出来 大概 对 大概 对

但在我读了Oracle的文章后,我认为它必须打印出来:

yes
yes
maybe
yes
因为实例方法覆盖了它的超类方法

我很肯定我的输出是正确的,但我也肯定,Oracle知道 更好,所以我想我只是不理解这篇文章。 当我从一个超类的对象调用一个实例方法时,它使用覆盖的方法,这不可能是真的。 所以我不明白为什么要区分覆盖和隐藏! 有人能帮忙吗


编辑;插入代码而不是描述类

静态方法根本不能被重写。它们不是多态调用的,因为它们不作用于类的实例,而是作用于类本身

如果调用
Maybe.printOut()
,它将调用
Maybe
中定义的静态
printOut()
方法。还有一个在
Yes
中定义的方法
printOut()
,这一事实与此无关:这两个方法除了名称之外没有任何共同之处

请注意,您只需编写一个程序并执行它,就可以确认或消除您的疑虑

隐藏方法的问题只有在您开始对对象实例调用静态方法时才会出现。这是非常糟糕的做法,永远不应该这样做。如果您不遵守此规则,并且有以下情况:

Maybe m = new Maybe();
Maybe y = new Yes();

m.printOut(); // DON'T DO THAT: it should be Maybe.printOut();
y.printOut(); // DON'T DO THAT: it should be Maybe.printOut() or Yes.printOut();

结果将是
可能
,因为在静态方法的情况下,重要的不是对象的具体类型(
可能
),而是它们的声明的类型(
可能
可能
)。

根据您的示例,以下面的示例为基础:

public class SO11720216 {
    static class Maybe {
        public static void hidden() { System.out.println("static maybe"); }
        public void overwritten() { System.out.println("instance maybe"); }
        public void inherited() { hidden(); }
        public void called() { overwritten(); inherited(); }
    }
    static class Yes extends Maybe {
        public static void hidden() { System.out.println("static yes"); }
        public void overwritten() { System.out.println("instance yes"); }
    }
    public static void main(String[] args) {
        Maybe m = new Maybe();
        Yes y = new Yes();

        m.called(); /* prints:
                       instance maybe
                       static maybe
                    */

        y.called(); /* prints:
                       instance yes
                       static maybe
                    */
        Yes.hidden(); /* prints: static yes */
        y.hidden(); /* bad style! prints: static yes */
    }
}
overwrited
的调用将被每个派生类覆盖。因此,每个方法都将使用属于当前对象的实现。另一方面,对
hidden
的调用将始终使用定义类的实现。因此,
Maybe.called
将始终调用
Maybe.hidden
,而从不调用
Yes.hidden
。要调用
Yes.hidden
,您必须在
Yes
中的方法中调用,或者使用限定名

换个说法:

  • 覆盖方法意味着每当对派生类的对象调用该方法时,就会调用新的实现
  • 隐藏一个方法意味着在这个类的作用域中(即在它的任何方法体中,或者在用这个类的名称限定时),对该名称的非限定调用(如上面例子中的
    inherited()
    方法中的
    hidden()
    调用)现在将调用一个完全不同的函数,需要限定才能从父类访问同名的静态方法
您的困惑可能来自这样一个事实,即您假设覆盖会影响对该方法的所有调用,即使是对基类的对象

public class Parent {

    public String test(){
        return "p";
    }

    public static String testStatic(){
        return "sp";
    }
}


public class Child extends Parent {

    public String test(){
        return "c";
    }

    public static String testStatic(){
        return "sc";
    }
}

public class Demo{

    public static void main(String[] args) {

        Parent p =new Parent();
        Child c = new Child();
        Parent pc = new Child();

        System.out.println(p.test());
        System.out.println(c.test());
        System.out.println(pc.test());

            //Although this is not the correct way of calling static methods
        System.out.println(p.testStatic());
        System.out.println(c.testStatic());
        System.out.println(pc.testStatic());
    }
}
输出将为:-(静态方法与实例方法)

p C C 服务提供商 sc
sp

请您发布这些类的代码,而不是描述它们好吗?这样,您所说的代码类型就毫无疑问了。是基本相同问题的一个很好的答案。@JoachimSauer好的,对不起,我下次会发布代码@杯子:你不必等到下一次,你只需在这里编辑问题即可。