一个类中有抽象方法,则必须声明为abstract(做为抽象类),抽象类不能实例化。子类继承抽象类,必须对所有的抽象方法重写,否则依然有抽象方法,还是抽象的,无法实例化。故抽象类常做为基类。
一个类中所有方法都是抽象方法,那么该类就可以使用接口来实现。
在Java语言中,接口(interface)默认是公开的(public)。这意味着,当你定义一个接口时,你不需要显式地将其声明为public,它默认就是public的。
例如,以下两种定义方式是等效的:
public interface MyInterface {
void myMethod();
}
interface MyInterface {
void myMethod();
}
在第二种情况下,虽然没有在接口前加上public关键字,但接口仍然默认是public的。
请注意,接口内的常量(常量成员变量)和方法默认是public static和public abstract的,这意味着可以直接通过接口名来访问它们,而不需要创建接口的实例。可以显式地给这些常量和方法添加public关键字,但这并不是必需的,因为它们是默认公开的。
例如,以下两种定义方式是等效的:
public interface MyInterface {
public static final int MY_CONSTANT = 10;
public abstract void myMethod();
}
interface MyInterface {
static final int MY_CONSTANT = 10;
abstract void myMethod();
}
另外,虽然Java语言允许你显式地在接口上使用public关键字,但实际上,由于接口默认是public的,这些显式声明通常是不必要的。
在Java编程语言中,接口(Interface)是一个非常重要的概念,具有多重意义。以下是接口在Java中的主要意义:
- 定义行为规范:接口定义了一组方法,这些方法由实现该接口的类来提供具体实现。这提供了一种机制,允许类遵循特定的行为规范或契约,而无需知道实现这些方法的具体细节。
- 实现多态:接口是实现多态性的关键工具之一。通过接口,我们可以创建一个接口类型的引用,该引用可以指向实现该接口的任何类的对象。这使得我们可以在不修改现有代码的情况下,将新的实现添加到系统中,从而增强了系统的可扩展性。
- 解耦:接口有助于降低类之间的耦合度。通过将功能划分为独立的接口,我们可以减少类之间的直接依赖关系,从而使代码更易于维护、测试和重用。
- 抽象:接口提供了一种抽象机制,允许我们只关注对象的行为,而不是其具体实现。这有助于我们创建更通用、更灵活的代码。
- 实现代码重用:多个类可以实现同一个接口,这意味着它们可以共享相同的方法签名。这有助于减少代码冗余,提高代码重用性。
- 支持回调:接口经常用于实现回调机制,即允许一个对象在某个事件发生时调用另一个对象的方法。这在事件驱动编程中非常常见,例如当用户点击按钮或触发其他事件时,程序会调用相应的回调函数。
总结:
(1)接口中的所有方法都是public abstact;
(2)与public 类一样,接口也必须定义在与接口同名的.java文件中;
(3)在接口中声明方法时,不能使用native、final、synchronized、protected等说明符。
(4)与类的继承不同的是,要使用接口,需要编写一个类去实现该接口,使用implements关键字,而不是extends,并要给出接口中的所有方法的具体实现。
(5)Java要求:在覆盖或者实现方法时,覆盖或者实现的方法设置的访问权限必须高于或等于被覆盖或实现的访问权限。方法的4种访问说明符的访问权限从高到低分别是:public、protected、default(不加访问说明符时)、private。接口中的所有方法都是public访问权限,因此在实现接口时,方法的访问权限只能是public。
(6)接口与抽象类的区别是:接口只是定义了实现它的类应该用什么方法,相当于为类的实现制定了一个规约;而抽象类除了抽象方法外,还可以定义一些方法的默认实现。如何在抽象类与接口间取舍呢?当需要一个公共实现来简化子类的创建时,使用抽象类比较合适。如果是对外提供一个统一的操作模型,则使用接口更加合适。
(7)接口中的数据成员默认都是public(公共的)、static(静态)的常量,因此在接口中声明时可以省略public static final。接口中的静态常量通过“接口名称.常量名称”的方式进行访问。如下面代码Week.java文件中定义的接口Week。可以使用Week.FRIDAY,如果某个类实现了这个接口,也可以这个类名来访问(“实现接口的类名.接口中定义的常量名”)。当然,在接口或者实现接口的类内部访问静态常量,直接访问即可。
package com.test;public interface Week {int SUNDAY = 0; //等价于public static final int SUNDAY = 0; 下同int MONDAY = 1;int TUESDAY = 2;int WEDNESDAY = 3;int THURSDAY = 4;int FRIDAY = 5;int SATURDAY = 5;}class DoSomethingWithWeek implements Week {void doWeek(int day) {switch (day) {case SUNDAY:System.out.println("星期天");break;case MONDAY:System.out.println("星期一");break;}}public static void main(String[] args) {// 实现接口的类中,使用接口中定义的常量的集中方式System.out.println(Week.SUNDAY); // 使用"接口名.常量名称"方式使用接口中的常量System.out.println(SUNDAY); // 直接使用“常量名”System.out.println(DoSomethingWithWeek.SUNDAY); // 使用"实现接口的类名.常量名称"方式使用接口中的常量DoSomethingWithWeek d = new DoSomethingWithWeek(); // 创建实现接口的类的实例d.doWeek(SUNDAY); // 在类的方法中使用接口中的常量}
}
(8)当一个类实现一个接口时,它必须提供该接口中所有抽象方法的实现。这是Java中实现接口的基本规则。然而,除此之外,该类还可以定义自己的新方法。这些方法并不需要在接口中声明,也不需要在接口的所有实现类中都有。它们是这个类特有的功能。
以下是一个简单的例子: // 定义一个接口 public interface MyInterface {void interfaceMethod(); // 接口中的抽象方法 }// 创建一个类实现该接口 public class MyClass implements MyInterface {// 实现接口中的抽象方法@Overridepublic void interfaceMethod() {System.out.println("Implementing interface method");}// 在类中定义自己的新方法public void myNewMethod() {System.out.println("This is a new method in MyClass");}public static void main(String[] args) {MyClass obj = new MyClass();// 调用接口方法obj.interfaceMethod();// 调用类的新方法obj.myNewMethod();} }