【问题标题】:Correct way of writing "super" [duplicate]“超级”的正确写法[重复]
【发布时间】:2016-05-17 12:19:22
【问题描述】:

如果我有对象并且我想调用父类中方法的版本,有没有办法可以像x.super.method()super.x.method() 一样调用它?

【问题讨论】:

  • 我看到您的问题与建议的副本略有不同。但是,我认为 Java 甚至不允许您尝试做的事情。当您使用面向对象编程时,它甚至看起来都不合适。如果您想尝试重新打开它,您应该使用一些示例代码编辑您的问题。
  • 就目前而言,我认为这个问题不应该重新提出。但是我同意@Code-Apprentice 的观点,这里有一个有价值的问题的核心,需要编辑才能将其提出。
  • super.method() 有什么问题,你还期待什么?
  • 我想要特定变量的超类方法,不在方法中。
  • “我想要特定变量的超类方法,而不是方法中。” > 那么你需要重新考虑你的解决方案。这是不可能的,有充分的理由,例如违反合同等。找到不需要此设置的解决方案。

标签: java


【解决方案1】:

与其说是一个答案,不如说是一个小小的研究。这是一个有趣的问题,所以只是为了好玩,我编写了一些测试代码。由于 cmets 不支持格式化,所以我在此处发布结果。

我怀疑将 super 用于方法调用并使其实际编译的唯一方法是使用 super unqualified,即没有前缀表达式。

bar.blarch() 按预期编译和运行(参见下面的示例)。

bar.super.blarch() 没有编译(我也预料到了)。

Bar bar = new Bar();
System.out.println("bar.super.blarch() ==> " + bar.super.blarch() );

但是,error 消息让我感到惊讶。原来javac抱怨“找不到符号”如下:

Bar.java:15: error: cannot find symbol
System.out.println("bar.super.blarch() ==> " + bar.super.blarch() ); // does not compile.
                                               ^
symbol:   class bar
location: class Bar

所以在这一点上,'super' 似乎不在运行中,而 javac 正试图在 bar 之后找到一个实例变量。表达。

然后我认为反射可能为您提供了一种调用您的首选方法实现的方法,但这看起来也像否。
特别是输出中最后一个示例的旁边:
"fooBlarch.invoke(bar)=Bar.blarch"
尝试在 Bar 类型的实例上调用 Foo 类中的方法,但它仍以 Bar 开头并调用第一个匹配的方法名称 + 签名。

$ javac *.java
Note: Bar.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ java Bar
foo.blarch() ==> Foo.blarch
bar.blarch() ==> Bar.blarch
bar.superBlarch() ==> Foo.blarch
moreFoo.blarch() ==> Bar.blarch
fooClass=class Foo
fooBlarch=public java.lang.String Foo.blarch()
fooBlarch.invoke(foo)=Foo.blarch
fooBlarch.invoke(bar)=Bar.blarch
fooBlarch.invoke((Foo)bar)=Bar.blarch
$ 

Foo.java

public class Foo {
   public String blarch() { return "Foo.blarch"; }
}

Bar.java

import java.lang.reflect.*;

public class Bar extends Foo {
   public String blarch() { return "Bar.blarch"; }

   public String superBlarch() { return super.blarch(); }

   public static void main( String[] args ) throws Exception {
      Foo foo = new Foo();
      System.out.println("foo.blarch() ==> " + foo.blarch() ); // prints Foo.blarch

      Bar bar = new Bar();
      System.out.println("bar.blarch() ==> " + bar.blarch() ); // prints Bar.blarch
      System.out.println("bar.superBlarch() ==> " + bar.superBlarch() ); // prints Foo.blarch
      // System.out.println("bar.super.blarch() ==> " + bar.super.blarch() ); // does not compile.
      // Bar.java:15: error: cannot find symbol
      //     System.out.println("bar.super.blarch() ==> " + bar.super.blarch() ); // does not compile.
      //                                                    ^
      //  symbol:   class bar
      //  location: class Bar

      Foo moreFoo = new Bar();
      System.out.println("moreFoo.blarch() ==> " + moreFoo.blarch() ); // prints Bar.blarch

      Class fooClass = foo.getClass();
      System.out.println("fooClass="+fooClass);
      Method fooBlarch = fooClass.getDeclaredMethod( "blarch", new Class[] { } );
      System.out.println("fooBlarch="+fooBlarch);

      System.out.println("fooBlarch.invoke(foo)="+ fooBlarch.invoke( foo ) ); // yields Foo.blarch

      // I think you're out of luck trying to use anything "super-like" outside of a given class.
      // looks like Method.invoke() walks the full instance ancestors looking for a suitable implementation.
      // I actually didn't expect this one to compile given that the method is from class Foo, not Bar.
      System.out.println("fooBlarch.invoke(bar)="+ fooBlarch.invoke( bar ) ); // yields Bar.blarch

      // casting matters not at all.
      System.out.println("fooBlarch.invoke((Foo)bar)="+ fooBlarch.invoke( (Foo)bar ) ); // yields Bar.blarch
   }

}

【讨论】:

    猜你喜欢
    • 2021-10-26
    • 2013-09-01
    • 2011-06-01
    • 2018-07-25
    • 1970-01-01
    • 2014-02-27
    • 2011-06-03
    • 1970-01-01
    • 2013-11-28
    相关资源
    最近更新 更多