Java 接口中的默认方法

Java 接口中的默认方法,java,default-method,Java,Default Method,一段时间以来,我一直对为什么我们需要在接口中使用默认方法感到困惑,今天我正在阅读有关它的文章。虽然我的问题很少得到回答,但我仍有一些疑问 让我们举一个简单的例子,我有一个接口1。A类和B类实现接口1。interface1有一个方法X interface interface1{ void methodX(); } class A implements interface1{ @override public void methodX(){ //something

一段时间以来,我一直对为什么我们需要在接口中使用默认方法感到困惑,今天我正在阅读有关它的文章。虽然我的问题很少得到回答,但我仍有一些疑问

让我们举一个简单的例子,我有一个接口1。A类和B类实现接口1。interface1有一个方法X

interface interface1{
    void methodX();
}

class A implements interface1{
   @override
   public void methodX(){
      //something 
  };
}

class B implements interface1{
   @override
   public void methodX(){
      //something 
  };
}
据我所知,由于向interface1添加一个新方法Y会破坏类a和类B,所以引入了默认方法。这意味着现在我可以添加一个默认方法,而无需修改类a和类B。这也意味着默认方法必须具有足够的通用性,以便对类a和类B执行我们希望它执行的任何操作

现在,让我们考虑我们通常在接口中添加函数,这样我们就可以通过重写它来为它们提供类特定的实现。因此,基本上,如果我在一个接口中添加一个方法Y作为默认值,那么我希望类a和类B(或类a/ClassB)重写该方法

也就是说,我将修改A类/B类或两者

这就是让我困惑的地方。这可以通过创建一个新接口和修改一个(或两个)类来处理,以实现该新接口(接口2扩展接口1),然后在类中提供相同的实现

interface interface2 extends interface1{
     void methodY();
}

class A implements interface2{
     @override
     public void methodY(){
         //something
     }
}

class B implements interface1{
   @override
   public void methodX(){
      //something 
  };
}

默认方法实际上如何帮助我们不修改实现它的类。

因为默认方法是在接口中定义的,所以它只能访问同样在同一接口中定义的实例方法。因此,它只能调用实现类实际提供的功能(在您的示例中是
A
B


默认方法不会“更改”类的行为,它通过访问现有的、正确定义的行为来扩展它。

因为默认方法是在接口中定义的,所以它只能访问同样在同一接口中定义的实例方法。因此,它只能调用实现类实际提供的功能(在您的示例中是
A
B


默认方法不会“更改”类的行为,它通过访问现有的、正确定义的行为来扩展它。

如果您强制所有实现类重写新方法,那么它应该(如果没有有效的默认实现)不是默认方法

但是,您所说的创建扩展现有接口的新接口并使希望通过更改其实现的接口类型来覆盖新方法的类的方法将是有问题的,因为新方法是新接口的一部分,如果具有父/基接口类型,则无法访问它

例如:

现有代码:

interface Base {
    void m1();
}
class A implements Base {
   @Override
   public void m1() {
      ....
   }
}
class B implements Base {
   @Override
   public void m1() {
      ....
   }
}
您可以创建以下接口

interface ExtendedBase extends Base {
    void m2();
}
只有类
A
想要实现
m2
。因此,它成为

class A implements ExtendedBase {
   @Override
   public void m1() {
      ....
   }
   @Override
   public void m2() {
      ....
   }
}
到目前为止一切都很好

当您有一个方法接受类型为
Base
的对象时,您只能对其调用
m1
(无论您传递类型为
a
B
)的对象)


要在其他地方实际使用
m2
,您需要将
Base
更改为
ExtendedBase
,这意味着您不能再向其传递
B
。因此,您已经让所有类实现了
m2

如果您强制所有实现类重写新方法,那么它应该(如果没有有效的默认实现)不是默认方法

但是,您所说的创建扩展现有接口的新接口并使希望通过更改其实现的接口类型来覆盖新方法的类的方法将是有问题的,因为新方法是新接口的一部分,如果具有父/基接口类型,则无法访问它

例如:

现有代码:

interface Base {
    void m1();
}
class A implements Base {
   @Override
   public void m1() {
      ....
   }
}
class B implements Base {
   @Override
   public void m1() {
      ....
   }
}
您可以创建以下接口

interface ExtendedBase extends Base {
    void m2();
}
只有类
A
想要实现
m2
。因此,它成为

class A implements ExtendedBase {
   @Override
   public void m1() {
      ....
   }
   @Override
   public void m2() {
      ....
   }
}
到目前为止一切都很好

当您有一个方法接受类型为
Base
的对象时,您只能对其调用
m1
(无论您传递类型为
a
B
)的对象)

要在其他地方实际使用
m2
,您需要将
Base
更改为
ExtendedBase
,这意味着您不能再向其传递
B
。因此,您已经让所有类实现了
m2

因此,基本上,如果我在一个接口中添加一个方法Y作为默认值,那么我希望类a和类B(或类a/ClassB)重写该方法

这是错误的

默认方法的思想是在不破坏与旧代码兼容性的情况下引入新方法

使用新的默认方法不需要修改现有的实现类

这可以通过创建一个新接口和修改一个(或两个)类来处理,以实现该新接口(接口2扩展接口1),然后在类中提供相同的实现

interface interface2 extends interface1{
     void methodY();
}

class A implements interface2{
     @override
     public void methodY(){
         //something
     }
}

class B implements interface1{
   @override
   public void methodX(){
      //something 
  };
}
然后您必须触摸/修改实现类。这就是
default
方法试图避免的

因此,基本上,如果我在一个接口中添加一个方法Y作为默认值,那么我希望类a和类B(或类a/ClassB)重写该方法

这是错误的

默认方法的思想是在不破坏与旧代码兼容性的情况下引入新方法

使用新的默认方法不需要修改现有的实现类

这可以通过创建一个新接口和修改一个(或两个)类来处理,以实现该新接口(接口2扩展接口1),然后在类中提供相同的实现

interface interface2 extends interface1{
     void methodY();
}

class A implements interface2{
     @override
     public void methodY(){
         //something
     }
}

class B implements interface1{
   @override
   public void methodX(){
      //something 
  };
}
然后,您必须触摸/修改机具