Javascript继承和方法覆盖

Posted

技术标签:

【中文标题】Javascript继承和方法覆盖【英文标题】:Javascript inheritance and method overriding 【发布时间】:2011-06-14 05:36:10 【问题描述】:

假设我有这样的课程:

function Widget() 
    this.id = new Date().getTime();
    // other fields

Widget.prototype = 
    load: function(args) 
        // do something
    

从这个类中,我创建了一些其他类,它们继承了相同的原型,但添加了一些方法。我想要做的是能够在子类中定义一个 load() 方法,它首先调用父方法,然后执行一些代码。比如:

SpecialWidget.prototype = 
    load: function(args) 
        super.load(args);
        // specific code here
    

我知道 javascript 中没有 super 关键字,但一定有办法做到这一点。

【问题讨论】:

【参考方案1】:

你可以这样模拟:

SpecialWidget.prototype = 
    load: function(args) 
        Widget.prototype.load.call(this, args);
        // specific code here
    

或者您可以像这样创建自己的超级属性:

SpecialWidget.prototype.parent = Widget.prototype;

SpecialWidget.prototype = 
    load: function(args) 
        this.parent.load.call(this,args);
        // specific code here
    

【讨论】:

我想这是最简单的解决方案!谢谢 只是为了补充我之前的评论,我有一个已经从一个类继承的对象,我想基本上专门化一个方法。【参考方案2】:

所以首先,你像这样设置你的“子类”

function SubClass(name) 
    Super.call(this);

    // stuff here


SubClass.prototype = new SuperClass(null);
SubClass.prototype.constructor = SubClass;

然后你就可以了

SuperClass.prototype.theMethod.apply(this);

从子类实现中专门调用超类的实现。

【讨论】:

对于像我这样质疑这种方法与答案中的调用之间的区别的人来说,简短的回答是没有。 Mozilla在这里提供了长答案...developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…【参考方案3】:

我不知道这是否是最好的解决方案,但你可以这样做:

function Widget() 
    this.id = new Date().getTime();

Widget.prototype.load = function(args) 
   alert( 'parent load' );
;

SpecialWidget = function();

   // Make the prototype of SpecialWidget an instance of Widget
var proto = SpecialWidget.prototype = new Widget;

   // Give the prototype a function that references the "load" from Widget
proto.parent_load = proto.load;

   // Give SpecialWidget its own "load" that first calls the parent_load
proto.load = function( args ) 
    this.parent_load( args );
    alert( 'special load' );
;

var inst = new SpecialWidget;

inst.load();

这使得SpecialWidget 的原型成为Widget 的实例,因此它继承了Widget 的所有内容。

然后它引用Widget 中的load(),称为parent_load(),并创建自己的load(),在调用时调用parent_load()

【讨论】:

如果您不迎合老客户,您可以使用Object.create(Thing.prototype) 而不是new Thing【参考方案4】:

如果您像这样进行覆盖,则可以将 load 方法的旧值存储在闭包中:

function Widget() 
    this.id = new Date().getTime();
    // other fields


Widget.prototype = 
    load: function(args) 
        // do something
        alert("Widget Prototype Load");
    
;

function SpecialWidget()
;

SpecialWidget.prototype = new Widget();

(function()
    var oldLoad = SpecialWidget.prototype.load;
    SpecialWidget.prototype.load = function()
        oldLoad();
        alert("new Load");
    ;
());


var x = new SpecialWidget();
x.load();

它有效,但我不确定这是否是最好的方法。

【讨论】:

【参考方案5】:

使用Simple Javascript Class:

Class.extend('Widget', 
  load: function () 
    alert('foo');
  
);

Widget.extend('SpecialWidget', 
  load: function () 
    this.super();
    alert('bar');
  
);

new Widget().load(); // Alert: 'foo'
new SpecialWidget().load(); // Alert: 'foo' and 'bar'

看看Simple Javascript Class Project、Simple JavaScript Inheritance和Inheritance Patterns in JavaScript。

【讨论】:

以上是关于Javascript继承和方法覆盖的主要内容,如果未能解决你的问题,请参考以下文章

javascript 覆盖继承的方法

始终要覆盖toString实现可以使类用起来更加舒服

方法和变量在继承时的覆盖和隐藏问题

四. Java继承和多态3. 继承中的方法的覆盖和重载

Java继承方法隐藏(覆盖)

201671010145 2016-2017 《Java程序设计》java的继承中什么叫方法覆盖,是如何实现的?