一:什么是js抽象类与虚方法

虚函数是类成员中的概念,是只做了一个声明而未实现的方法,具有虚函数的类就称之为抽象类,这些虚函数在派生类中才被实现。抽象类是不能实例化的,因为其中的虚函数并不是一个完整的函数,不能被调用。所以抽象类一般只作为基类被派生以后再使用。
和类的继承一样,JavaScript并没有任何机制用于支持抽象类。但利用JavaScript语言本身的性质,可以实现自己的抽象类。

二: 在JavaScript实现抽象类

在传统面向对象语言中,抽象类中的虚方法必须先被声明,但可以在其他方法中被调用。而在JavaScript中,虚方法就可以看作该类中没有定义的方法,但已经通过this指针使用了。和传统面向对象不同的是,这里虚方法不需经过声明,而直接使用了。这些方法将在派生类中实现,例如:
<script language="JavaScript" type="text/javascript">
<!--
//定义extend方法
Object.extend = function(destination, source) {
  for (property in source) {
    destination[property] = source[property];
  }
  return destination;
}
Object.prototype.extend = function(object) {
  return Object.extend.apply(this, [this, object]);
}
//定义一个抽象基类base,无构造函数
function base(){}
base.prototype={
      initialize:function(){
               this.oninit(); //调用了一个虚方法
      }
}
//定义class1
function class1(){
      //构造函数
}
//让class1继承于base并实现其中的oninit方法
class1.prototype=(new base()).extend({
      oninit:function(){ //实现抽象基类中的oninit虚方法
             //oninit函数的实现
      }
});
//-->
</script>
这样,当在class1的实例中调用继承得到的initialize方法时,就会自动执行派生类中的oninit()方法。从这里也可以看到解释型语言执行的特点,它们只有在运行到某一个方法调用时,才会检查该方法是否存在,而不会向编译型语言一样在编译阶段就检查方法存在与否。JavaScript中则避免了这个问题。当然,如果希望在基类中添加虚方法的一个定义,也是可以的,只要在派生类中覆盖此方法即可。例如:
//定义一个抽象基类base,无构造函数
function base(){}
base.prototype={
     initialize:function(){
          this.oninit(); //调用了一个虚方法
     },
     oninit:function(){} //虚方法是一个空方法,由派生类实现
}

代码:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <meta charset="utf-8"/>
  6. <script type="text/javascript" src="js/Core.js"></script>
  7. <script type="text/javascript">
  8. function Base(){
  9.  
  10. }
  11. Base.prototype={
  12. initialize:function(){
  13. this.oninit(); //调用了一个虚方法
  14. },
  15. oninit:function(){
  16. //留一个空的方法
  17. }
  18. }
  19.  
  20. function Class01(){
  21.  
  22. }
  23.  
  24. Class01.prototype=(new Base()).extend({
  25. oninit:function(){ //实现抽象基类中的oninit虚方法
  26. //oninit函数的实现
  27. console.log("init.....");
  28. }
  29. });
  30.  
  31. var class01 = new Class01();
  32. class01.initialize();
  33.  
  34. </script>
  35. </head>
  36. <body>
  37.  
  38. </body>
  39. </html>

三:使用抽象类的示例

仍然以prototype-1.6.1为例,其中定义了一个类的创建模型:
//Class是一个全局对象,有一个方法create,用于返回一个类
var Class = {
   create: function() {
     return function() {
       this.initialize.apply(this, arguments);
     }
   }
}
这里Class是一个全局对象,具有一个方法create,用于返回一个函数(类),从而声明一个类,可以用如下语法:
var class1=Class.create();
这样和函数的定义方式区分开来,使JavaScript语言能够更具备面向对象语言的特点。现在来看这个返回的函数(类):
function(){
      this.initialize.apply(this, arguments);
}
这个函数也是一个类的构造函数,当new这个类时便会得到执行。它调用了一个initialize方法,从名字来看,是类的构造函数。而从类的角度来看,它是一个虚方法,是未定义的。但这个虚方法的实现并不是在派生类中实现的,而是创建完一个类后,在prototype中定义的,例如prototype可以这样写:
var class1=Class.create();
class1.prototype={
      initialize:function(userName){
                      alert(“hello,”+userName);
      }
}
这样,每次创建类的实例时,initialize方法都会得到执行,从而实现了将类的构造函数和类成员一起定义的功能。其中,为了能够给构造函数传递参数,使用了这样的语句:
function(){
      this.initialize.apply(this, arguments);
}
实际上,这里的arguments是function()中所传进来的参数,也就是new class1(args)中传递进来的args,现在要把args传递给initialize,巧妙的使用了函数的apply方法,注意不能写成:
this.initialize(arguments);
这是将arguments数组作为一个参数传递给initialize方法,而apply方法则可以把arguments数组对象的元素作为一组参数传递过去,这是一种很巧妙的实现。
尽管这个例子在prototype-1.3.1中不是一个抽象类的概念,而是类的一种设计模式。但实际上可以把Class.create()返回的类看作所有类的共同基类,它在构造函数中调用了一个虚方法initialize,所有继承于它的类都必须实现这个方法,完成构造函数的功能。它们得以实现的本质就是对prototype的操作。

具体代码:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2. "http://www.w3.org/TR/html4/loose.dtd">
  3. <html>
  4. <head>
  5. <title></title>
  6. <script type="text/javascript" src="js/prototype-1.6.0.3.js"></script>
  7. <script type="text/javascript" src="js/Person.js"></script>
  8. <script type="text/javascript" src="js/Employee.js"></script>
  9. <script type="text/javascript">
  10. //创建一个类
  11. function getEmployeeInfo(){
  12. var employee = new Employee("sunliyuan","Miscofo");
  13. var info = employee.showInfo();
  14. alert(info);
  15. }
  16.  
  17. </script>
  18. </head>
  19. <body>
  20. <button onclick="getEmployeeInfo()">GetEmployeeInfo</button>
  21. </body>
  22. </html>

父类js:

  1. /**
  2. * Created by shizhiwei on 2016/9/11.
  3. */
  4. var Person = Class.create();
  5. Person.prototype={
  6. //必须给初始化值
  7. initialize: function(name) {
  8. this.personName=name;
  9. },
  10. showInfo:function(){
  11. alert(this.personName);
  12. }
  13. }

子类的js:

  1. /**
  2. * Created by shizhiwei on 2016/9/11.
  3. */
  4. var Employee = Class.create();
  5.  
  6. Employee.prototype = Object.extend(new Person(), {
  7. //定义一个抽象类
  8. initialize: function(name,corp) {
  9. this.personName=name;
  10. this.corpName=corp;
  11. },
  12. // corpName:"Micosoft",
  13. showInfo:function(){
  14. return this.personName+","+this.corpName;
  15. }
  16. });

JavaScript实现抽象类与虚方法(六)的更多相关文章

  1. c#多态之抽象类与虚方法的异同点~

    多态之抽象类与虚方法的相似点及不同点 : 不同点 1.方法关键字不一样 虚方法的方法关键字是:virtual. 抽象类的方法关键词是:abstract 2.基类的方法是否有方法体/实现 虚方法的方法: ...

  2. C#之类的继承、抽象类和虚方法

    代码下载地址 类的继承: 写电池的基类:包含条码和箱体码两个字段,含有两个参数的构造函数 class Battery { public string _barCode; public string _ ...

  3. 译:C#面向对象的基本概念 (Basic C# OOP Concept) 第三部分(多态,抽象类,虚方法,密封类,静态类,接口)

    9.多态 Ploy的意思就是多于一种形式.在文章开始,方法那一章节就已经接触到了多态.多个方法名称相同,而参数不同,这就是多态的一种. 方法重载和方法覆盖就是用在了多态.多态有2中类型,一种是编译时多 ...

  4. 抽象类和虚方法、base关键字

    微软官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract ...

  5. C#之抽象类、虚方法、重写、接口、密封类

    前言    学了这么长时间的C#,我想说对于这个东东还是不是特别了解它,以至于让我频频郁闷.每次敲代码的时候都没有一种随心所欲的感觉.所以不得不在网上搜集一些资料,look 了 look~ 内容   ...

  6. C#.NET里面抽象类,接口,虚方法

    1抽象类 (1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法 (2) 抽象类不能被实例化 (3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明 ...

  7. C#通过完整的例子,Get常用的2个套路,理解抽象方法,虚方法,接口,事件

    一.理解:抽象方法,虚方法,接口,事件 描述: 1.定义一个抽象父类"People": 要求: 1>3个属性:名字,性别,年龄: 2>一个普通方法"说话&qu ...

  8. C#-面向对象的三大特性——多态(虚方法与重写、抽象类、接口)

    多态 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果.在运行时,可以通过指向基类的指针,来调用实现派生类中的方法. 编译时的多态性:编译时的多态性是通过重载来实现的.对于非虚的成员来说 ...

  9. c#面向对象基础 重写、虚方法、抽象类

    虚方法 抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例 ...

随机推荐

  1. HTTP1.0、HTTP1.1和HTTP2.0的区别

    一.HTTP的历史 早在HTTP建立之初,主要就是为了将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器.也是说对于前端来说,我们所写的HTML页面将要放在我们的web服务器上,用户端 ...

  2. python 小爬虫爬取博客文章初体验

    最近学习 python 走火入魔,趁着热情继续初级体验一下下爬虫,以前用 java也写过,这里还是最初级的爬取html,都没有用html解析器,正则等...而且一直在循环效率肯定### 很低下 imp ...

  3. MySQL与宿主Linux之间交互式执行命令

    在MySQL里面执行Linux的命令并返回结果 system commands root@localhost 11:36:23> system cal March 2017 Su Mo Tu W ...

  4. HTML5的manifest 本地离线缓存

    下面直接放测试代码: index.html <!DOCTYPE html> <html manifest="m.manifest"> <head> ...

  5. Bootstrap的响应式后台管理模板推荐

    1.Admin LTE 该模版开源免费.已用到项目中,客户评价说UI很好看... AdminLTE - 是一个完全响应式管理模板.基于Bootstrap3的框架.高度可定制的,易于使用.支持很多的屏幕 ...

  6. java程序在windows后台执行的办法

    1.新建run.txt文件 2.在文件中输入一下内容: @echo off start javaw -jar xx.jar exit 3.保存,修改文件名为run.bat4.双击即可 5.删除wind ...

  7. Linux TCP 连接数

    查看 TCP 连接数 : 每一个 IP 访问的链接数:head 默认 前10 netstat -na|grep ESTABLISHED|awk '{print $5}'|awk -F: '{print ...

  8. 2017-2018-2 20155303『网络对抗技术』Exp7:网络欺诈防范

    2017-2018-2 『网络对抗技术』Exp7:网络欺诈防范 --------CONTENTS-------- 一.原理与实践说明 1.实践目标 2.实践内容概述 3.基础问题回答 二.实践过程记录 ...

  9. weblogic基本目录介绍,位数查看,启动与发布项目,修改JVM参数,设置项目为默认项目

    这里的基本目录%base%表示安装目录,如我的目录为:E:/weblogic就是%base% 1.weblogic目录介绍 weblogic主要的目录介绍: 1.日志目录: 每个domain(域)都有 ...

  10. C++ socket 传输不同类型数据的四种方式

    使用socket传输组织好的不同类型数据,有四种不同的方式(我知道的嘿嘿): a. 结构体 b. Json序列化 c. 类对象 d. protobuf 下面逐一整理一下,方便以后进行项目开发. 1. ...