多态
同一操作作用于不同的对象上面,可以产生不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。
让你叫,你就叫
var makeSound = function(animal){
if(animal instanceof Duck){
console.log('嘎嘎嘎');
}else if(animal instanceof Chicken){
console.log('咯咯咯');
}
};
var Duck = function(){};
var Chicken = function(){};
makeSound(new Duck());
makeSound(new Chicken());
真正意义的多态
// 不变部分隔离出来,所有动物都会发出叫声
var makeSound = function(animal){
animal.sound();
};
//封装可变部分--对象的多态性
var Duck = function(){};
Duck.prototype.sound = function(){
console.log('嘎嘎嘎');
};
var Chicken = function(){};
Chicken.prototype.sound = function(){
console.log('咯咯咯');
};
makeSound(new Duck());
makeSound(new Children());
//此时增加一只狗
var Dog = function(){};
Dog.prototype.sound = function(){
console.log('汪汪汪');
};
makeSound(new Dog());
JavaScript在编译时没有类型检查的过程,既没有检查创建对象类型, 又没有检查传递的参数类型。
Java多态实现
public class Duck {
public void makeSound(){
System.out.println('嘎嘎嘎');
}
}
public class Chicken {
public void makeSound(){
System.out.println('咯咯咯');
}
}
public class AnimalSound {
public void makeSound(Duck duck){
duck.makeSound();
}
}
public class Test {
public static void main(String args[]){
AnimalSound animalSound = new AnimalSound();
Duck duck = new Duck();
animalSound.makeSound(duck);
}
}
我们已经顺利地让鸭子可以发出叫声,如果让鸡也叫,可能受AnimalSound类的makeSound方法只接受Duck类型参数的影响然后报错
public class Test {
public static void main(String args[]){
AnimalSound animalSound = new AnimalSound();
Chicken chicken = new Chicken();
animalSound.makeSound(chicken); //报错,只能接受Duck类型的参数
}
}
为解决这问题,静态类型的面向对象语言通常被设计为可以向上转型:当给一个类变量赋值时,这个变量的类型既可以使用这个类本身,也可以使用这个类的超类。
可以让Duck对象和Chicken对象的类型都被隐藏在超类型Animal ,这通常是对象表现多态型的必经之路。
使用继承得到多态效果
继承通常包括实现继承和接口继承
先创建一个Animal抽象类,再分别让Duck和Chicken都继承自Animal抽象类。
public abstract class Animal {
abstract void makeSound(); // 抽象方法
}
public class Chicken extends Animal {
public void makeSound(){
System.out.println('咯咯咯');
}
}
public class Duck extends Animal {
public void makeSound(){
System.out.println('嘎嘎嘎');
}
}
Animal duck = new Duck();
Animal chicken = new Chicken();
让AnimalSound类的makeSound方法接收Animal类型的参数
public class AnimalSound{
public void makeSound(Animal animal){
animal.makeSound();
}
}
public class Test {
public static void main(String args[]){
AnimalSound animalSound = new AnimalSound();
Animal duck = new Duck();
Animal chicken = new Chicken();
animalSound.makeSound(duck);
animalSound.makeSound(chicken);
}
}
地图案例
var googleMap = {
show: function(){
console.log('开始渲染谷歌地图');
}
};
var renderMap = function(){
googleMap.show();
};
renderMap();
//-----------------------------------------
// google->baidu
var googleMap = function(){
show:function(){
console.log('开始渲染谷歌地图');
}
};
var baiduMap = function(){
show: function(){
console.log('开始渲染百度地图');
}
};
var renderMap = function(type) {
if(type == 'google'){
googleMap.show();
} else if(type === 'baidu') {
baiduMap.show();
}
};
renderMap('google');
renderMap('baidu');
//--------------------------------------
var renderMap = function(map){
if(map.show instanceof Function){
map.show();
}
};
renderMap(googleMap);
renderMap(baiduMap);
//增加搜搜
var sooMap = {
show: function(){
console.log('开始渲染搜搜地图');
}
};
renderMap(sosoMap);