接口中静态和默认方法的区别

Vip*_*non 94 java java-8

当我注意到你现在可以在界面中定义静态和默认方法时,我正在通过接口学习.

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

    public default void menthod3() {
        System.out.println("default print");
    }
}
Run Code Online (Sandbox Code Playgroud)

请解释两者的区别,如果有一个例子,我们什么时候使用它会很好.在接口上有点困惑.

sti*_*ger 102

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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..");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • static关键字的用途没有改变 - 定义类级别成员:字段,方法等.在Java 8中,这种行为被扩展为接口,因此它们变得更加类似于类,现在可以在大多数情况下替换类. (4认同)
  • 但是为什么要“静态”呢?它在Java 8中有什么作用? (2认同)

Eya*_*sSH 28

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

bar另一方面,默认实现由.调用

Interface x = new ConcreteClass();
x.bar();
Run Code Online (Sandbox Code Playgroud)

一个static接口方法不能知道的this变量,而是一个默认的实现可以.


Sha*_*016 16

1.解释两者的区别

静态接口方法类似于静态类方法(这里它们只属于接口).其中默认接口方法提供default implementation了接口方法(实现类可能override)
但请记住,如果一个类是implementing more than one interface with same default方法签名,那么实现类needs to override the default method

你可以在下面找到一个简单的例子(可以根据不同的情况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);
    }
}
Run Code Online (Sandbox Code Playgroud)

2.当我们使用它时会很好.

这取决于你的问题陈述.我会说Default方法很有用,如果你需要在你的规范中对该方法中的所有类中的方法执行相同的实现,或者它可以像Adapter类一样使用.

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

在oracle doc下面还解释了用于演进现有接口的默认和静态方法:

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

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


Abh*_*eet 8

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

defaultstatic方法弥补了接口抽象类之间的差异.

界面默认方法:

  • 它有助于避免实用程序类,例如可以在接口本身中提供所有Collections类方法.
  • 它有助于扩展接口而不必担心破坏实现类.

接口静态方法:

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

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


小智 7

这是我的看法:

接口中的静态方法

  • 您可以直接调用它(InterfacetA.staticMethod())

  • 子类将无法覆盖。

  • 子类可能具有与staticMethod同名的方法

接口中的默认方法

  • 您不能直接调用它。

  • 子类将能够覆盖它

优点:

  • 静态方法:您无需为实用程序方法创建单独的类。

  • 默认方法:提供默认方法的常用功能。


小智 5

根据Java14 JLS 文档:

默认方法:

  • 它是在具有默认修饰符的接口中声明的实例方法

  • 它只能被实现类的实例访问

  • 它的主体总是由一个块表示,它为任何实现类提供默认实现或行为,而无需覆盖该方法

  • 它永远不能是静态的或私有的

静态方法:

  • 可以在不引用特定对象的情况下通过接口调用,就像类静态方法一样

  • 静态方法可以是私有的

  • 实现类不能访问静态方法

让我们借助以下示例代码来理解它:

            public interface MyInterface {
        
            private void privateMethod() {
                System.out.println("Hi, this is privateMethod");
            }
        
            private static void staticPrivateMethod() {
                System.out.println("Hi, this is staticPrivateMethod");
            }
        
            static void staticMethod() {
                //privateMethod();    // Non-static method cannot be referenced from a static contex
                System.out.println("Hi, this is staticMethod");
                staticPrivateMethod();
            }
        
            default void defaultMethod() {
                System.out.println("Hi, this is defaultMethod");
            }
        
        }
    
    public class MyInterfaceImpl implements MyInterface{
        public static void main(String[] args) {
    
            MyInterface.staticMethod();
            // myInterface.staticMethod(); // Not allowed
    
            MyInterface myInterface = new MyInterfaceImpl();
            myInterface.defaultMethod();
            // MyInterface.defaultMethod(); // Not allowed
    
        }
    }

Run Code Online (Sandbox Code Playgroud)