Javascript - 可以模拟经典的OOP继承吗?

时间:2016-02-13 18:46:56

标签: javascript oop inheritance prototype prototypal-inheritance

我很想知道,鉴于javascript原型继承的局限性,可以模拟基于类的继承,如其他OOP语言所示。

我创建了一个超类和子类,如下所示:

//Parent
function Animal(i)
{
    //Some constructor implementation
}

//Child
function Pig(i)
{
    //Some additional constructor implementation
}

Pig.prototype = new Animal();

我可以确保子进程继承父进程的功能,使我不需要显式调用它们,或者在子对象中创建它们吗?

Animal.prototype.eat = function()
{
    console.log("eating...");
}

Pig.eat(); //No implementation of eat in the Pig object

除了自己的父对象变量之外,我是否可以确保子进程继承其所有父对象变量,而不显式调用父代的构造函数:

function Pig(i) 
{
    User.call(this, i);
    //Some pig-like variables
}

基本上,我想在我的父类中创建所有实现,并且只编写需要重写的函数+子类中的任何其他函数。如果我想调用Pig.eat(),我希望它使用父函数,如果子对象中不存在。在创建Pig对象时,除了它自己独特的变量之外,我还希望继承它的父变量。这可能吗?

2 个答案:

答案 0 :(得分:2)

  

我想在我的父类中创建所有实现,只编写需要重写的函数+子类中的任何其他函数。

它实际上是这样的。 可能你刚做了一些有点不对的事,看看这个例子:



//Parent
function Animal()
{
    this.animalInstinct = true;
}

Animal.prototype.eat = function()
{
    alert("eating...");
}

//Child
function Pig()
{
    this.nose = 'pigNose' 
}

Pig.prototype = new Animal();

pig = new Pig();

pig.eat(); //There is implementation of eat in the Pig object




另请注意,Pig.prototype = new Animal();在某些情况下可能会出现问题。例如,为了定义Pig类,您需要实例化Animal对象。对于需要将一些参数传递给构造函数的更复杂的对象,这可能不方便。

Recommended wayPig.prototype = Object.create(Animal.prototype)

答案 1 :(得分:1)

查看ES6方式,可以使用Babel等方法轻松编译成ES5。

'use strict';
class Animal {
    constructor() {
    }

    eat() {
        console.log('Eating')
        return this;
    }

    play() {
        console.log('Do whatever an animal does...');
        return this;
    }
}

class Pig extends Animal {
    constructor() {
        super()
    }

    play() {
        // This overrides the Animal play method
        console.log('Roll in the mud!');
        return this;
    }

    makeBacon() {
        console.log('BACON!!');
    }
}

如果您想查看ES5版本,请将上述内容粘贴到Babel的实时testing console中,或者只是在支持它的最新版Chrome中测试。 然后,您可以执行以下操作:

var pig = new Pig();
pig.eat().play().eat().makeBacon();