在Java中的抽象类与接口:附带示例的解释
抽象类和接口在Java中用于抽象化。面向对象编程中的抽象化是指将实现细节隐藏起来,对终端用户不可见。
在抽象化中,您可以了解功能,但无法了解其实现方式。
让我们来看看每个功能并试着理解它们为什么被使用。
抽象类
在Java中,无法作为对象实例化的类,可能具有也可能没有抽象方法的类被称为抽象类。抽象方法是指在声明时没有实现体的方法。
您可以在class关键字之前使用abstract关键字来创建抽象类。
abstract class abstractClass {
void run() {
System.out.println("ran");
}
}
抽象类可以由其他类继承。换句话说,它也可以被子类化。
abstract class AbstractClass {
void run() {
System.out.println("ran");
}
}
class ExtendingAbstractClass extends AbstractClass {
void newMethod() {
System.out.println("new");
}
@Override
void run() {
System.out.println("override");
}
}
抽象类用于在多个继承给定抽象类的类之间实现公共方法。此外,在抽象类中定义抽象方法的能力使其对具有类似方法但具有不同实现的类非常有用。让我们举个例子。
考虑一个具有一些功能(如启动、停止、倒车等)的汽车。这些功能在所有类型的汽车中都是共同的。
但是自动化功能(如自动驾驶)怎么办?这些功能的实现因不同类型的汽车而异。让我们看看如何创建与此相关的面向对象程序。
首先,创建一个Car
类,该类将由不同类型的多个汽车类扩展。
abstract class Car {
void start() {
// implementation
System.out.println("runs car");
}
void stop() {
// implementation
System.out.println("engine stops");
}
void reverse() {
// implementation
System.out.println("reverse mode enabled");
}
abstract void selfDrive();
}
方法start()
、stop()
和reverse()
是所有汽车共有的方法。因此,它们的实现已经在Car类中定义。然而,某种类型的汽车可以有不同的自动驾驶模式实现。因此,您可以将selfDrive()
定义为抽象方法,并在不同类型的汽车的不同类中以不同方式实现它。
class CarTypeA extends Car {
@Override
void start() {
super.start();
}
@Override
void stop() {
super.stop();
}
@Override
void reverse() {
super.reverse();
}
void selfDrive() {
// custom implementation
System.out.println("Type A self driving mode enabled");
}
}
class CarTypeB extends Car {
// ...所有相似的方法
void selfDrive() {
// custom implementation
// 与CarTypeB不同的实现
System.out.println("Type B self driving mode enabled");
}
}
需要注意的是,如果子类没有实现抽象类中定义的所有抽象方法,则它应该自身被声明为抽象类。
接口
接口是告诉类必须实现的方法的一种方式。例如,如果考虑汽车的例子,它具有一些基本功能。它可以启动、移动和停止。这些功能在所有汽车中是共同的。
所以,如果在一个类中实现一个汽车的接口,你必须实现所有的方法,以使汽车能够正常安全地运行。
与抽象类类似,我们不能实例化或创建接口的对象。它可以被认为是一个完全抽象的类,因为它只包含没有实现体的抽象方法。
你可以使用interface
关键字来创建一个接口。
interface CAR {
void start();
void stop();
void move();
}
在定义类时,使用implements
关键字来实现一个接口。
class CarTypeB implements CAR {
public void start() {
System.out.println("started");
}
public void stop() {
System.out.println("stopped");
}
public void move() {
System.out.println("running");
}
}
相似性
不实例化作为对象是抽象类和接口共同的特点。
区别
抽象类 | 接口 | |
继承和实现 | 一个类只能继承一个抽象类。 | 一个类可以实现多个接口。 |
变量类型 | 可以有final、非final、静态和非静态变量。 | 只能有静态和final变量。 |
方法类型 | 可以包含抽象方法和非抽象方法。 | 只能包含抽象方法,但静态方法是个例外。 |
访问修饰符 | 抽象类可以有访问修饰符。 | 接口中定义的方法签名默认为public。接口没有访问修饰符。 |
构造函数和析构函数 | 可以声明构造函数和析构函数。 | 不能声明构造函数或析构函数。 |
速度 | 快 | 慢 |
何时使用抽象类和接口?
使用抽象类时:
- 您想在多个类之间共享一些公共的方法和字段。
- 声明
非静态
和非final
字段,以便修改它们所绑定的对象的状态。
使用接口时:
- 您想定义实现接口的类的行为,但不关心它的实现方式。
- 您想确保一个类实现所有的方法以正常运行。
最后
接口主要用于创建API,因为它们可以提供一个结构来实现功能而不必担心实际的实现。
抽象类通常用于在多个类之间共享公共的抽象和非抽象方法,这些类扩展了抽象类以使代码更可重用。
通过这些 online courses for java 来了解更多关于Java的知识。您准备进行Java面试吗?这里有一些 interview questions on Object Oriented Programming。