多态:同一操做做用于不一样的对象上面,能够产生不一样的解释和不一样的执行结果。
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 Chicken()); // 咯咯咯
- 类型检查和多态:在静态类型语言中编译时会进行类型匹配检查,不能给变量赋予不一样类型的值因此须要向上转型(当给一个类变量赋值时,这个变量的类型既可使用这个类自己,也可使用这个类的超类)。
- 使用继承获得多态效果
- 继承一般包括实现继承和接口继承。
- 实现继承例子:
先建立一个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(); // (1)
Animal chicken = new Chicken(); // (2)
public class AnimalSound {
public void makeSound(Animal 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); // 输出咯咯咯
}
}
- JavaScript的多态
- 多态的思想其实是把“作什么”和“谁去作”分离开来。
- 在JavaScript 中,并不须要诸如向上转型之类的技术来取得多态的效果。
- 多态在面向对象程序设计中的做用
- 《重构:改善既有代码的设计》里写到:多态的最根本好处在于,你没必要再向对象询问“你是什么类型”然后根据获得的答案调用对象的某个行为——你只管调用该行为就是了,其余的一切多态机制都会为你安排稳当。
- 多态最根本的做用就是经过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句。
- 地图应用例子:
var googleMap = {
show: function () {
console.log('开始渲染谷歌地图');
}
};
var baiduMap = {
show: function () {
console.log('开始渲染百度地图');
}
};
var renderMap = function (map) {
if (map.show instanceof Function) {
map.show();
}
};
renderMap('google'); // 输出:开始渲染谷歌地图
renderMap('baidu'); // 输出:开始渲染百度地图
- 封装:封装的目的是将信息隐藏
- 封装数据:JavaScript 并无提供对这些关键字的支持,咱们只能依赖变量的做用域来实现封装特性,并且只能模拟出public 和private 这两种封装性。例子:
var myObject = (function () {
var __name = 'sven'; // 私有(private)变量
return {
getName: function () { // 公开(public)方法
return __name;
}
}
})();
console.log(myObject.getName()); // 输出:sven
console.log(myObject.__name) // 输出:undefined
- 封装类型:封装类型是经过抽象类和接口来进行的。把对象的真正类型隐藏在抽象类或者接口以后,JavaScript 中,并无对抽象类和接口的支持。
- 封装变化:封装在更重要的层面体现为封装变化,《设计模式》一书曾提到以下文字,“考虑你的设计中哪些地方可能变化,这种方式与关注会致使从新设计的缘由相反。它不是考虑何时会迫使你的设计改变,而是考虑你怎样才可以在不从新设计的状况下进行改变。这里的关键在于封装发生变化的概念,这是许多设计模式的主题。”
- 原型模式和基于原型继承的JavaScript对象系统:JavaScript 也一样遵照这些原型编程的基本规则
- 全部的数据都是对象
- 基本类型包括undefined、number、boolean、string、function、object。
- JavaScript 中的根对象是Object.prototype 对象,Object.prototype 对象是一个空的对象。
- 要获得一个对象,不是经过实例化类,而是找到一个对象做为原型并克隆它。