[基础]JavaScript中的面向对象(个人学习笔记) 三
前面的两篇已经介绍了对象的定义和类的实现方法,现在开始学习面向对象中一个很重要的特性:继承。要用ECMAScript实现继承机制,首先从基类入手。所有开发者定义的类都可以作为基类,但出于安全原因的考虑,本地类和宿主类不作为基类,防止这些代码被恶意攻击。
虽然在ECMAScript中没有java中那样严格定义的抽象类,但有时也可以创建一些不允许访问的类,作为ECMAScript中的抽象类。子类可以像java中那样继承超类的所有属性和方法,包括构造函数及方法实现;子类也可以覆盖超类中的属性和方法,添加超类中没有的属性和方法。
实现继承的方式多种多样,就像定义一个类一样,开发者可以自由的选择,下面还是从实现继承的各种方式说起。
1、对象冒充
构造原始的ECMAScript时,根本没有打算设计对象冒充(object masquerading),它是在开发者理解函数的工作方式,尤其是如何在函数环境中使用this关键字后发展出来的。
其基本原理如下:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构构造函数方式)。因为构造函数只是一个函数,所以可以使Person的构造函数成为Student的方法,然后调用它。Student就会收到Person的构造函数中定义的属性和方法。例如:
function Person(sName){ this.name = sName; this.sayName = function(){ alert("name is " + this.name); }; } function Student(sName,sSubject){ this.newMethod = Person; this.newMethod(sName); delete this.newMethod; this.subject = sSubject; this.saySubject = function(){ alert("Subject is " + this.subject); }; } var s1 = new Student("yzl","computer science"); s1.sayName(); s1.saySubject();
function ClassZ(){ this.newMethod = ClassX; this.newMethod(); delete this.newMethod; this.newMethod = ClassY; this.newMethod(); delete this.newMethod; }
function sayInfo(sJob,sSex){ alert("My name is " + this.name + ", my job is " + sJob + ", sex is " + sSex); } var p1 = new Object; p1.name = "yzl"; sayInfo.call(p1,"J2EE Developer","male");// output: My name is yzl,my job is J2EE Developer,sex is male
function Person(sName){ this.name = sName; this.sayName = function(){ alert("name is " + this.name); }; } function Student(sName,sSubject){ //this.newMethod = Person; //this.newMethod(sName); //delete this.newMethod; [color=red]Person.call(this,sName);[/color] this.subject = sSubject; this.saySubject = function(){ alert("Subject is " + this.subject); }; } var s1 = new Student("yzl","computer science"); s1.sayName(); s1.saySubject();
function sayInfo(sJob,sSex){ alert("My name is " + this.name + ", my job is " + sJob + ", sex is " + sSex); } var p1 = new Object; p1.name = "yzl"; sayInfo.apply(p1,new Array("J2EE Developer","male")); // output: My name is yzl,my job is J2EE Developer,sex is male
function Person(sName){ this.name = sName; this.sayName = function(){ alert("name is " + this.name); }; } function Student(sName,sSubject){ //this.newMethod = Person; //this.newMethod(sName); //delete this.newMethod; //Person.call(this,sName); Person.apply(this.arguments); this.subject = sSubject; this.saySubject = function(){ alert("Subject is " + this.subject); }; } var s1 = new Student("yzl","computer science"); s1.sayName(); s1.saySubject();
function Person(){ } Person.prototype.name = "yzl"; Person.prototype.sayName = function(){ alert("name is " + this.name); }; function Student(){ } Student.prototype = new Person(); Student.prototype.subject = "computer science"; Student.prototype.saySubject = function(){ alert("Subject is " + this.subject); } var s1 = new Student(); s1.sayName(); s1.saySubject();
alert(s1 instanceof Person); alert(s1 instanceof Student);
function Person(sName){ this.name = sName; } Person.prototype.sayName = function(){ alert("name is " + this.name); }; function Student(sName,sSubject){ Person.call(this,sName); this.subject = sSubject; } Student.prototype = new Person(); Student.prototype.saySubject = function(){ alert("Subject is " + this.subject); } var s1 = new Student("yzl","computer science"); s1.sayName(); s1.saySubject();