【问题标题】:When is method hiding practically used?什么时候实际使用方法隐藏?
【发布时间】:2018-04-28 16:40:07
【问题描述】:

我想知道java中方法隐藏的实际使用。

例如

class MyClass{
     public static void myMethod(){
         //some code here
     }
}

class MyClass1 extends MyClass{

     public static void myMethod(){
         //some code here
     }
  public static void main(String args[]){
    MyClass1 obj1=new MyClass1();
    MyClass obj=obj1;
    MyClass.myMethod();  // this method will run the parent Class method myMethod then what is the use of this practically.                           
    }
}

【问题讨论】:

  • @overriding 注释是什么?如果这是一个错字并且应该是@Override,为什么要放在静态方法上?它不会编译。
  • 方法隐藏是无用的恕我直言。它只会造成混乱。

标签: java


【解决方案1】:

首先,这不是一种覆盖形式。 (当方法被继承时会发生覆盖,而static 方法在 Java 中不会被继承。)

这叫做“隐藏”……不过有点假象。访问隐藏的静态方法或字段非常容易。因此,这种“技术”并不是特别有用。

如果有的话,隐藏是一个坏主意,因为它可能是程序错误的来源......或者至少是看起来像这样做但实际上正在做某事的代码源不同。

所以我的建议是避免隐藏而不是寻找使用它的地方。 (事后看来,如果 Java 语言将其视为编译错误可能会更好......)


为了记录,这里是一个隐藏的例子:

public class A {
    public static String method() { return "'A.method()'"; }
}

public class B extends A {
    public static String method() { return "'B.method()'"; }

    public static void main(String[] args) {
        System.out.println(A.method());  // prints 'A.method()'
        System.out.println(B.method());  // prints 'B.method()'
        System.out.println(method());    // prints 'B.method()'
    }
}

上面Bmethod()的版本隐藏了A中的版本,不过你还是可以调用的。 “隐藏”是一种错觉。

下面是一个例子,它显示了它可能导致的问题类型:

A a = new A();
B b = new B();

System.out.println(a.method());  // prints 'A.method()'
System.out.println(b.method());  // prints 'B.method()'

b = a;
System.out.println(b.method());  // prints 'B.method()'

看起来就像我们正在调用实例方法...直到您点击第三个 method() 调用。


还有另外两个术语——“遮蔽”和“遮蔽”——适用于不同的环境:

  • 阴影是内部作用域中的名称重新声明外部作用域中的名称。

  • Obscuring 是您将名称用于成员、类型和/或包的位置。这个你真的想避免,因为它会导致非常混乱的代码。但幸运的是,您必须无视 Java 的标识符样式规则才能被此烧毁。

【讨论】:

  • 根据docs.oracle.com/javase/tutorial/java/IandI/override.html,它被称为“隐藏”。 “如果子类定义了与超类中的类方法具有相同签名的类方法,则子类中的方法会隐藏超类中的方法”。除了实际回答 OP 要求的出色答案之外。
  • JLS 还提到了“方法隐藏”docs.oracle.com/javase/specs/jls/se7/html/jls-8.html,除非我遗漏了什么
  • man @Stephen C 我说我想要实际使用它,否则我也知道该怎么做
  • @Sahil - 没有好的例子……只有可怜/危险的例子。这就是我的观点。
【解决方案2】:

您所说的“方法隐藏”没有特定用途。相反,这是在子类中使用相同的静态方法签名的结果。

【讨论】:

    【解决方案3】:

    当你在超类中有静态方法,如果你在子类中创建一个具有相同签名的方法,如果你使用超类引用,超类方法将被调用,如果你是子类方法,则被调用使用子类引用。对静态方法的调用在编译时自行解决。因此MyClass.myMethod()会调用父类方法,而MyClass1.myMethod()会调用子类方法。

    根据Oracle tutorial

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

    【讨论】:

    • OP 在问它的“实际用途”是什么(即你为什么要这样做?)
    【解决方案4】:

    Java 不会在运行时解析方法调用,根据用于调用静态方法的 Object 类型,将调用相应的方法。

    也就是说如果你使用Parent类的类型调用静态方法,就会调用专利类的原始静态方法,反之,如果你使用Child类的类型调用静态方法,就会调用子类的方法。 简而言之,Java 中不能覆盖静态方法

    值得一读:java non-static to static method -- hiding or overriding

    【讨论】:

      【解决方案5】:

      我不明白你为什么要创建你的类的对象,因为它们在这里并不重要并且在你的问题中没有任何作用。

      我想用一个例子为你清除它。将MyClass 视为Car 类并将MyClass2 视为bus 类(假设您正在为一家汽车公司编程!!)如果您想了解,现在还可以将public static void myMethod() 视为NumberOfProduced公司生产的汽车数量,您应该使用Car.NumberOfProduced()(其中还有附加代码。)但如果您想了解巴士生产的数量,请使用Bus.NumberOfProduced()。我再次提到该对象对结果没有任何影响(除非您想计算创建对象的数量。) 希望对你有用。

      【讨论】:

      • 这甚至没有提到你会躲起来的情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2013-07-27
      • 1970-01-01
      • 2021-08-07
      相关资源
      最近更新 更多