介绍
抽象(Abstraction)和接口(Interface)是 Java 中另外两个重要的概念。抽象类和接口虽然有一些共同点,但它们之间有很大的不同。开始这个实验,理解这些概念。
抽象(Abstraction)和接口(Interface)是 Java 中另外两个重要的概念。抽象类和接口虽然有一些共同点,但它们之间有很大的不同。开始这个实验,理解这些概念。
抽象(Abstraction) 旨在建模和维护组织结构,它不会提供太多细节。细节留给 实现类 去补充。例如,当你考虑 Animal
的情况时,复杂的行为细节对用户是隐藏的。因此,每个具体的动物都会自行实现这些细节;我们只需要调用方法即可。在面向对象编程(OOP)中,抽象是一个向用户隐藏实现细节的过程。用户只会获得功能信息,而不会知道功能是如何实现的。换句话说,用户将知道对象能做什么,而不是它如何做。在 Java 中,抽象是通过抽象类和接口来实现的。
我们使用关键字 abstract
来声明一个抽象类。抽象类可以包含或不包含抽象方法(只有声明而没有实现的方法)。但是,如果一个类至少有一个 abstract
方法,那么该类必须声明为 abstract
。如果一个类被声明为抽象类,则它不能被实例化。要使用抽象类,你必须在另一个类中继承它,并为其抽象方法提供实现。如果你继承了一个抽象类,你必须为其所有抽象方法提供实现。另一种使用抽象类的方式是调用其 类方法(static
方法)。
示例:
将以下代码写入 /home/labex/project/abstractTest.java
文件中:
// 抽象类
abstract class Animal{
// 抽象方法
public abstract void grow();
}
abstract class Bird extends Animal{
/*
* 这个类继承了 Animal,
* 但没有实现 Animal 的抽象方法 grow(),
* 因此这个类也必须声明为抽象类,
* 抽象类不能被实例化。
*/
// 这个类有一个具体方法
public void sing(){
System.out.println("I'm singing a song...");
}
}
class Dog extends Animal{
// 在这个类中,我们必须实现抽象方法,否则子类必须保持抽象。
public void grow(){
System.out.println("I'm dog, I grow up.");
}
}
public class abstractTest{
public static void main(String[] args){
Dog dog = new Dog();
dog.grow();
}
}
输出:
使用以下命令运行 abstractTest.java
文件:
javac /home/labex/project/abstractTest.java
java abstractTest
查看输出:
I'm dog, I grow up.
接口(Interface)是抽象方法的集合。这意味着 interface
中的所有方法都是 abstract
的。接口不包含任何构造函数。接口不能包含实例字段;接口中只能有静态(static)和最终(final)字段。接口不能被类继承(extend),只能被类实现(implement)。一个接口可以扩展多个接口,一个类可以实现多个接口。
示例:
将以下代码写入 /home/labex/project/interfaceTest.java
文件中:
// 使用关键字 interface 创建接口。
interface myInterface1 {
// 接口中的变量默认是 public、static 和 final 的。
String NAME = "Interface";
// 方法默认是 abstract 和 public 的。
public void method1();
}
interface myInterface2 {
// 我们可以显式地将接口中的变量定义为 public、static 和/或 final,或者像 myInterface1 那样直接定义。
public final String ID = "1001";
public void method2();
}
// myInterface3 包含 myInterface2 的方法,它从 myInterface2 扩展而来。
interface myInterface3 extends myInterface2{
public void method3();
}
// 类 interfaceTest 必须实现上层接口的所有三个方法。
public class interfaceTest implements myInterface1,myInterface3 {
/*
* 这个类有三个来自三个接口的方法
* 同时也获取了两个接口的变量
*/
// 实现 method1()
public void method1(){
System.out.println("implement method1.");
}
// 实现 method2()
public void method2(){}
// 实现 method3()
public void method3(){}
public static void main(String[] args){
// 测试方法
interfaceTest test = new interfaceTest();
test.method1();
test.method2();
test.method3();
System.out.println("I have properties:" + interfaceTest.NAME +", " +interfaceTest.ID);
}
}
输出:
使用以下命令运行 interfaceTest.java
文件:
javac /home/labex/project/interfaceTest.java
java interfaceTest
查看输出:
implement method1.
I have properties:Interface, 1001
抽象类和接口可以解耦类,并为我们提供更清晰的设计思路。它们都不能直接实例化。抽象类仅支持单继承,而接口支持多继承,并且一个类可以实现多个接口。它们都提供了多态的一些特性,这是下一个实验的主题。