JavaScript面向对象轻松入门之多态(demo by ES5、ES6、TypeScript)
多态(Polymorphism)按字面的意思就是“多种状态”,同样的行为(方法)在不同对象上有不同的状态。
在OOP中很多地方都要用到多态的特性,比如同样是点击鼠标右键,点击快捷方式、点击桌面空白处、点击任务栏等弹出的菜单都是不同的。
方法重写(override):
即子类定义一个与父类名字相同的方法,以此覆盖父类方法,以此来实现不同的功能。
function Animal(){}
var AnimalP = Animal.prototype;
AnimalP.eat = function(food){
console.log('这个动物正在吃' + food);
};
function Snake(){}
var SnakeP = extend(Snake,Animal);//extend函数请看上一节
/*snake没有对eat方法重写,继承的父类eat()方法*/
function Dog(){}
var DogP = extend(Dog,Animal);
DogP.eat = function(food){
/*对eat()方法重写*/
/*上一章讲过,也可以在这里通过 Animal.eat.call(this,food)调用父方法;*/
console.log("这只狗正在吃"+food);
};
function Cat(){}
var CatP = extend(Cat,Animal);
CatP.eat = function(food){
console.log("这只猫正在吃"+food);
};
var snake = new Snake();
snake.eat('老鼠');//log:这个动物正在吃老鼠
var dog = new Dog();
dog.eat('骨头');//log:这只狗正在吃骨头
var cat = new Cat();
cat.eat('鱼');//log:这只猫正在吃鱼
抽象类(abstract class):
上面的代码中,Snake类没有实现自己的eat()方法,但有的时候我们希望子类一定要有某个方法(抽象方法),这样可以规范子类的行为,这时候就要用到抽象类,
ES5、ES6都没有抽象类的概念的,所以我们只能通过模拟来实现,让我们接着上面的代码,假如我们要把Animal的eat()方法定义为抽象方法:
AnimalP.eat = function(food){
/*定义抽象方法(虚函数),如果子类没有重写这个方法,在执行这方法的时候就会抛出错误*/
throw '"' + this.constructor.name + "'类没有eat()方法";
};
function Snake(){}
var SnakeP = extend(Snake,Animal);
var snake = new Snake();
snake.eat('老鼠');//throw:"Snake'类没有eat()方法
方法重载(overload):
我们一定写过这样的函数,根据传入的参数不一样(类型、参数个数),方法的运行结果也不一样:
var run = function(speed){
if(typeof speed == 'number'){
console.log('跑的速度有' + speed + 'm/s');
}else if(typeof speed == 'string'){
console.log('跑的速度有' + speed);
}
}
run(15);//log:跑的速度有15m/s
run('20KM/h');//log:跑的速度有20KM/h
但上面这样写明显代码难维护,可以把run方法作为一个接口,根据参数的类型执行不同方法,用在类中就向下面一样:
function Dog(){}
var DogP = Dog.prototype;
DogP.run = function(speed){
if(typeof speed == 'number'){
this._runNumber(speed);
}else if(typeof speed == 'string'){
this._runString(speed);
}else{
throw '参数不匹配';
}
}
DogP._runString = function(speed){
console.log('这只狗跑的速度有' + speed);
}
DogP._runNumber = function(speed){
console.log('这只狗跑的速度有' + speed + 'm/s');
}
var dog = new Dog();
dog.run(15);//log:这只狗跑的速度有15m/s
dog.run('20KM/h');//log:这只狗跑的速度有20KM/h
dog.run([]);//throw:参数不匹配
这就是方法重载的模拟,但实际上,ES5、ES6、typescipt都不支持语法上的方法重载,typescipt也只是支持函数重载。
这是多态的另一种实现方式。
Demo by ES6:
class Animal{
eat(food){
throw '"' + this.constructor.name + "'类没有eat()方法";
}
}
class Snake extends Animal{}
class Dog extends Animal{
eat(food){
console.log("这只狗正在吃"+food);
}
}
class Cat extends Animal{
eat(food){
console.log("这只猫正在吃"+food);
}
}
let snake = new Snake();
snake.eat('老鼠');//throw:"Snake'类没有eat()方法
let dog = new Dog();
dog.eat('骨头');//log:这只狗正在吃骨头
let cat = new Cat();
cat.eat('鱼');//log:这只猫正在吃鱼
Demo by TypeScript:
abstract class Animal{//定义抽象类Animal
constructor(){}
abstract eat(food: string){}
/*定义抽象方法eat(),并且限定传入的参数类型是string,
还可以定义返回值,接口等,如果子类不符合限定的规范,编译的时候就会报错。
*/
}
class Snake extends Animal{}//报错,无法通过编译,因为没有定义eat()抽象方法
class Dog extends Animal{
eat(food: string){
console.log("这只狗正在吃"+food);
}
}
class Cat extends Animal{
eat(food: string){
console.log("这只猫正在吃"+food);
}
}
let dog = new Dog();
dog.eat('骨头');//log:这只狗正在吃骨头
let cat = new Cat();
cat.eat('鱼');//log:这只猫正在吃鱼
后话
如果你喜欢作者的文章,记得收藏,你的点赞是对作者最大的鼓励;
面向对象的主要知识点在这里就讲完了,这些东西仅仅是基础,我讲的肯定不够完善,仅仅是为了让大家快速入门,建议大家有时间的话还是系统的看书学习一下js OOP;
本系列还有最后一章,会把前几张讲的知识点通过一个案例整合在一起,让大家可以更好的消化吸收,大概会酝酿两周的时间;
大家有什么疑问可以留言或私信作者,作者尽量第一时间回复大家;
如果老司机们觉得那里可以有不恰当的,或可以表达的更好的,欢迎指出来,我会尽快修正、完善。
JavaScript面向对象轻松入门之多态(demo by ES5、ES6、TypeScript)的更多相关文章
- JavaScript面向对象轻松入门之封装(demo by ES5、ES6、TypeScript)
本章默认大家已经看过作者的前一篇文章 <JavaScript面向对象轻松入门之抽象> 为什么要封装? 封装(Encapsulation)就是把对象的内部属性和方法隐藏起来,外部代码访问该对 ...
- JavaScript面向对象轻松入门之概述(demo by ES5、ES6、TypeScript)
写在前面的话 这是一个JavaScript面向对象系列的文章,本篇文章主要讲概述,介绍面向对象,后面计划还会有5篇文章,讲抽象.封装.继承.多态,最后再来一个综合. 说实话,写JavaScript面向 ...
- JavaScript面向对象轻松入门之继承(demo by ES5、ES6)
继承是面向对象很重要的一个概念,分为接口继承和实现继承,接口继承即为继承某个对象的方法,实现继承即为继承某个对象的属性.JavvaScript通过原型链来实现接口继承.call()或apply()来实 ...
- JavaScript面向对象轻松入门之抽象(demo by ES5、ES6、TypeScript)
抽象的概念 狭义的抽象,也就是代码里的抽象,就是把一些相关联的业务逻辑分离成属性和方法(行为),这些属性和方法就可以构成一个对象. 这种抽象是为了把难以理解的代码归纳成与现实世界关联的概念,比如小狗这 ...
- JavaScript面向对象轻松入门之综合
javascrpit面向对象之综合 这一章是对前几章的一个总结,通过一个案例来综合认识javascript面向对象的基本用法 需求: 几乎所有的web应用都需要保存数据一些到本地,那么我们就来 ...
- javascript面向对象:继承、多态
继承 js中同样可以实现类的继承这一面向对象特性,继承父类中的所有成员(变量和属性),同时可扩展自己的成员,下面介绍几种js中实现继承的方式: 1,对象模仿:通过动态的改变 this 指针的指向,实现 ...
- JavaScript面向对象编程入门
来源极客网 function Person() { var _this = {} //创建一个空的对象,接着我们利用这个"空的对象"承载Person的属性和方法 _this.say ...
- JavaScript 面向对象程序设计(下)——继承与多态 【转】
JavaScript 面向对象程序设计(下)--继承与多态 前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员.公有实例成员.私有静态成员.公有静态成员和静态类的封装.这次我们来讨论 ...
- Swift轻松入门——基本语法介绍和详细地Demo讲解(利用WebView打开百度、新浪等网页)
转载请务必注明出处(all copyright reserved by iOSGeek) 本文主要分为两个部分,第一部分介绍Swift的基本语法,第二部分讲解一个利用WebView来打开百度.sina ...
随机推荐
- Go - Struct
定义 go 语言中的struct与c的很相似,此外,go没有Class,也没有继承. stuct的格式为:type <name> struct{} package main import ...
- Day4-软件目录开发规范
层次清晰的目录结构:1. 可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等.从而非常快速的了解这个项目.2. 可维护性高: 定义好 ...
- 关于ubuntu的图标创建以及快捷方式打开
//这里个人要添加的的为微信小程序开发工具 1:终端命令: sudo gedit /usr/share/applications/MyChat.desktop 2:修改启动器配置如下: [Deskto ...
- Maven学习(三)
maven相关概念 maven坐标 Maven世界拥有大量构建,当我们需要引用依赖包是,需要用一个用来唯一标识去确定唯一的一个构建.如果拥有了统一规范,就可以把查找工作交给机器. 类似于空间找点的坐标 ...
- XD
题目 是否完成 题目分类 简要题解 没有上司的舞会(codevs1380) Y 树形dp dp[u][0]表示不包含此节点,dp[u][1]表示包含,转移方程为 dp[u][0]+=max(dp[v] ...
- SonarQube+Jenkins,搭建持续交付平台
前言 Kurt Bittner曾说过,如果敏捷仅仅只是开始,那持续交付就是头条! "If Agile Was the Opening Act, Continuous Delivery is ...
- Cohort Analysis and LifeCycle Grids mixed segmentation with R(转)
This is the third post about LifeCycle Grids. You can find the first post about the sense of LifeCyc ...
- 【Netty】WebSocket
一.前言 前面学习了codec和ChannelHandler之间的关系,接着学习WebSocket. 二.WebSocket 2.1. WebSocket介绍 WebSocket协议允许客户端和服务器 ...
- Redis 小白指南(三)- 事务、过期、消息通知、管道和优化内存空间
Redis 小白指南(三)- 事务.过期.消息通知.管道和优化内存空间 简介 <Redis 小白指南(一)- 简介.安装.GUI 和 C# 驱动介绍> 讲的是 Redis 的介绍,以及如何 ...
- Yii2项目实现Markdown功能 在线Markdown编辑器
版权声明:本文为博主原创文章,欢迎扩散,扩散请务必注明出处. Yii中添加MarkDown编辑器 主要使用了两个网页Markdown编辑器,都带预览功能. 1,ijackua/yii2-lepture ...