js超类子类

转载 2018年04月16日 10:22:25
先引一段原文,可略过.. 
Java代码  收藏代码
  1. .....Object is the superclass of all the built-in classes, and all classes inherit a few basic methods from Object.  
  2. Recall that objects inherit properties from the prototype object of their constructor. How do they also inherit properties from the Object class? Remember that the prototype object is itself an object; it is created with the Object( ) constructor. This means the prototype object itself inherits properties from Object.prototype! Prototype-based inheritance is not limited to a single prototype object; instead, a chain of prototype objects is involved. Thus, a Complex object inherits properties from Complex.prototype and from Object.prototype. When you look up a property in a Complex object, the object itself is searched first. If the property is not found, the Complex.prototype object is searched next. Finally, if the property is not found in that object, the Object.prototype object is searched.  

    这段话前半部分描述了一个重要信息:prototype由构造函数Object()创建,所以它本身也是一个Object实例,而任何Object实例都可以从Object.prototype中继承属性;于是prototype就也具有了这种能力。 
  这就引出了另一个重要的信息:基于prototype的继承不仅仅局限于单一的prototype对象,访问沿着一条prototype链逐级向上执行:假设有个Complex实例,访问其中一属性,如果本身找不到,便访问Complex.prototype对象;还找不到即在Object实例中找不到,就接着访问Complex.prototype的上一级--Object.prototype。 
  这就解释了为什么JS对象都从Object对象中继承了方法:如自定义了Complex类,然后它的每个实例就都能访问toString()方法,因为它的prototype是Object实例,能访问Object.prototype。 
  这就是所谓“超类和子类”的核心。拿上例来说,它所表述的是,由于Complex.prototype默认是Object的实例(由Object()初始化),于是Complex便继承了Object(即可以访问Object和Object.prototype的所有属性)。 
    好戏登场了:只要把Complex.prototype的构造函数换成其他的,而不是默认的Object(),那Complex便成为了那个类的子类;这就实现了自己定义的超类和子类关系。当然Complex还是Object的子类,但那是因为那个类最终也是Object的子类。 
    举例说明(以Person和Man为例): 
Js代码  收藏代码
  1. function Person(name){this.name=name;}  
  2. Person.prototype.say=function(){alert("hello");}  
  3. function Man(){}  
  4. Man.prototype=new Person("Tom");  
  5. //------------  
  6. var man = new Man();  
  7. alert(man.name);//Tom,继承了Person实例的属性:name  
  8. man.say();//hello,继承了Person.prototype的属性:say  
  9. alert(man.hasOwnProperty('name'));//false,name在Man.prototype中  

完工了,Man已经成为了Person的子类。 
当然,这样写虽然能达到效果,但可能不符合“标准”,那就换成标准的: 
Js代码  收藏代码
  1. function Person(name){this.name=name;}  
  2. Person.prototype.say=function(){alert(this.hasOwnProperty('name'));}  
  3. function Man(name){  
  4.    Person.call(this,name);//多了这一步,实现实例属性的继承,要先明白call的作用  
  5. }  
  6. Man.prototype=new Person();//继承Person.prototype的属性。  
  7. //--------------  
  8. var man = new Man("Tom");  
  9. alert(man.constructor==Person);//true  
  10. Man.prototype.constructor=Man;//将Man的构造函数指回Man  
  11. alert(man.name);//Tom  
  12. alert(man.hasOwnProperty('name'));//true,通过call方法,name已经成为man的实例属性。hasOwnProperty判断man本身是否具有name属性。  
  13. man.say();//true,继承了Person.prototype的属性,this指向man  
  14. alert(Man.prototype.constructor==Person);//false  
  15. alert(Man.prototype instanceof Person);//true  


这就是“标准”的做法。当然也可以突发奇想,让Man只继承Person.prototype的属性,而不包括Person的实例属性。 
Java代码  收藏代码
  1. function Person(name){this.name=name;}  
  2. Person.prototype.say=function(){alert('hello');}  
  3. function Man(){}  
  4. Man.prototype=Person.prototype;  
  5. var man = new Man();  
  6. alert(man.name);//undefined,没有继承Person实例的属性  
  7. man.say();//hello,继承了Person.prototype的属性:say  
  8. alert(Man.prototype.constructor==Object);//true  
  9. alert(Man.prototype instanceof Object);//true  

总之,Man是谁的子类就看Man.prototype是由谁的构造函数初始化的。只要把握了这点,继承关系可以随心所欲的构造。 
但注意,试图通过把子类的prototype的constructor设为父类的构造函数是不行的。因为prototype并没有被父类的构造函数初始化,它还是由Object()初始化,只是它的constructor属性值改为父类了。 当子类实例访问"父类"prototype内的同名方法时,并不会到"父类"里查找,而是查找Object及Object.prototype。 
Js代码  收藏代码
  1. Man.prototype.constructor=Person;//这样达不到继承的目的  

另外说说call的作用(apply也一样): 
Java代码  收藏代码
  1. function Man(name){Person.call(this,name);}  

JS_JavaScript类_超类与子类_2011-08-25;

/**  * 奇谈怪论:JavaScript类_超类与子类_2011-08-25;  * 超类:  * Here is a simple Rectangle(矩形) class.It has a...
  • cenyebao
  • cenyebao
  • 2011-08-24 13:05:11
  • 961

JS中,子类调用超类函数

概述   JS虽然并不直接具备面向对象的特性,但仍可以通过prototype来模拟面向对象的继承和多态等特性。和大多数面向对象语言(例如C++,Java等)相比,JS来实现面向对象仍稍显繁琐和抽象,需...
  • mousebaby808
  • mousebaby808
  • 2014-07-06 23:39:51
  • 4859

超类和子类

Java新创建的类可以使用关键字extends继承一个已经存在的类,已经存在的类我们称之为超类,基类或父类;新创建的类我们称为子类、派生类或孩子类。看下面的基类Coder:public class C...
  • xzx4959
  • xzx4959
  • 2017-12-30 10:15:33
  • 98

超类与子类之间的关系

类的行为和属性分为两部分:自己的行为和属性以及从超类继承的行为和属性继承子类使用超类的方法和属性建立继承使用关键字extendsclass A extends B{ //behavior and at...
  • u010562436
  • u010562436
  • 2017-03-09 17:01:03
  • 1066

Java:子类调用超类方法的一种特殊情况

在Java的子类中,可以通过super来明确调用超类(也即父类)的方法。但当所调用的超类的方法(1)中又调用了其它的方法(2)时,由于Java默认动态绑定,所以方法(2)调用的是子类中的方法。如下,示...
  • lxymine
  • lxymine
  • 2014-05-05 10:02:56
  • 1658

Java学习笔记【继承之类、超类、子类】

1、继承关键字extends表示继承,表明正在构造的新类派生于一个存在的类。 class Manager extends Employee { .... }Jav...
  • y396397735
  • y396397735
  • 2015-09-25 08:41:16
  • 1246

超类对象引用变量引用子类对象

当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 (但是如果强制把超类转换成子类的话...
  • ryanemma
  • ryanemma
  • 2016-09-06 10:44:26
  • 460

Core Java (十一) Java 继承,类,超类和子类

继承关系 两个类之间存在三种关系: 依赖,uses-a,如果一个类的方法操纵另一个对象,我们就说一个类依赖于另一个类。聚合(关联),has-a,一个对象包含另外一个对象,聚合关系意味着类A...
  • xujinsmile
  • xujinsmile
  • 2013-01-22 17:08:22
  • 4369

自学java(6)继承类,超类和子类

继承:基于已存在的类构造一个新类,继承已存在的类就是复用(继承)这些类的方法和域。在此基础上,还可以添加一些新的方法和域,以满足新的需求,这是java程序设计中的一项核心技术。(is-a) ...
  • hello_bravo_
  • hello_bravo_
  • 2016-08-08 10:31:48
  • 563
收藏助手
不良信息举报
您举报文章:js超类子类
举报原因:
原因补充:

(最多只允许输入30个字)