当我注意到你现在可以在界面中定义静态和默认方法时,我正在通过接口学习。
public interface interfacesample2 {
public static void method() {
System.out.println("hello world");
}
public default void menthod3() {
System.out.println("default print");
}
}
请解释两者的区别,如果有一个例子,我们何时会使用它会很好。接口上有点困惑。
答案 0 :(得分:93)
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..");
}
}
答案 1 :(得分:28)
静态方法是一种适用于类“命名空间”的方法,可以这么说。因此,static
可以访问foo
接口Interface
的{{1}}方法Interface.foo()
。请注意,函数调用不适用于接口的任何特定实例。
另一方面,默认实现bar
由
Interface x = new ConcreteClass();
x.bar();
static
接口方法无法知道this
变量,但默认实现可以。
答案 2 :(得分: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);
}
}
<强> 2。当我们使用它时会很好。
这取决于你的问题陈述。我会说默认方法很有用,如果你在规范中的方法中需要在该合同的所有类中使用相同的实现,或者它可以像Adapter
类一样使用。
也在oracle doc下面解释默认&amp;用于发展现有接口的静态方法:
具有实现使用new增强的接口的类的用户 默认或静态方法不必修改或重新编译它们 适应其他方法。
http://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html
答案 3 :(得分:8)
This link有一些有用的见解,在此列出了一些有用的见解。
默认&amp; 静态方法弥补了接口和抽象类之间的差异。
接口默认方法:
界面静态方法:
喜欢引用另一个有用的reference。
答案 4 :(得分:6)
以下是我的观点:
接口中的静态方法:
您可以直接调用它(InterfacetA.staticMethod())
子类将无法覆盖。
子类可能具有与staticMethod同名的方法
默认方法:
您无法直接调用它。
子类将能够覆盖它
<强>优势:强>
静态方法:您不需要为实用工具方法创建单独的类。
默认方法:以默认方式提供常用功能。
答案 5 :(得分:3)
根据Oracle的Javadocs:http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码具有二进制兼容性。
静态方法是一种与定义它的类相关联的方法,而不是与任何对象相关联的方法。该类的每个实例都共享其静态方法。
通常,interface中的static方法用作Helper方法,而default方法用作实现该接口的类的默认实现。
示例:
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());
}
}
答案 6 :(得分:3)
界面默认方法:
它有助于避免实用程序类,例如可以在接口本身中提供所有Collections类方法。
它有助于扩展接口而不必担心破坏实现类。
接口静态方法:
它们是接口的一部分,我们不能将它用于实现类对象。
通过不允许实现类覆盖它们来帮助提供安全性。
现在静态方法如何提供安全性。我们来看一个例子。
interface MyInterface {
/*
* This is a default method so we need not to implement this method in the implementation classes
*/
default void newMethod() {
System.out.println("Newly added default method in Interface");
}
/*
* This is a static method. Static method in interface is similar to default method except that we cannot override them in the implementation classes. Similar to default methods, we need to implement these methods in implementation classes so we can safely add them to the existing interfaces.
*/
static void anotherNewMethod() {
System.out.println("Newly added static method in Interface");
}
/*
* Already existing public and abstract method We must need to implement this method in implementation classes.
*/
void existingMethod(String str);
}
public class Example implements MyInterface {
// implementing abstract method
public void existingMethod(String str) {
System.out.println("String is: " + str);
}
public void newMethod() {
System.out.println("Newly added default method in Class");
}
static void anotherNewMethod() {
System.out.println("Newly added static method in Class");
}
public static void main(String[] args) {
Example obj = new Example();
// calling the default method of class
obj.newMethod();
// calling the static method of class
obj.anotherNewMethod();
// calling the static method of interface
MyInterface.anotherNewMethod();
// calling the abstract method of interface
obj.existingMethod("Java 8 is easy to learn");
}
}
这里obj.newMethod();
打印类实现逻辑,意味着我们可以在实现类中更改该方法的逻辑。
但是obj.anotherNewMethod();
打印类实现逻辑,但没有改变接口实现。因此,如果在该方法中编写的任何加密 - 解密逻辑都无法更改。
答案 7 :(得分:2)
根据 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
}
}
答案 8 :(得分:0)
我们无法执行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");
}
}
答案 9 :(得分:0)
启动Java 8接口也可以具有静态方法。像类的静态方法一样,可以使用接口名称来调用接口的静态方法。
示例
public interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
default int multiply(int a, int b) {
throw new RuntimeException("Operation not supported. Upgrade to UltimateCalculator");
}
static void display(String value) {
System.out.println(value);
}
}
接口的静态方法和默认方法之间的区别是默认方法支持继承,但静态方法不支持。可以在继承接口中覆盖默认方法。
这里很好地了解了接口的默认方法和静态方法。 Interface Default Method in Java 8
答案 10 :(得分:0)
所有好的答案都在这里。我想在界面中添加静态函数的另一种实际用法。提示来自Joshua Bloch在《第二章:创建和销毁对象》中的书-有效的Java,第三版。
Static functions can be used for static factory methods.
静态工厂方法是返回对象的方法。它们像构造函数一样工作。在特定情况下,静态工厂方法比使用构造函数提供的可读性更高。
书中引述-约书亚·布洛赫(Joshua Bloch)第三版,有效的Java
在Java 8之前,接口不能使用静态方法。通过 按照惯例,名为Type的接口的静态工厂方法为 放入名为Types的不可实例的伴随类(第4项)。
作者提供了一个Collections的示例,其中实现了这种静态工厂方法。检查代码,Josh Bloch可以被视为Collections类的第一作者。尽管Collections是类而不是接口。但是这个概念仍然适用。
例如,Java Collections Framework具有45个实用程序 接口的实现,提供不可修改的集合, 同步集合等。几乎所有这些 通过静态工厂方法将实现导出为一个 不可实例化的类(java.util.Collections)。的类别 返回的对象都是非公开的。
他进一步解释说,API不仅更小,而且还有助于提高代码的可读性和API的易用性。
减少的不仅是API的大部分,而且是概念上的 权重:程序员概念的数量和难度 必须掌握才能使用API。程序员知道 返回的对象恰好具有其接口指定的API,因此 无需阅读有关 实现类。
这是java.util.Collections类中的静态方法之一:
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
return new UnmodifiableCollection<>(c);
}