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 ...
随机推荐
- 解决Windos7中优盘安装centos7后无法引导原系统问题
一前言 最近学习Linux操作系统,打算在原Window7系统中装centOS7系统,使笔记本上跑双系统.将系统D盘的文件转移后,删除卷标,将U盘做成CentOS7启动盘,进行正常安装.此为前提. 但 ...
- 项目Contact开发中遇到的,引以为戒
程序进去就闪退 其中指示错误的地方,函数内容如下: public void loadButtomMenu() { gv_buttom_menu = (GridView) this.findViewBy ...
- 第 8 章 MySQL 数据库 Query 的优化
前言: 在之前“影响 MySQL 应用系统性能的相关因素”一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 Query 语句的优化进行相应的分析. ...
- (入门篇 NettyNIO开发指南)第五章-分隔符和定长解码器使用
TCP 以流的方式进行数据传输上层的应用协议为了对消息进行区分,往往采用如下4种方式. (1)消息长度固定,累计读取到长度总和为定长LEN 的报文后,就认为读取到了一个完整的消息,将计数器置位, ...
- javaWeb学习总结(3)- Servlet总结(servlet的主要接口、类)
Servlet总结01——servlet的主要接口.类 (一)servlet类 Servlet主要类.接口的结构如下图所示: 要编写一个Servlet需要实现javax.servlet.Servlet ...
- 简单的用jQuery做遮罩效果
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...
- [原创]MongoDB_Sharding
Mongo Sharding:本示例搭建了三个副本集作为三个分片的sharding集群,其中master,slave,factershi三台同网段的内网主机.前期规划和原理分析省略,可根据具体配置推导 ...
- MySQL的复制
1.复制概述1.1.复制解决的问题数据复制技术有以下一些特点:(1) 数据分布(2) 负载平衡(load balancing)(3) 备份(4) 高可用性(high avail ...
- [Leetcode] Binary search--436. Find Right Interval
Given a set of intervals, for each of the interval i, check if there exists an interval j whose st ...
- Java中SimpleDateFormat用法详解
所有已实现的接口: Serializable, Cloneable SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类.它允许进行格式化(日期 -> 文本) ...