鴨子類型(duck typing)是動態(tài)類型的一種風(fēng)格穿香。在這種風(fēng)格中一個對象的有效語義不是由繼承自特定的類或?qū)崿F(xiàn)特定的接口漓糙,而是由當前的方法和屬性的集合決定。
"當看到一只鳥走起來像鴨子奕筐、游泳起來像鴨子泪酱、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子茴肥。"
在鴨子類型中坚踩,關(guān)注的不是對象的類型本身,而是它是如何使用的瓤狐。
由于鴨子類型機制常見于動態(tài)語言瞬铸,我們先看個Python的例子:
class Duck:
def quack(self):
print "鴨子叫"
def feathers(self):
print "鴨子有羽毛"
class Person:
def quack(self):
print "模仿鴨子叫"
def feathers(self):
print "人沒有羽毛"
def in_the_forest(duck):
duck.quack()
duck.feathers()
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
game()
在該例中in_the_forest方法不關(guān)注傳入的參數(shù)是那種類型,而關(guān)心該對象是否有特定的方法础锐。
Java 實現(xiàn)鴨子類型
- 其中一種方式是通過多態(tài)
public interface Performer {
void eat();
void walk();
}
public class Dog implements Performer {
@Override
public void eat() {
System.out.println("狗吃狗糧");
}
@Override
public void walk() {
System.out.println("狗跑的很快");
}
}
public class Cat implements Performer {
@Override
public void eat() {
System.out.println("貓吃貓糧");
}
@Override
public void walk() {
System.out.println("貓走路很輕盈");
}
}
public class T {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
perform(dog);
perform(cat);
}
static <T extends Performer> void perform(T duck){
duck.eat();
duck.walk();
}
}
嚴格來說這種實現(xiàn)并非準確的鴨子模型嗓节,因為perform方法的參數(shù)必須實現(xiàn)了Performer接口,即關(guān)注了對象的本身的類型
- 常用方式是使用反射
public class Cat {
public void eat() {
System.out.println("貓吃貓糧");
}
public void walk() {
System.out.println("貓走路很輕盈");
}
}
public class Dog {
public void eat() {
System.out.println("狗吃狗糧");
}
public void walk() {
System.out.println("狗跑的很快");
}
}
public class T {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
try {
perform(dog);
perform(cat);
} catch (Exception e){
e.printStackTrace();
}
}
static void perform(Object duck) throws Exception {
Class clazz = duck.getClass();
Method eat = clazz.getMethod("eat");
eat.invoke(duck);
Method walk = clazz.getMethod("walk");
walk.invoke(duck);
}
}
比起使用多態(tài)皆警,使用反射更接近于鴨子模型拦宣,perform方法不關(guān)心傳入的對象的類型,只關(guān)心該對象是否擁有指定的方法。