Java继承
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我们将向你展示JavaScript 如何实现面向对象的语言中的: 继承. 同时, 这些例子将向你展示如何实现类的封装. 在此, 我们不会讨论多态实现.
虽然JavaScript 是脚本语言, 但它所支持的面向对象编程也是非常强大的. 虽然它没有类和实例, 但它有对象, 原型和隐式的继承. 我们将会解释如何模拟继承及其超类与子类之间关系的形式. 原型是理解继承概念的关键, 我们将会教你如何建立原型, 如何检测一个对象是否是另外一个对象的原型, 及其JavaScript 的模型与Java 面向对象编程之间的区别. 我们同样会向你展示如何检测对象所包含的各种属性的方法. 在另外一篇文章里, 我还会详细地讲解有关"原型链(prototype chain)" 的知识.
本文大量地参考了 中"Object-Oriented Programming with JavaScript, Part I: Inheritance" 的内容, 许多内容我进行了详细的测试和再探讨, 以保证内容不会有太大的失误.
原文地址: /js/column79/
面向对象语言的特点
面向对象设计是基于以下 3 个主要原理的: 封装, 继承和多态. 说某种程序语言是支持OO (面向对象) 设计的, 只有在它的语法中支持以上 3 个概念才可以这么说. 这种语言应该为你提供某些方法, 以使你能很轻松地定义和使用这些范例. 封装涉及到了将某个对象变成一个"黑盒子"的概念. 当你使用某个对象时, 你不用知道它内部是如何工作的, 你也不必理解对象是如何工作的. 这个对象只需将它绝对有用的信息以接口方式提供出来. 此对象应该给你提供友好的接口, 来让你可以使用其有限的属性集和方法集. 封装还有一层意思, 那就是说某个对象包含了它需要的每一样东西, 这包括数据和对于它的操作. 封装的概念非常的强大, 因为它允许将一个大的软件项目有效地分配给每个开发人员, 对于团队中的每个人, 他们只需要关注自己所实现的对象, 而不需要太多地关注于别人的实现. 开发项目中的开销使得开发团队中成员与接口的数量按指数级别增长. 封装是自"软件危机" 以来最受欢迎的OO 设计理念.
软件的复用是OO 设计思想中另外一个重要的特点. 在软件体系中实现此思想的主要方法就是继承. 类就是定义对象的功能. 超类是某个新类, 或者说是子类被建立的来源类. 一个子类从它的超类中继承了所的方法和属性. 实际上, 所有的子类都是被自动地生成的, 因此节省了大量的工作. 你不需要一个一个地定义这些子类. 当然, 你可以重载那些继承下来的方法和属性. 事实上, 谁也没有指出哪个子类要建立得和其超类一模一样, 除非你没有重载任何的属性和方法.
多态可能是这个 3 个概念中最复杂的一个了. 其本质上是说, 每个对象都可以处理各种不同的数据类型. 你不必为处理不同的数据类型而建立不同的类. 其典型的例子就是画图的类, 你不必为实现画圆, 画矩形, 画椭圆而编写不同的类. 你可以建立一个足够聪明的类来调用特定的方法来操作特定的形状.
通过函数实现继承
虽然JavaScript 不支持显示继承操作符, 但你可以通过其实方式实现隐式继承. 对于实
现类的继承, 有 2 种比较常用的方式. 第一种将某个类定义成子类的方法是, 通过在负责定义子类函数的内部调用超类的构造函数. 看下面的示例:
// 超类构造函数
function superClass() {
this.bye = superBye;
this.hello = superHello;
}
// 子类构造函数
function subClass() {
this.inheritFrom = superClass;
this.inheritFrom();
this.bye = subBye;
}
function superHello() {
return "Hello from superClass";
}
function superBye() {
return "Bye from superClass";
}
function subBye() {
return "Bye from subClass";
}
// 测试构造特性的函数
function printSub() {
var newClass = new subClas
欢迎光临学网,收藏本篇文章[1] [2] [3] [4] [5] [6] [7] [8]
$False$
s();
alert(newClass.bye());
alert(newClass.hello());
}
当你运行上面的printSub 函数时, 它会依次执行subBuy 和superHello 函数. 我们可以看到, bye 和hello 方法最先在superClass 中被定义了. 然而, 在subClass 中, bye 方法又被重载了, subClass 构造函数头两行的功能只是做了一个简单的原始的继承操作, 但它是
通过显示执行inheritFrom 方法来完成的继承操作. 继承的过程先是将superClass 的对象原型赋给subClass 下的inheritFrom 方法, 然后在执行完superClass 的构造函数后, superClass 的属性就被自动地加到了subClass 的属性列表中.这主要是由于在subClass 中通过this 来调用的inheritFrom (也就是superClass) 构造函数造成的, 通过此种方式调用superClass 构造函数时, JavaScript 解释器会把superClass 中的this 与subClass 中的this 理解成位于同一个作用域下的this 关键字, 所以就产生了继承的效果.
另外, 需要说明的是, 对于任何一个实例化的对象, 你任意地为它添加属性或方法, 如下所示:
var newClass = new subClass();
newClass.addprop = "added property to instance object";
很明显, 通过此种方式添加的属性和方法只对当前实例化对象有效, 不会影响所有的同类型对象实例. 无疑, 它是你创造的一个独一无二的对象实例.
通过原型实现继承
第二种, 也是更强大的方法是通过建立一个超类对象, 然后将其赋值给子类对象的prototype 属性, 以此方式来建立子类的继承. 假设我们的超类是superClass, 子类是subClass. 其prototype 的赋值格式如下:
subClass.prototype = new superClass;
对于原型继承的实现方式, 让我们刚前面的代码改写一下, 示例如下:
// 超类构造函数
function superClass() {
this.bye = superBye;
this.hello = superHello;
}
// 子类构造函数
function subClass() {
this.bye = subBye;
}
subClass.prototype = new superClass;
function superHello() {
return "Hello from superClass";
}
function superBye() {
return "Bye from superClass";