background image

第 4

 

章 继承

继承在 JS 中是一个非常复杂的课题,其困难程度远远超过了其他 OO 语言。不像在其他 OO 语言中用一
个简单的关键字就可以继承一个类,JS 需要一系列的步骤来使公共成员得以继承。使问题变得进一步复
杂的是,JS 是少数使用原型来继承(稍后会它的优势)的语言之一。当然,由于 JS 的灵活性,你可以
选择使用标准的基于类的继承,或者稍微有些棘手的原型继承。
在本章中,我们来看下 JS 中创建子类的方法,以及适用它们的不同情况。

为什么要使用继承
在我们涉及任何代码之前,我们需要知道使用继承有什么好处。一般来讲,你希望你设计的类可以减少
大量重复的代码并且尽可能保持对象之间的松耦合。继承可以帮助你实现这两个概念中的第一个,并且
可以让你在现有的类的基础上补充它的方法。他也允许你很容易的修改。如果你有几个类都需要一个
toString 方法用特定方法来做结构输出,你需要拷贝并且粘贴方法给每一个类。但当你每次修改这个方
法时,你必需要为每个类修改。但如果你创建了一个 ToStringProvider 类,并且让这些类继承了它,那么
其方法的代码仅需修改一次。
让一个类继承另一个类有一种可能性,你使他们之间的耦合增强。就是说,一个类依靠内部实现了另外
一个类。我们来看下一些避免这种情况的方法,包括使用掺元类(mixin classes)来世像其他类提供方法。

标准继承
JS 可以像标准继承语言一样。通过使用函数声明类,并用 new 关键字来创建实例,对象的行为也和 Java
或 C++中的类非常类似。这实在 JS 中一个非常基本的类声明。

/* Class Person. */
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}

首先创建构造体,按照惯例,类名称要使用了一个大写字母开头。在构造体中,使用 this 关键字来创建
实例的属性。要创建方法,就把方法添加到类的 prototype 对象中,例如 Person.prototype.getName。要创建
实例,只需要用 new 关键字调用构造体函数即可。

var reader = new Person('John Smith');
reader.getName();

然后你就可以访问实例所有的属性和方法了,这是 JS 中非常简单的一类的例子

原型链
要创建一个类来继承 Person 就稍微有些复杂了:

/* Class Author. */
function Author(name, books) {
Person.call(this, name); // Call the superclass's constructor in the scope of this.
this.books = books; // Add an attribute to Author.
}
Author.prototype = new Person(); // Set up the prototype chain.
Author.prototype.constructor = Author; // Set the constructor attribute to Author.
Author.prototype.getBooks = function() { // Add amethod to Author.
return this.books;
};