一. 前言
我们知道面向对象的三个特性是:封装,继承,多态。
- 
封装:对外隐藏类的属性和实现细节(如private,protect属性),对外提供公共接口来提供属性读取和修改行为(如c++,java语言中的set构造器,get构造器函数等),以及只对外暴露需要公开的属性和方法。
 - 
继承:子类拥有基类的行为和属性,并可以在以上扩展。例如:人类生物学的遗传。
 - 
多态:同一种方法不同对象之间的响应,即同一个操作作用于不同的对象上,可以产生不同的解释和不同的执行结果。例如:我们右键打开任何一个文件,调用打开方法,MP4调用后是视频播放器播放该视频,MP3是音乐播放器播放改音乐,图片打开的是图片预览程序。这就是多态。
 
在前两篇文章,我们的知识点几乎都在讲封装和继承两大特性,本章来讲讲JavaScript语言中多态的实现方式。
二. 基本思想
核心思想:通过一个函数,函数的形参是超类(顶级类)的引用,函数体直接调用该方法即可。
首先看以下java代码多态的实现:
    package juejinBlog;
// 超类: 文件
abstract class File {
	protected String name;
	// 构造函数
	File(String name) {
		this.name = name;
	}
	public abstract void open();
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
};
// 子类:视频文件
class Video extends File {
	// 构造函数
	Video(String name) {
		super(name);
	}
	@Override
	public void open() {
		System.out.println("打开了视频文件:"+this.name);
	}
}
// 子类:图片文件
class Image extends File {
	Image(String name) {
		super(name);
	}
	@Override
	public void open() {
		System.out.println("打开了图片文件:"+this.name);
	}
}
// 测试类
public class Polymorphism {
	// 核心方法,作用就是弱化类型,用一个抽象对象代替N种实现。
	public static void openFile(File file) {
		file.open();
	} 
        // 主函数
	public static void main(String[] args) {
		Video mp4 = new Video("企业宣传视频.mp4");
		Image img = new Image("图片1.png");
		System.out.println(mp4.getName());
		System.out.println(img.getName());
		openFile(mp4);
		openFile(img);
	}
}
运行结果如下:

三. JavaScript中的多态实现。
我们模拟java中核心方法的实现,看我们是否能完成多态,我们看以下代码。
超类:文件类
    // file.js
    class File {
  __name = "";
  constructor(name) {
    if (new.target === File) {
      throw new Error("抽象类不能被实例化");
    }
    this.__name = name;
  }
  setFileName(name) {
    this.__name = name;
  }
  getFileName() {
    return this.__name;
  }
  open() {}
}
export default File;
子类:视频类
  // video.js
  import File from "./file";
class Video extends File {
  constructor(name) {
    super(name);
  }
  open() {
    console.log(`打开了视频文件${this.__name}`);
  }
}
export default Video;
子类:图片类
//image.js
import File from "./file";
class Image extends File {
  constructor(name) {
    super(name);
  }
  open() {
    console.log(`打开了图片件${this.__name}`);
  }
}
export default Image;
测试文件:index.js
import Image from "./mutipleSector/image";
import Video from "./mutipleSector/video";
// 核心方法
function openFile(file) {
  file.open();
}
let mp4 = new Video("我的视频.mp4");
let image = new Image("我的图片.png");
console.log(mp4.getFileName());
console.log(image.getFileName());
openFile(mp4);
openFile(image);
运行结果:

不管你有多少子类,只要调用openFile(
四. 结论
多态其实是强类型结的果,对于强类型语言,如C++、C#、Java,通常采用抽象类或者接口,进行更高一层的【抽象】(本例中使用的File类)。
本质上是为了【弱化具体类型】(用一个【抽象】代替N种具体实现,java例中的openFile方法)。
如java例子中我们添加两行到main函数中:
    // 弱化具体类型
    File f1 = new Video("测试视频文件.avi");
    File f2 = new Image("测试图片文件.png");
    f1.open();
    f2.open();
运行结果如图:

我们发现js中其实多态的实现是非常容易的,即函数传参。其原因就是js语言的特性:本身就是弱类型性。
- 
多态其实是强类型结的果。
 - 
而对于JS这种本身就是【弱类型】的语言来说,多态是与生俱来的。。
 
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
 - 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
 
- 提示下载完但解压或打开不了?
 
- 找不到素材资源介绍文章里的示例图片?
 
- 模板不会安装或需要功能定制以及二次开发?
 
                    
    
发表评论
还没有评论,快来抢沙发吧!