0

针对接口编程,而不是针对实现编程

 2 years ago
source link: https://codeshellme.github.io/2020/12/dp-code-interface/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

针对接口编程,而不是针对实现编程

2020-12-23

675 字 阅读约需 2 分钟

针对接口编程”的真正含义是“针对超类型编程”,它利用了多态的特性。

更明确的来说就是,一个变量 a声明类型应该是超类型A,所谓的超类型一般是抽象类接口。超类型强调的是,它与它的所有派生类共有的“特性”。

这样做的好处是,变量 a 可以指向超类型 A 的任意一个派生类,并且 a 调用超类型A 中的任意一个方法都不会出错。这时 a 进行任何操作,其实都是动态决定的,而不是硬编码,这样的代码也更加有弹性。

比如,我们有下面的继承关系:

interface Animal {
void makeSound();
class Dog implements Animal {
public void makeSound() {
bark();
public void bark() {
// 汪汪叫
class Cat implements Animal {
public void makeSound() {
meow();
public void meow() {
// 喵喵叫

Animal 是一个接口(也可以是抽象类),其中包含了 makeSound 方法。

DogCat 都是 Animal 的派生类,它们除了实现 makeSound 方法外,还有各自的 barkmeow 方法。

makeSound 方法代表了 Animal 及其所有派生类的“共性”,而 barkmeow 则是“非共性”。

针对实现编程

如果我们编写了下面代码:

Dog d = new Dog();
d.bark();

那么这种代码就是“针对实现编程”,因为 d 的类型为 Dog,是一个具体类型,而不是一个抽象类型。并且 bark 方法,也是 Dog 所特有的一种操作,而不是共性。

针对接口编程

再来看下面代码:

Animal a = new Dog();
a.makeSound();

现在的代码就是“针对接口编程”了,因为 a 的类型是 Animal,是一个抽象类型,而不是一个具体类型。此时 a 调用 makeSound 方法,代表的是所有的 Animal 都能进行的一种操作。

那么再进一步,我们可以将对象的创建封装成一个方法,如下:

public static Animal getAnimal(String name) {
Animal a = null;
if (name.equals("dog")) {
a = new Dog();
} else if (name.equals("cat")) {
a = new Cat();
return a;

这样使用 getAnimal 方法:

String name = ... ; // name 可以动态决定
Animal a = getAnimal(name);
a.makeSound();

可以看到,name 变量可以动态决定,从而 a 也是动态决定的,调用 makeSound 时不需要关心真正的对象是什么,而且代码也不会出错。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK