Java中的多态
我们知道Java是强类型语言,如果将预先定义好的类型进行其他赋值就会报错
String str;
str = 'abc';
str = 2; // 报错
我们想在让给函数传不同对象时,能执行该对象中的方法。在下面代码中,我们想在给AnimalSound类的makeSound方法传入chicken或者duck对象可以发出叫声
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('嘎嘎噶');
}
}
public class AnimalSound(){
public void makeSound(Chicken chiken){
//makeSound的具体实现
chiken.makeSound();
}
}
//...
Animal duck = new Duck();
Animal chicken = new Chicken();
AnimalSound animalSound = new AnimalSound();
animalSound.makeSound(duck); //报错,类型不同
为了绕过这个类型检查,我们在Animal类的makeSound方法中让它接收Animal类型的参数,而不是具体的Duck或者Chicken类型
public class AnimalSound(){
public void makeSound(Animal animal){
//makeSound的具体实现
animal.makeSound();
}
}
//...
AnimalSound animalSound = new AnimalSound();
animalSound.makeSound(duck); // 嘎嘎噶
animalSound.makeSound(chicken); // 咯咯咯
如果我们想让对象duck和对象chicken都拥有这样的makeSound方法,就必须通过多态来实现,这让我们通过向上转型来绕过强类型语言的类型检查,如果makeSound一开始指定了调用方法的类型,那么就无法让鸭子对象和鸡对象都使用这个方法。多态的实现是Java众多设计模式的目标,多态的思想实际上就是把做什么和谁去做分离开。而js的变量类型在运行期是可变的,一个js对象可以随意使用从父类继承来的方法,运行时的this指向就是当前的对象。
多态在面向对象中的作用
多态是面向对象设计中最重要的技术,多态的最基本好处在于,你不必向对象询问它是什么类型,只需要让对象使用方法就可以了。多态的根本作用是将过程化的条件分支语句转化成对象的多态性。
想象刚才的问题,如果我们使用面向过程的思路会是什么样呢。对于一个对象,我们要先判断它是鸡还是鸭,然后决定它怎么叫。如果只有鸡和鸭还好,如果类型多了要有多少个判断?
再通俗一点,我们每个人吃饭的方式不同,如果我们想让大家一起开始吃饭,是要依次调用每个人的方法,还是用一个统一的开饭方法,把对象传入,大家自动去吃饭呢?
js中的多态
这个直接上代码
function Animal(){
}
Animal.prototype.makeSound = function(){
console.log('我是一只动物');
}
function Duck(){ }
function Chicken(){ }
Duck.prototype = new Animal();
Duck.prototype.makeSound = function(){
console.log('咯咯咯');
}
Chicken.prototype = new Animal();
Chicken.prototype.makeSound = function(){
console.log('嘎嘎噶');
}
var animal = new Animal();
var duck = new Duck();
var chicken = new Chicken();
function AnimalSound(obj){
obj.makeSound();
}
function AnimalSound(){
}
AnimalSound.prototype.makeSound = function(obj){
//这里省略对obj的判断
obj.makeSound();
}
var animalSound = new AnimalSound();
animalSound.makeSound(duck); // 嘎嘎噶
animalSound.makeSound(chicken); // 咯咯咯
当然这里体现的是js对象的灵活性,只要对象中有这个makeSound方法,就可以传入animalSound对象的方法中。