>[danger] ##### 语言类型分类
[编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别](https://www.cnblogs.com/zy1987/p/3784753.html?utm_source=tuicool)
[Python是解释型的强类型动态语言](https://zhuanlan.zhihu.com/p/113408690)
>[success] # 鸭子类型 -- 动态类型语言
* **起源**:意大利软件工程师、Python软件基金会研究员`Alex Martelli` 于2000年`python`的邮件组中最早将这个概念引入了程序设计范畴中
* **概念来源**:`Duck typing` 这个概念来源于美国印第安纳州的诗人**詹姆斯·惠特科姆·莱利(James Whitcomb Riley,1849-1916)** 的诗句:` When I see a bird that walks like a duck and swims like a duck and quacks
like a duck, I call that bird a duck.`**中文意思** `当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子`
* **鸭子类型是动态类型语言才具备的**(运行时才进行数据类型检查 即在变量赋值时,才确定变量的数据类型,不用事先给变量指定数据类型 ),例如 `js` `python`
* **鸭子类型** `只关心对象的行为,不关心对象本身`
>[info] ## 鸭子案例
`《 javasprict 设计模式与开发实践 》`书中有个例子,`js` 王国的国王觉得鸭子叫声很美妙,他要组织一个大型的鸭子合唱团,一共需要`1000`只鸭子,但是最后全国只找到了`999`只,但还差一只,怎么办?就在这个时候发现一只鸡叫起来和鸭子一样,这只鸡就成了第`1000`个合唱团的成员
*****
根据鸭子类型去解释上面的例子,**鸭子和鸡就是编程时候的实例对象**
,我们**不关心**你是鸭子对象还是鸡对象,**只关心**你能不能像鸭子一样叫,这个叫就是`行为`
>[danger] ##### 案例
1. 像下面的代码案例,以后不管你是鸡鸭鱼还是其他动物,只要你会鸭子叫就能加入合唱团,我们只需要吧这类实例放到`joinChoir`方法中
~~~
// 鸭子
const duck = {
duckSing:function () {
console.log('嘎嘎嘎')
}
}
// 会鸭子叫的鸡
const chicken = {
duckSing:function () {
console.log('嘎嘎嘎')
}
}
const choir = [] // 合唱团
function joinChoir(animal) {
// 只关心你的行为 是能发出鸭子叫
if(animal && typeof animal.duckSing === 'function'){
choir.push(animal)
}
}
joinChoir(duck)
joinChoir(chicken)
console.log(choir) // 鸭子
~~~
>[success] # 多态 -- 静态类型语言
* **多态解释**:从多态的英文`prolymorphism`,也就是`poly(复数) + morph(形态)`,字面意思复数形态,概念上说**多态主要指** 同一种事物表现出来的多种形态,当**同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果**
* **多态常见静态类型语言**,例如接口的多种不同的实现方式即为多态,继承重写重载都体现了多态
* **多态的实际意义**在于屏蔽不同子类的差异性实现通用的编程带来不同的效果
>[info] ## 多态的案例
`java `王国的国王觉得鸭子叫声很美妙,他要组织一个大型的鸭子合唱团,一共需要1000只鸭子,但是最后全国只找到了999只,但还差一只,怎么办?就在这个时候发现一只鸡叫起来和鸭子一样,这只鸡就成了第1000个合唱团的成员
>[danger] ##### 案例
* 创建父类`Animal `
~~~
public class Animal {
public void sing() {
System.out.print('唱');
}
}
~~~
* 创建`Chicken`
~~~
class Chicken extends Animal {
public void sing() {
System.out.print('唱');
}
}
~~~
* 创建 `Duck`
~~~
class Duck extends Animal {
public void sing() {
System.out.print('唱');
}
}
~~~
* **没有用多态**,但由于类型检查`AnimalSound`类中的`makeSound`只接受`Duck`类型的导致当我们用`Chicken`的实例当成参数的时候报错
~~~
public class AnimalSound {
public void makeSound( Duck duck ){ // (1)
duck.sing();
}
}
public class Test {
public static void main( String args[] ){
AnimalSound animalSound = new AnimalSound();
Duck duck = new Duck();
animalSound.makeSound( duck ); // 输出:嘎嘎嘎
}
}
~~~
* **使用多态**,有一个特点就是可以向上转型
~~~
public class AnimalSound {
public void makeSound( Animal animal ){
animal.sing();
}
}
~~~
>[info] ## 多态和鸭子区别
**多态**指的一类事物有多种形态,比如动物有多种形态:猫、狗、猪,像这里'猫、狗、猪'往上看都是动物,**鸭子**类型只要你像你就是我们需要的因此汽车叫的像鸭子,他也是鸭子他和鸭子没有任何关联只是单纯像
>[info] ## 有了多态和鸭子类型
用书中的话来说,**将过程化的条件分支语句转换为对象的多态性,从而消除这些条件语句**,像上面的案例我们从if判断是那个类,在决定发出什么声音,到后来真正的多态,我们不关心你是谁怎么叫,只要你能叫,发出指令你执行就可以
>[danger] ##### js 案例
书中给的场景:需要编写地图应用一开始选择谷歌地图,后来因为需求部分需要百度地图,就可以利用多态的形式
~~~
const googleMap = {
show: function () {
console.log('开始渲染谷歌地图');
}
};
const baiduMap = {
show: function () {
console.log('开始渲染百度地图');
}
};
const renderMap = function (map) {
if (map.show instanceof Function) {
map.show();
}
};
renderMap(googleMap); // 输出:开始渲染谷歌地图
renderMap(baiduMap); // 输出:开始渲染百度地图
// 错误使用多态(过多的if判断)
const renderMap = function (type) {
if (type=== 'google') {
googleMap.show()
}else if(type === 'baidu'){
baidu.show()
}
}
~~~
>[danger] ##### java 案例
* 父类
~~~
public abstract class Map {
public abstract void show();
}
~~~
* 子类
~~~
class BaiDuMap extends Map {
public void show() {
System.out.print('唱');
}
}
~~~
* 子类
~~~
class GoogleMap extends Map {
public void show() {
System.out.print('唱');
}
}
~~~
* 使用
~~~
public class App {
public void useMap(Map map) {
map.show();
}
// 否则要做两个方法 判断具体用那个对象
public void useBMap(BaiDuMap bM) {
new BaiDuMap().show();
}
// 否则要做两个方法 判断具体用那个对象
public void useGMap(BaiDuMap bM) {
new GoogleMap().show();
}
public static void main(String[] args) throws Exception {
BaiDuMap b = new BaiDuMap();
GoogleMap g = new GoogleMap();
App app = new App();
app.useMap(g);
app.useMap(b);
// 根据 实例判断
// Map m = b;
// if (m instanceof BaiDuMap) {
// // .....
// } else {
// // .....
// }
}
}
~~~