界面中静态和默认方法的区别

当我发现现在可以在界面中定义静态方法和默认方法时,我正在通过接口学习。

public interface interfacesample2 { public static void method() { System.out.println("hello world"); } public default void menthod3() { System.out.println("default print"); } } 

请解释两者的区别,如果有一个例子,我们将使用这将是很好的。 对接口有点困惑。

Java 8中静态和默认方法之间的区别:

1)在实现类中可以重写默认方法,而静态方法不能

2)静态方法属于Interface类,所以你只能在Interface类上调用静态方法,而不能在实现这个接口的类上调用,参见:

 public interface MyInterface { default void defaultMethod(){ System.out.println("Default"); } static void staticMethod(){ System.out.println("Static"); } } public class MyClass implements MyInterface { public static void main(String[] args) { MyClass.staticMethod(); //not valid - static method may be invoked on containing interface class only MyInterface.staticMethod(); //valid } } 

3)类和接口都可以有相同名称的静态方法,也不会重写其他的!

 public class MyClass implements MyInterface { public static void main(String[] args) { //both are valid and have different behaviour MyClass.staticMethod(); MyInterface.staticMethod(); } static void staticMethod(){ System.out.println("another static.."); } } 

静态方法是一种适用于类“命名空间”的方法,可以这么说。 所以接口Interface一个static方法fooInterface.foo()访问。 请注意,函数调用不适用于任何特定的接口实例

另一方面,默认的实现bar被调用

 Interface x = new ConcreteClass(); x.bar(); 

static接口方法不能知道thisvariables,但是默认的实现可以。

1.解释两者的区别

静态接口方法就像静态类方法(这里它们只属于Interface)。 作为默认的接口方法提供接口方法的default implementation (实现类可以override
但是请记住,如果一个类正在implementing more than one interface with same default方法签名的implementing more than one interface with same default那么实现类needs to override the default method

你可以在下面find一个简单的例子(可以DIY不同情况下)

 public class Test { public static void main(String[] args) { // Accessing the static member I1.hello(); // Anonymous class Not overriding the default method I1 t = new I1() { @Override public void test() { System.out.println("Anonymous test"); } }; t.test(); t.hello("uvw"); // Referring to class instance with overridden default method I1 t1 = new Test2(); t1.test(); t1.hello("xyz"); } } interface I1 { void test(); //static method static void hello() { System.out.println("hello from Interface I1"); } // default need not to be implemented by implementing class default void hello(String name) { System.out.println("Hello " + name); } } class Test2 implements I1 { @Override public void test() { System.out.println("testing 1234..."); } @Override public void hello(String name) { System.out.println("bonjour" + name); } } 

2.当我们使用这个会很好。

这取决于你的问题陈述。 如果你需要在你的规范中的一个方法在你的规范中的所有类中实现相同的实现,或者它可以像Adapter类一样使用,那么Default方法是有用的。

这里是一个很好的阅读: https : //softwareengineering.stackexchange.com/questions/233053/why-were-default-and-static-methods-added-to-interfaces-in-java-8-when-we-alread

也在Oracle文档下解释了用于演化现有接口的默认和静态方法:

拥有使用新的默认或静态方法增强接口的类的用户不必修改或重新编译它们以适应其他方法。

http://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html

这个链接有一些有用的见解,在这里列出了一些。

默认静态方法弥合了接口抽象类之间的差异。

接口默认方法:

  • 它有助于避免工具类,比如所有的Collections类方法都可以在接口本身提供。
  • 它有助于扩展接口,而不用担心破坏实现类。

接口静态方法:

  • 它们是接口的一部分,我们不能用它来实现类对象。
  • 它通过不允许实现类覆盖它们来帮助提供安全性。

喜欢引用另一个有用的参考 。

根据Oracle的Javadocs: http : //docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

默认方法使您能够为库的接口添加新function,并确保与为这些接口的旧版本编写的代码的二进制兼容性。

静态方法是一种与其定义的类关联的方法,而不是任何对象。 每个类的实例共享其静态方法。

通常,接口中的静态方法用作Helper方法,而默认方法用作实现该接口的类的默认实现。

例:

 interface IDemo { //this method can be called directly from anywhere this interface is visible static int convertStrToInt(String numStr) { return Integer.parseInt(numStr); } //getNum will be implemented in a class int getNum(); default String numAsStr() { //this.getNum will call the class's implementation return Integer.toString(this.getNum()); } } 

这在Oracle文档中得到了最好的解释。

在Java 8中,接口可以包含实现的方法,静态方法和所谓的“默认”方法(实现类不需要重写)。

在我(可能是天真的)看来,没有必要违反像这样的接口。 接口一直是你必须履行的合同,这是一个非常简单和纯粹的概念。 现在它是几件事的混合物。 我的想法是:

 static methods do not belong to interfaces. They belong to utility classes. "default" methods shouldn't have been allowed in interfaces at all. You could always use an abstract class for this purpose. 

简而言之:

在Java 8之前

  • 你可以使用抽象的和常规的类来提供静态和默认的方法。 界面的作用很明显。
  • 接口中的所有方法都应该通过实现类来重写。
  • 你不能在一个接口中添加一个新的方法而不修改所有的实现,但这实际上是一件好事。

在Java 8之后

  • 接口和抽象类之间几乎没有区别(多重inheritance除外)。 实际上你可以用一个接口模拟一个普通的类。
  • 编程实现时,程序员可能忘记覆盖默认的方法。
  • 如果一个类试图实现具有相同签名的默认方法的两个或多个接口,则会出现编译错误。
  • 通过向接口添加默认方法,每个实现类都会自动inheritance此行为。 其中的一些类可能没有devise出新的function,这可能会导致问题。 例如,如果某人在接口Ix中添加了一个新的默认方法default void foo(),那么实现Ix的类Cx和具有相同签名的私有foo方法将不会被编译。

我们不能执行Interfacesample2.menthod3(); 因为它不是静态的方法。 为了执行method3()我们需要一个Interfacesample2接口的实例。

请看下面的实例:

 public class Java8Tester { public static void main(String args[]){ // Interfacesample2.menthod3(); Cannot make a static reference to the non-static method menthod3 from the type Interfacesample2 new Interfacesample2(){ }.menthod3();// so in order to call default method we need an instance of interface Interfacesample2.method(); // it } } interface Interfacesample2 { public static void method() { System.out.println("hello world"); } public default void menthod3() { System.out.println("default print"); } }