java—如何在接口和匿名实现中使用成员变量

hgncfbus  于 2021-06-30  发布在  Java
关注(0)|答案(4)|浏览(379)

请检查以下java代码:

public class Test
{
  public static void main(String arg[]) throws Throwable
  {
      Test t = new Test();
      System.out.println(t.meth().s);           //OP: Old value
      System.out.println(t.meth().getVal());    //OP: String Implementation
  }
  private TestInter meth()
  {
    return new TestInter()
    {
      public String s = "String Implementation";
      public String getVal()
      {
        return this.s;
      }
    };
  }
}
interface TestInter
{
  String s = "Old value";
  String getVal();
}

如您所见,我创建了一个匿名接口。当我直接访问接口变量时,它将显示“old value”。
t、 meth().s=>“旧值”
通过getval()方法访问它会返回正确的值,
t、 meth().getval()=>“字符串实现”
我不明白这个代码是怎么工作的,有人能给我解释一下吗?

zxlwwiss

zxlwwiss1#

这个 s 接口中声明的变量与 s 在匿名内部类中声明的变量。
接口变量实际上只是被设计成常量——它们不是每个实现需要提供的api的一部分。特别是,它们是隐式静态的和最终的。
根据jls第9.3节:
接口主体中的每个字段声明都是隐式公共的、静态的和最终的。允许为此类字段冗余指定任何或所有这些修饰符。
您已经通过实现示例访问了该字段这一事实与此无关—以下代码:

System.out.println(t.meth().s);

实际上是:

t.meth();
System.out.println(TestInter.s);

我强烈建议您避免在接口中使用变量,除了真正的常量。。。即使这样,也只有在真正有意义的地方。不清楚您想要实现什么,但是在接口中声明一个字段并不是一个好方法。

holgip5t

holgip5t2#

When i access a interface variable directly

你有接口类型的引用,这就是为什么它直接引用接口,你得到“旧值”

Accessing getVal() method, showing proper values

当您调用方法getval()时,您引用的是这个方法的实际实现,这就是调用实际实现的getval的原因。这表示具有以下值的当前示例:

public String s = "String Implementation";
ecfsfe2w

ecfsfe2w3#

没有什么比 variable-overriding 就像 method overriding 在 java 。为命名新类型 subclass ,那么您将获得 "String Implementation" ,当您通过子类引用类型进行访问时。
访问权限 protected 只意味着我们可以访问子类中的变量,但不能覆盖它。
即使你用的是普通的 class 而不是 interface 这行不通。当你提到使用 super 类类型,你只得到 instance 变量来自 super 类型等等。。。。此示例演示了第一种情况:示例:

public class Tester
{
  public static void main(String arg[]) throws Throwable
  {
      Tester t = new Tester();
      System.out.println(t.meth().s); // it prints "Old value" because your type is TestInter           
  }
  private TestInter meth()
  {
    return new TestInter()
    {
       protected String s = "String Implementation";

    };
  }
}
class TestInter
{
  protected String s = "Old value";

}

这个例子演示了第二种情况:它打印 "String Implementation" ```
public class Tester
{
public static void main(String arg[]) throws Throwable
{
Tester t = new Tester();
System.out.println(t.meth().s);
}
private SubTestInter meth()
{
return new SubTestInter();
}
}
class SubTestInter extends TestInter{
protected String s = "String Implementation";
}
class TestInter
{
protected String s = "Old value";

}

vsaztqbk

vsaztqbk4#

接口中声明的字段是常量。
因此,在写作时

interface TestInter
{
  String s = "Old value";
  String getVal();
}

你在声明一个常数s。这就是为什么 t.meth().s 正在打印
Old value t.meth().getVal() 正在打印字段的内容 s 你的匿名班级。

相关问题