目录
比喻
想象一下,你有一个 “交通工具” 的抽象概念(可以是一个接口或类),然后你有不同的具体交通工具,比如 “汽车” 和 “自行车”。
1. 交通工具(Driver)
- 这是一个接口,定义了所有交通工具应该具备的功能,比如 “行驶”。
2. 汽车(Car)和自行车(Bicycle)
- 这两个类实现了 “交通工具” 的功能。
代码示例:
interface Vehicle {
void drive(); // 行驶的方法
}
class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Car is driving.");
}
}
class Bicycle implements Vehicle {
@Override
public void drive() {
System.out.println("Bicycle is pedaling.");
}
}
public class Main {
public static void main(String[] args) {
Vehicle v = new Car(); // 创建一个汽车对象
v.drive(); // 输出: Car is driving.
v = new Bicycle(); // 现在把 v 变成一个自行车对象
v.drive(); // 输出: Bicycle is pedaling.
}
}
-
Vehicle v = new Car();
:你创建了一个 “汽车” 对象,并把它赋值给一个 “交通工具” 类型的变量v
。你可以通过v
来调用 “汽车” 的功能。 -
v.drive();
:调用drive
方法,输出 “Car is driving.”。 -
然后你可以把
v
重新赋值为一个 “自行车” 对象,依然使用同一个变量v
,但现在它代表的是 “自行车”。
思考:为什么不直接 Car V=new Car( );?
使用 Vehicle v = new Car();
而不是 Car v = new Car();
的主要原因是 多态性 和 灵活性。下面是一些具体的原因和好处:
1. 多态性
- 多态性允许你使用父类(或接口)类型的引用来指向子类(或实现类)的对象。这意味着你可以在运行时决定使用哪个具体的实现。
- 例如,如果你有多个实现(如
Car
和Bicycle
),你可以将它们都赋值给同一个Vehicle
类型的变量,这样你就可以通过同一个接口来处理不同的对象。
2. 代码的灵活性
- 使用接口或父类类型的引用可以让你的代码更灵活。例如,你可以在运行时根据条件选择不同的实现,而不需要修改代码的其他部分。
Vehicle v; if (condition) { v = new Car(); } else { v = new Bicycle(); } v.drive(); // 根据条件调用不同的实现
3. 易于扩展
- 如果将来你想添加新的交通工具(例如
Truck
),只需实现Vehicle
接口,而不需要修改使用Vehicle
类型的现有代码。class Truck implements Vehicle { @Override public void drive() { System.out.println("Truck is driving."); } } // 使用时 Vehicle v = new Truck(); v.drive(); // 输出: Truck is driving.
4. 减少耦合
- 使用接口可以减少代码之间的耦合,使得代码更易于维护和测试。你可以轻松替换实现而不影响使用它的代码。
-
总结
- 使用
Vehicle v = new Car();
提供了更大的灵活性和可扩展性,使得代码更具可维护性和可读性。而直接使用Car v = new Car();
则限制了你只能使用Car
类型,失去了多态性带来的优势。