在Java 8中,接口默认方法可以访问实例变量吗?

时间:2019-02-07 16:37:44

标签: java java-8

TL; TD在Java 8中,接口默认方法是否可以访问实例变量?

例如:

public interface Foo{
    default getBazModified(){
       return baz * 2; 
    }
}

public class Bar implements Foo {
   int baz;
   ...
}

我知道这听起来很蠢,但是在Java 8中有没有办法做类似的事情?

或者是唯一的方法是拥有一个实现Foo的抽象类,该类将声明实例变量 baz 和默认实现 getBazModified()

3 个答案:

答案 0 :(得分:7)

接口没有“看到”其实现的实例字段。这不是特定于接口的,任何超类型都不知道其子类型的特定字段(或与此有关的任何成员类型)。

在这种情况下,您的解决方案是在接口中声明一个抽象的getter方法,并使用它来读取子类的属性:

public interface Foo{
    default int getBazModified(){
       return this.getBaz() * 2; 
    }

    int getBaz();
}

然后让具体的类实现getter:

public class Bar implements Foo {
   int baz;
   public int getBaz() {return this.baz;}
}

答案 1 :(得分:2)

不。 因为在接口的默认方法内使用的变量只能访问在接口内定义的变量。

public interface Foo {
int BAZ=1;

default int getBazModified(){
    return BAZ * 2;
  }
}

记住在接口内部定义的变量是public,static和final,必须对其进行初始化。

现在

public class Bar implements Foo {
  int BAZ = 10;
}

在调用类中。

 Foo foo = new Bar();
 System.out.print(foo.getBazModified()); // output: 2

您只能通过覆盖默认方法来访问“ Bar”类中的实例变量。 像这样

public class Bar implements Foo {

  int BAZ = 10;

  @Override
  public int getBazModified() {
    return BAZ * 2;
  }
}

知道是否

Foo foo = new Bar();
System.out.print(foo.getBazModified()); // output: 20 (access instance variable)

答案 2 :(得分:1)

您尝试编译它吗?答案是否定的,因为该界面甚至不知道是否存在名为“ baz”的字段。

  

我知道这听起来很蠢,但是有什么办法   像Java 8中那样?

是的。抽象类。从字面上看,这正是为抽象类设计的。