针对接口编程,而不是针对实现编程
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.
针对接口编程,而不是针对实现编程
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
方法。
Dog
和 Cat
都是 Animal
的派生类,它们除了实现 makeSound
方法外,还有各自的 bark
和 meow
方法。
makeSound
方法代表了 Animal
及其所有派生类的“共性”,而 bark
和 meow
则是“非共性”。
针对实现编程
如果我们编写了下面代码:
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
时不需要关心真正的对象是什么,而且代码也不会出错。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK