什么是隐藏在Java中的方法? 即使是JavaDoc的解释也是令人困惑的

Javadoc说:

被调用的隐藏方法的版本是超类中的版本,并且被调用的重写方法的版本是子类中的版本。

不响铃给我。 任何清楚的例子显示这个意思将不胜感激。


public class Animal {
    public static void foo() {
        System.out.println("Animal");
    }
}

public class Cat extends Animal {
    public static void foo() {  // hides Animal.foo()
        System.out.println("Cat");
    }
}

在这里, Cat.foo()被称为隐藏Animal.foo() 。 隐藏不像重写一样工作,因为静态方法不是多态的。 所以下面会发生:

Animal.foo(); // prints Animal
Cat.foo(); // prints Cat

Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;

a.foo(); // should not be done. Prints Animal
b.foo(); // should not be done. Prints Animal because the declared type of b is Animal
c.foo(); // should not be done. Prints Cat because the declared type of c is Cat
d.foo(); // should not be done. Prints Animal because the declared type of b is Animal

对实例而不是类调用静态方法是一种非常糟糕的做法,不应该这样做。

将它与实例方法进行比较,这些实例方法是多态的,因此被覆盖。 调用的方法取决于对象的具体运行时类型:

public class Animal {
    public void foo() {
        System.out.println("Animal");
    }
}

public class Cat extends Animal {
    public void foo() { // overrides Animal.foo()
        System.out.println("Cat");
    }
}

然后会发生以下情况:

Animal a = new Animal();
Animal b = new Cat();
Animal c = new Cat();
Animal d = null;

a.foo(); // prints Animal
b.foo(); // prints Cat
c.foo(); // prints Cat
d.foo(): // throws NullPointerException

首先什么是方法隐藏的含义?

方法隐藏装置亚类中定义的类方法具有相同签名作为在超类中的一类方法。 在这种情况下,超类的方法被子类隐藏。 它表示: 执行的方法的版本不会由用于调用它的对象决定 。 实际上它将由用于调用方法的引用变量的类型决定。

什么是方法重写的意思?

方法覆盖意味着子类定义了具有如超实例方法相同的签名和返回类型(包括协变型)的实例方法 。 在这种情况下,超类的方法被子类重写(替换)。 它表示: 执行的方法的版本将由用于调用它的对象决定 。 它不会由用于调用该方法的引用变量的类型决定。

为什么不能重写静态方法?

因为静态方法是基于它们被调用的类静态地(即在编译时)被解析的,而不是动态的,如同基于对象的运行时类型多态地解析的实例方法那样。

应该如何访问静态方法?

静态方法应该以静态方式访问。 即通过类本身的名称而不是使用实例。

下面是方法覆盖和隐藏的简短Demo:

class Super
{
  public static void foo(){System.out.println("I am foo in Super");}
  public void bar(){System.out.println("I am bar in Super");}
}
class Child extends Super
{
  public static void foo(){System.out.println("I am foo in Child");}//Hiding
  public void bar(){System.out.println("I am bar in Child");}//Overriding
  public static void main(String[] args)
  {
     Super sup = new Child();//Child object is reference by the variable of type Super
     Child child = new Child();//Child object is referenced by the variable of type Child
     sup.foo();//It will call the method of Super.
     child.foo();//It will call the method of Child.

     sup.bar();//It will call the method of Child.
     child.bar();//It will call the method of Child again.
  }
}

输出是

I am foo in Super
I am foo in Child
I am bar in Child
I am bar in Child

显然,随着指定的,因为foo是类方法,以便版本foo调用将被(即超级或儿童)引用的对象的类型的参考变量来确定Child 。 如果Super变量被引用,则调用Super foo 。 如果它被Child变量引用,则调用Child foo
然而,
由于bar是实例方法,因此被调用的bar版本完全由用于调用它的对象(即Child )确定。 无论通过哪个引用变量( SuperChild )调用,将要调用的方法始终为Child


覆盖方法意味着无论何时在派生类的对象上调用该方法时,都会调用新的实现。

隐藏一个方法意味着在这个类的范围内(即在它的任何方法的主体中,或者当用这个类的名字限定时)对该名称的非限定的调用现在将调用一个完全不同的函数,需要一个限定从父类访问相同名称的静态方法。

更多描述Java继承:覆盖或隐藏的方法

链接地址: http://www.djcxy.com/p/13821.html

上一篇: What is method hiding in Java? Even the JavaDoc explanation is confusing

下一篇: mocking a singleton class