💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
>[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 { // // ..... // } } } ~~~