java设计模式多态_javascript设计模式与开发实践(一)- 多态

PS:上一篇文章发表之后,很多朋友关注了本人的思否和掘金的博客,虽然关注的朋友还有有限,但足够让我把自己在技术上的问题积累分享给大家,也希望大家能够喜欢,同时能动一动手指,给一颗心(赞),博主会持续更新下去

多态

本文是《javascript设计模式与开发实践》一书学习笔记,因书中所表述的概念简单明了,故将整本书的笔记奉上,全部文章大概在20篇左右,还请朋友们持续关注

动态语言类型

编程语言按照数据类型大体可以分为两类,一类是静态类型语言,另一类是动态类型语言

静态类型语言,声明任何变量或者形参都需要指定类型,例如java语言。

动态类型语言,声明任何变量或者形参都不需要指定类型,javascript就是动态类型语言。

所谓动态,可以多层面的理解,首先,声明变量不需要指定类型,其次,在多态思想下,java中需要利用父类实现多态,而javascript就不需要,本身自带多态属性。

多态

熟悉java的朋友知道,java三大特征之一就有多态,多态给java带来了很大的灵活性,很多设计模式也是通过多态来实现,java中的多态涉及到向上转型和向下转型,而javascript(以下简称js)的"多态"就相对来说容易实现

我们来看一段“多态”的js代码

var makeSound = function(an) {

if(an instanceof Duck) {

console.log("嘎嘎嘎");

} else if(an instanceof Dog) {

console.log("汪汪汪");

}

}

var Dog = function(){};

var Duck = function(){};

makeSound(new Dog());

makeSound(new Duck());

这段代码确实体现了“多态性”,当我们分别向鸭和鸡发出“叫唤”的消息时,它们根据此 消息作出了各自不同的反应,但是这样写会有一个弊端,当更多的类型出现时,我们要不断的修改makeSound函数,后期makeSound函数也会变得十分巨大,这不符合良好代码设计的规范,多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事 物”与 “可能改变的事物”分离开来。在这个故事中,动物都会叫,这是不变的,但是不同类 型的动物具体怎么叫是可变的。把不变的部分隔离出来,把可变的部分封装起来,这给予了我们 扩展程序的能力,程序看起来是可生长的,也是符合开放—封闭原则的,相对于修改代码来说, 仅仅增加代码就能完成同样的功能,这显然优雅和安全得多

首先,我们把makeSound函数修改一下:

var makeSound = function(an) {

an.speak();

}

这段代码传入一个对象,然后调用对象的speak函数

var Duck = function(){}

Duck.prototype.sound = function(){

console.log( '嘎嘎嘎' );

};

var Chicken = function(){}

Chicken.prototype.sound = function(){

console.log( '咯咯咯' );

};

makeSound( new Duck() ); // 嘎嘎嘎

makeSound( new Chicken() );

现在我们向鸭和鸡都发出“叫唤”的消息,它们接到消息后分别作出了不同的反应。如果有 一天动物世界里又增加了一只狗,这时候只要简单地追加一些代码就可以了,而不用改动以前的 makeSound 函数

类型检查和多态

现在,我们来进一步了解多态,之前说到,java的多态需要利用继承来实现,我们现在把动物的例子换成java代码

public class Duck {

public void speak(){

System.out.println( "嘎嘎嘎" );

}

}

public class Dog {

public void speak(){

System.out.println( "汪汪汪" );

}

}

public class AnimalSpeak{

public void makeSound(Duck duck){

duck.speak();

}

}

public static void main(String args[]){

AnimalSpeak an = new AnimalSpeak();

Duck duck = new Duck();

an.makeSound(duck); // 输出:嘎嘎嘎

}

现在鸭子已经顺利叫出来了,但是我们想让狗也叫,发现不太容易实现,因为makeSound函数中,形参是Duck类型,传入Dog类型一定会报错,这个时候继承就出现了,java设计思路是我先创建一个父类,具体传入的类型由子类决定,但是makeSound函数中的形参确是父类类型,实现如下:

public abstract class Animal{

abstract void speak(); // 抽象方法

}

public class Duck extends Animal {

public void speak(){ // 覆写父类中的抽象方法

System.out.println( "嘎嘎嘎" );

}

}

public class Dog extends Animal {

public void speak(){ // 覆写父类中的抽象方法

System.out.println( "汪汪汪" );

}

}

public class AnimalSpeak{

public void makeSound(Animal an){

an.speak();

}

}

public static void main(String args[]){

AnimalSpeak an = new AnimalSpeak();

Animal duck = new Duck();

Animal dog = new Dog();

an.makeSound(duck); // 输出:嘎嘎嘎

an.makeSound(dog); // 输出:汪汪汪

}

js中的多态

JavaScript 对象的多态性是与生俱来的,为什么这么说? 仔细看看这两个函数:

public void makeSound(Animal an){

an.speak();

}

function(an) {

an.speak();

}

js和java中的函数的形参是不同的,java定死了传入的类型,而js是动态的,js随便可以传入任何类型,所以,我们之前说js是动态类型语言,在 JavaScript 这种将函数作为一等对象的语言中,函数本身也是对象,函数用来封装行为并 且能够被四处传递。当我们对一些函数发出“调用”的消息时,这些函数会返回不同的执行结 果,这是“多态性”的一种体现,也是很多设计模式在 JavaScript 中可以用高阶函数来代替实现的原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值