在JDK8中,接口引入了默认方法(Default Methods),允许在接口中提供方法的默认实现。这一特性主要用于解决接口升级时的问题,即在不破坏现有实现类的情况下,向接口中添加新方法。
JDK8以后接口中新增的方法:
允许在接口中定义默认方法,需要使用关键字default修饰
作用:解决接口升级的问题
默认方法的定义
默认方法使用default
关键字修饰,并提供一个方法体。实现类可以选择重写默认方法,也可以直接使用接口中的默认实现。
interface MyInterface {
// 抽象方法
void abstractMethod();
// 默认方法
default void defaultMethod() {
System.out.println("This is a default method in the interface.");
}
}
实现类使用默认方法
实现类可以直接使用接口中的默认方法,无需重写。
class MyClass implements MyInterface {
@Override
public void abstractMethod() {
System.out.println("Implementation of abstractMethod in MyClass.");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.abstractMethod(); // 调用抽象方法的实现
obj.defaultMethod(); // 调用接口中的默认方法
}
}
解决接口升级问题
假设有一个接口MyInterface
,已经有许多类实现了该接口。现在需要向接口中添加一个新方法newMethod()
,但不想破坏现有的实现类。通过使用默认方法,可以轻松实现这一点。
interface MyInterface {
void abstractMethod();
default void newMethod() {
System.out.println("This is a new method added to the interface.");
}
}
现有的实现类无需修改,仍然可以正常工作,并且可以选择是否重写newMethod()
。
class MyClass implements MyInterface {
@Override
public void abstractMethod() {
System.out.println("Implementation of abstractMethod in MyClass.");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.abstractMethod(); // 调用抽象方法的实现
obj.newMethod(); // 调用接口中的默认方法
}
}
通过这种方式,接口的升级变得更加灵活,不会对现有代码造成破坏。
接口中默认方法的定义格式:
-
格式: public default 返回值类型 方法名(参数列表){}
-
范例:public default void show(){}
接口中默认方法的注意事项:
-
默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
-
public可以省略,default不能省略
-
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
默认方法不是抽象方法,不强制被重写
默认方法在接口中提供了默认实现,因此子类可以选择是否重写它。如果不重写,子类将使用接口中的默认实现。
interface MyInterface {
default void show() {
System.out.println("Default method in MyInterface");
}
}
class MyClass implements MyInterface {
// 不重写show方法,使用默认实现
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.show(); // 输出: Default method in MyInterface
}
}
重写默认方法时去掉default
关键字
当子类决定重写默认方法时,需要去掉default
关键字,并重新实现方法。
interface MyInterface {
default void show() {
System.out.println("Default method in MyInterface");
}
}
class MyClass implements MyInterface {
@Override
public void show() {
System.out.println("Overridden method in MyClass");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.show(); // 输出: Overridden method in MyClass
}
}
public
可以省略,default
不能省略
在接口中,默认方法的访问修饰符public
可以省略,但default
关键字不能省略。
interface MyInterface {
default void show() {
System.out.println("Default method in MyInterface");
}
}
class MyClass implements MyInterface {
// 不重写show方法,使用默认实现
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.show(); // 输出: Default method in MyInterface
}
}
多个接口中存在相同名字的默认方法,子类必须重写
如果一个类实现了多个接口,并且这些接口中有相同名字的默认方法,子类必须重写该方法以解决冲突。
interface InterfaceA {
default void show() {
System.out.println("Default method in InterfaceA");
}
}
interface InterfaceB {
default void show() {
System.out.println("Default method in InterfaceB");
}
}
class MyClass implements InterfaceA, InterfaceB {
@Override
public void show() {
System.out.println("Overridden method in MyClass");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.show(); // 输出: Overridden method in MyClass
}
}
通过以上代码示例,可以更好地理解接口中默认方法的使用和注意事项。
JDK8以后接口中新增的方法:
允许在接口中定义定义静态方法,需要用static修饰
在JDK 8中,接口引入了静态方法的概念,允许在接口中定义静态方法,并使用static
关键字进行修饰。静态方法可以直接通过接口名调用,而不需要实现类的实例。
以下是一个代码示例,展示了如何在接口中定义静态方法:
// 定义一个接口
public interface MyInterface {
// 抽象方法
void abstractMethod();
// 默认方法
default void defaultMethod() {
System.out.println("This is a default method.");
}
// 静态方法
static void staticMethod() {
System.out.println("This is a static method.");
}
}
// 实现接口的类
public class MyClass implements MyInterface {
@Override
public void abstractMethod() {
System.out.println("This is the implementation of the abstract method.");
}
public static void main(String[] args) {
// 创建实现类的实例
MyClass myClass = new MyClass();
// 调用抽象方法
myClass.abstractMethod();
// 调用默认方法
myClass.defaultMethod();
// 调用静态方法,直接通过接口名调用
MyInterface.staticMethod();
}
}
在这个示例中,MyInterface
接口定义了一个抽象方法abstractMethod
、一个默认方法defaultMethod
和一个静态方法staticMethod
。MyClass
类实现了MyInterface
接口,并提供了abstractMethod
的具体实现。在main
方法中,通过接口名直接调用了静态方法staticMethod
,而不需要创建MyClass
的实例。
接口中静态方法的定义格式:
-
格式: public static返回值类型方法名(参数列表){}
-
范例: public static void show(){}
接口中静态方法的注意事项:
-
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
-
public可以省略,static不能省略
静态方法在接口中的使用
在接口中定义静态方法时,需要注意以下几点:
-
调用方式:静态方法只能通过接口名直接调用,不能通过实现类名或对象名调用。
-
访问修饰符:
public
可以省略,但static
不能省略。
代码示例
以下是一个接口 MyInterface
的示例,其中定义了一个静态方法 staticMethod
:
interface MyInterface {
// 静态方法,public 可以省略,static 不能省略
static void staticMethod() {
System.out.println("This is a static method in the interface.");
}
}
调用静态方法
静态方法只能通过接口名调用,不能通过实现类或对象调用:
public class Main {
public static void main(String[] args) {
// 正确调用方式:通过接口名调用静态方法
MyInterface.staticMethod();
// 错误调用方式:通过实现类或对象调用静态方法
// MyInterfaceImpl.staticMethod(); // 编译错误
// MyInterface obj = new MyInterfaceImpl();
// obj.staticMethod(); // 编译错误
}
}
实现类示例
实现类 MyInterfaceImpl
实现了 MyInterface
接口,但无法通过实现类调用静态方法:
class MyInterfaceImpl implements MyInterface {
// 实现类中不需要实现静态方法
}
总结
静态方法在接口中定义时,只能通过接口名直接调用,不能通过实现类或对象调用。public
修饰符可以省略,但 static
修饰符必须保留。
JDK9接口中私有方法的定义格式:
格式1:private 返回值类型 方法名(参数列表){}
1:private void show(){ }
格式2:private static 返回值类型 方法名(参数列表){}
2: private static void method(){ }
JDK9 接口中私有方法的定义格式
在 JDK9 中,接口允许定义私有方法,这些方法只能在接口内部使用,不能被实现类或外部类调用。私有方法分为两种:实例私有方法和静态私有方法。
实例私有方法
实例私有方法使用 private
关键字定义,通常用于在接口内部封装一些通用的逻辑,避免代码重复。
public interface MyInterface {
default void publicMethod() {
show(); // 调用私有方法
}
private void show() {
System.out.println("This is a private method in the interface.");
}
}
静态私有方法
静态私有方法使用 private static
关键字定义,通常用于在接口内部封装一些静态的通用逻辑。
public interface MyInterface {
static void publicStaticMethod() {
method(); // 调用静态私有方法
}
private static void method() {
System.out.println("This is a private static method in the interface.");
}
}
代码样例说明
- 实例私有方法
show()
只能在接口内部被调用,通常用于封装一些默认方法中的通用逻辑。 - 静态私有方法
method()
只能在接口内部被调用,通常用于封装一些静态方法中的通用逻辑。
通过使用私有方法,接口可以更好地组织代码,减少重复逻辑,提高代码的可维护性。
接口的应用:
接口的定义与实现
接口是一种行为的抽象,定义了一组方法签名,但不提供具体实现。类通过实现接口来拥有这些行为。
// 定义一个接口
interface Flyable {
void fly();
}
// 实现接口的类
class Bird implements Flyable {
@Override
public void fly() {
System.out.println("Bird is flying");
}
}
class Airplane implements Flyable {
@Override
public void fly() {
System.out.println("Airplane is flying");
}
}
接口多态
当一个方法的参数是接口类型时,可以传递任何实现了该接口的类的对象。这种方式称为接口多态。
// 方法参数为接口类型
public void letItFly(Flyable flyable) {
flyable.fly();
}
// 使用接口多态
public static void main(String[] args) {
Flyable bird = new Bird();
Flyable airplane = new Airplane();
letItFly(bird); // 输出: Bird is flying
letItFly(airplane); // 输出: Airplane is flying
}
解释
Flyable
接口定义了一个fly
方法,Bird
和Airplane
类分别实现了这个接口,并提供了具体的fly
方法实现。letItFly
方法的参数类型是Flyable
接口,因此可以传递任何实现了Flyable
接口的对象,如Bird
和Airplane
的实例。- 在
main
方法中,通过接口多态,letItFly
方法可以处理不同类型的对象,并调用它们各自的fly
方法。