惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
爱范儿
爱范儿
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
雷峰网
雷峰网
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
有赞技术团队
有赞技术团队
美团技术团队
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Engineering at Meta
Engineering at Meta
T
Tailwind CSS Blog
J
Java Code Geeks
Martin Fowler
Martin Fowler
I
InfoQ
小众软件
小众软件
MongoDB | Blog
MongoDB | Blog

博客园 - 想那风霜雪

基于web的甘特图,易度甘特图edogantt! JavaScript异常处理 - 想那风霜雪 - 博客园 一个支持Drag页面拖动的组件 - 想那风霜雪 - 博客园 main Function和Object(2) Function和Object(1) - 想那风霜雪 - 博客园 Atlas系列:从AtlasRuntime.js开始-简介 Atlas源码阅读系列之一 9)使用面向对象思想处理cookie 8)事件设计模式 6)类的继承 5)使用for(...in...)实现反射机制 4)公有成员\私有成员和静态成员 - 想那风霜雪 - 博客园 3)类的实现 2)深入认识JavaScript中的函数 1)JavaScript面向对象的基础 JavaScript的OO特性:Singleton单件模式 JavaScript的OO特性:私有访问限制实现 JavaScript的OO特性:继承
7)实现抽象类
想那风霜雪 · 2006-08-16 · via 博客园 - 想那风霜雪

    1)抽象类和虚函数.
    虚函数类成员中的概念,是只做了一个声明而未实现的方法,具有虚函数的类就称为抽象类,这些虚函数在派生类中才被实现.
    抽像类是不能实例化的,因为其中的虚函数并不是一个完整的函数,不能被调用.所以抽象类只作为基类派生以后再使用.
    和类的继承一样,JavaScript并没有任何机制用于支持抽象类。但利用JavaScript语言本身的性质,可以实现自己的抽象类.
   
    2)在JavaScript实现抽象类
    在传统的面向对象语言中,抽象类中的虚方法必须先被声明,但可以在其方法中被调用.
    而在
JavaScript中,虚方法就可以看作该类中没有定义的方法,但已经通过this指针使用了.和传统面向对象不同的是,这里的虚方法不需经过声明,而直接使用了.这些方法将在派生类中实现,例如:

//定义一个抽象基类base,无构造函数
function base(){};
base.prototype 
= {
    initialize:
function(){
        
this.oninit(); //调用了一个虚方法
    }
}
//定义class1
function class1(){
    
//构造函数
}
//让class1继承于base,并实现其中的oninit方法
class1.prototype = (new base()).extend({
    oninit:
function(){//实现抽象基类中的oninit
    }
});

    这样,当在class1的实例中调用继承得到的initialize方法时,就会自动执行派生类中的oninit()方法.
    从这里也可以看到解释型语言执行的特点,它们只有在运行到某一方法调用时,才会检查该方法是否存在,而不会向编译型语言一样在编译阶段就检查方法存在与否.
    当然,如果希望在基类中添加虚方法的一个定义,也是可以的,只要在派生类中覆盖此方法即可.如下:

//定义一个抽象基类base,无构造函数
function base(){}
base.prototype
={
     initialize:
function(){
          
this.oninit(); //调用了一个虚方法
     },
     oninit:
function(){} //虚方法是一个空方法,由派生类实现
}


    3)使用抽象类的示例
    以prototype.js为例,其中定义了一个类的创建模型:

//Class是一个全局无类型对象,有一个方法create,用于返回一个类
var Class = {
    create:
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);

   

这是将argumnets数组作为一个参数传递给initialize方法,而apply方法则可以把arguments数组对象的元素作为一组参数传递过去,这是一种巧妙的实现.