Java中隐藏的方法是什么?甚至JavaDoc的解释也令人困惑

Java中隐藏的方法是什么?甚至JavaDoc的解释也令人困惑,java,oop,method-hiding,Java,Oop,Method Hiding,说: 调用的隐藏方法的版本是超类中的版本,调用的重写方法的版本是子类中的版本 对我来说没什么意义。任何清楚的示例都会非常感谢。例如,您可以覆盖超类中的实例方法,但不能是静态的 隐藏是父类有一个名为Foo的静态方法,子类也有一个名为Foo的静态方法 另一种情况是父类有一个名为Cat的静态方法,子类有一个名为Cat的实例方法。(具有相同签名的静态和实例不能混合使用) 在这里,Cat.foo()被称为隐藏Animal.foo()。隐藏与重写不同,因为静态方法不是多态的。因此,将发生以下情况: Anim

说:

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


对我来说没什么意义。任何清楚的示例都会非常感谢。

例如,您可以覆盖超类中的实例方法,但不能是静态的

隐藏是父类有一个名为Foo的静态方法,子类也有一个名为Foo的静态方法

另一种情况是父类有一个名为Cat的静态方法,子类有一个名为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 because the declared type of a is 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 d is Animal
Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;

a.foo(); // prints Animal
b.foo(); // prints Cat
c.foo(); // prints Cat
d.foo(): // throws NullPointerException
在实例而不是类上调用静态方法是一种非常糟糕的做法,永远不应该这样做

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

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.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 because the declared type of a is 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 d is Animal
Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;

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

覆盖方法意味着每当对派生类的对象调用该方法时,就会调用新的实现

隐藏方法意味着在该类范围内(即在其任何方法的主体中,或使用该类的名称进行限定时)对该名称的非限定调用现在将调用完全不同的函数,需要限定才能从父类访问同名的静态方法

更多说明

如果子类定义的类方法与超类中的类方法具有相同的签名,则子类中的方法将隐藏超类中的方法

我相信隐藏的方法是在静态上下文中。静态方法本身不会被重写,因为方法调用的解析是由编译器在编译时本身完成的。因此,如果您在基类中定义了一个静态方法,该方法的签名与父类中的签名相同,那么子类中的方法将隐藏从超类继承的方法

class Foo {
  public static void method() {
     System.out.println("in Foo");
  }
}

class Bar extends Foo {
   public static void method() {
    System.out.println("in Bar");
  }
}
首先,什么是方法隐藏?

方法隐藏意味着子类定义了一个与超类中的类方法具有相同签名的类方法。在这种情况下,子类隐藏了超类的方法。它表示:执行的方法的版本将不由用于调用它的对象确定。事实上,它将由用于调用该方法的引用变量的类型决定

方法重写是什么意思

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

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

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

如何访问静态方法?

静态方法应该以静态方式访问。i、 e.使用类本身的名称,而不是使用实例

下面是方法重写和隐藏的简短演示:

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或Child)确定。如果它被
Super
变量引用,则调用
Super
foo
。如果它被
Child
变量引用,则调用
Child
foo

鉴于,

由于
bar
是实例方法,因此调用的
bar
的版本仅由用于调用它的对象(即
子对象
)确定。无论通过哪个引用变量(
Super
Child
)调用,当Super/parent类和sub/Child类包含相同的静态方法,包括相同的参数和签名时,将要调用的方法始终是
Child
。超类中的方法将被子类中的方法隐藏。这就是所谓的方法隐藏

 class P
    {
    public static  void m1()
    {
    System.out.println("Parent");
    }
}
    class C extends P
    {
    public static void m1()
    {
    System.out.println("Child");
    }
}
class Test{
    public static void main(String args[])
    {
    Parent p=new Parent();//Parent
    Child c=new Child();  //Child
    Parent p=new Child();  //Parent
    }
    }

If the both parent and child class method are static the compiler is responsible for method resolution based on reference type

class Parent
{
public void m1()
{
System.out.println("Parent");
}}
class Child extends Parent
{
public void m1()
{
System.out.println("Child")
}
}
class Test
{
public static void main(String args[])
{
Parent p=new Parent(); //Parent 
Child c=new Child();   //Child
Parent p=new Child();  //Child
}
}

If both method are not static  jvm is responsible for method resolution based on run time object
示例:1

class Demo{
   public static void staticMethod() {
      System.out.println("super class - staticMethod");
   }
}
public class Sample extends Demo {

   public static void main(String args[] ) {
      Sample.staticMethod(); // super class - staticMethod
   }
}
示例:2-方法隐藏

class Demo{
   public static void staticMethod() {
      System.out.println("super class - staticMethod");
   }
}
public class Sample extends Demo {
   public static void staticMethod() {
      System.out.println("sub class - staticMethod");
   }
   public static void main(String args[] ) {
      Sample.staticMethod(); // sub class - staticMethod
   }
}

回答得很好,你是唯一一个提到在实例上调用静态方法是邪恶的人+1我怀疑你仍然可以通过说super.foo之类的话来访问父类方法,对吗?那么这里发生了什么事。它只是重申了一个事实,即被调用的函数是与引用变量相关联的函数,而不是实例。仍然无法确定对这个终端的具体需求
super
,就像
this
,不能在静态上下文中使用。您可以从
Cat.foo()
调用
Animal.foo()
,但是这两个方法实际上没有任何共同之处,除了它们的名称和签名。隐藏用于区分覆盖和隐藏。但是方法隐藏并不是真正有用的,而方法过度隐藏是OO设计的关键部分之一。从语言学角度来说,我认为动物的静态方法隐藏了猫的静态方法。我花了一段时间