继承之谨慎地定义方法

谨慎地定义方法

子类型有时候需要覆盖超类型中的某个方法,或者需要添加超类型中不存在的某个方法。但不管怎样,给原型添加方法的代码一定要放在替换原型的语句之后。来看以下的例子:

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
}

function SubType() {
    this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();

//添加新方法
SubType.prototype.getSubValue = function() {
    return this.subproperty;
}

SubType.prototype.getSuperValue = function() {
    return false;
}

var instance = new SubType();
alert(instance.getSuperValue());   //false

在以上代码中,加粗的部分是两个方法的定义。第一个方法getSubValue()被添加到了Subtype中。第二个方法getSuperValue()是原型链中已经存在的一个方法,但重写这个方法将会屏蔽原来的那个方法。换句话说,当通过SubType的实例调用getSuperValue()时,调用的就是这个重新定义的方法;但通过SuperType的实例调用getSuperValue()时,还会继续调用原来的那个方法。这里要给外注意的是,必须在用SuperType的实例替换原型之后,再定义这两个方法。

如果反过来:

SubType.prototype.getSubValue=function(){};
//现在SubType上有了getSubValue方法
SubType.prototype=new SuperType();
//现在prototype被覆盖了,之前定义的getSubValue等方法都没了

所以,自定义的扩展要在继承父类之后进行!

还有就是,在通过原型链实现继承时,不能使用对象字面量创建原型方法。因为这样做就会重写原型链,如下面的例子所示:

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
}

function SubType() {
    this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();

//使用对象字面量添加新方法,会导致上一行代码无效
SubType.prototype = {
    getSubValue: function() {
        return this.subproperty;
    },
    someOtherMethod: function() {
        return false;
    }
};

var instance = new SubType();
alert(instance.getSubValue());   //error!

以上代码展示了刚刚把SuperType的实例赋值给原型,紧接着又将原型替换成一个对象字面量而导致的问题。由于现在的原型是一个Object实例,而非SuperType的实例,因此我们设想中的原型链已经被切断——SubType和SuperType之间已经没有关系了。

猜你喜欢

转载自blog.csdn.net/m0_37581397/article/details/82078523