我如何在JavaScript中实现这个java模式(使用继承)

How do I implement this java pattern in JavaScript (using inheritance)?

本文关键字:模式 java 继承 JavaScript 实现      更新时间:2023-09-26

以下是工作的java代码,用于为各种游戏使用的许多引擎实现提供一个处理平衡侦听器注册的基本引擎类。例如,将有一个为演示游戏维护演示余额的演示引擎和从后台获取余额的同一引擎的现金版本等。这里的关键不是实际的java,而是如何在JavaScript中实现这种模式。我已经尝试了大约30种不同的方法来实现这一点,包括使用John Resigs的"简单JavaScript继承"answers"JavaScript:the definitional Guide"中定义的extend()sugar,使用各种模块模式,使用that=this等。这些都不适用于这个问题。

以下是正在工作的java代码:

文件引擎.java:

package com.test;
public abstract class Engine {
    BalanceListener externalBalanceListener = null;
    double balance = 0;
    public void registerBalanceListener(BalanceListener balanceListener) {
        externalBalanceListener = balanceListener;
        balanceListener.update(balance);  // call once when first register
    }
    public double getBalance() {
        return balance;
    }
    protected void setBalance(double newBal) {
        if (newBal != balance) {
            balance = newBal;
            if (externalBalanceListener != null) {
                externalBalanceListener.update(newBal);
            }
        }       
    }
    public abstract double startGame(double stake, int numLines);
}

File BalanceListener.java

package com.test;
public interface BalanceListener {
    void update(double balance);
}

文件DemoEngine.java

package com.test;
import java.util.Random;
public class DemoEngine extends Engine {
    public DemoEngine() {
        setBalance(10000);
    }
    public double startGame(double stake, int numLines) {
        double wonAmount;
        Random random = new Random();
        setBalance (getBalance() - (stake * numLines));
        // some game logic
        wonAmount = Math.round((random.nextDouble() * 10)) * stake;
        setBalance (getBalance() + wonAmount);          
        return wonAmount;
    }
}

文件DemoGame.java

package com.test;
public class DemoGame {
    public class MyListener implements BalanceListener {
        public MyListener(){
        }
        public void update(double balance) {
            System.out.println("new balance: " + balance);
        }
    }
    public static void main(String[] args) {
        Engine engine = new DemoEngine();
        DemoGame demoGame = new DemoGame();
        BalanceListener balanceListener = demoGame.new MyListener();
        engine.registerBalanceListener(balanceListener);
        engine.startGame(10, 20);
    }
}

下面是一个简单的(失败的)尝试,试图让同样的东西在JavaScript中工作(请参阅http://jsfiddle.net/fmX67/)

function Engine() {
    this.balance = 0;
    this.externalBalanceListener;
    this.registerBalanceListener = function(l) {
            this.externalBalanceListener= l;
            this.externalBalanceListener(this.balance);
    };
    this.getBalance = function() {
        return this.balance;
    };
    this.setBalance = function (newBal) {
        if (newBal != this.balance) {
            this.balance = newBal;
            if (this.externalBalanceListener != undefined) {
                this.externalBalanceListener(newBal);
            }
        }
    };
};
function DemoEngine() {
    this.startGame = function(stake, numLines) {
        var won;
        setBalance(this.getBalance() - stake*numlines);
        won = Math.round(Math.random() * 10) * Stake;
        this.setBalance(this.getBalance() + won);
        return won;
    };
}
DemoEngine.prototype = Engine;
function DemoGame() {
    function balanceListener(balance) {
        console.log(balance);
    }
    var engine = new DemoEngine();
    engine.registerBalanceListener(balanceListener); // This throws an exception: Uncaught TypeError: Object [object Object] has no method 'registerBalanceListener'
    engine.startGame(10, 25);
}
var game = new DemoGame();

显然,我不知道自己在做什么(尽管我读了几本JS书)。我认为我可以使用composition而不是试图继承,但这限制了语言的使用以及可以实现的模式。

编辑:这是肖恩·韦斯特的答案。看见http://jsfiddle.net/fmX67/3/

function Engine() {
    this.balance = 0;
    this.externalBalanceListener;
    this.registerBalanceListener = function(l) {
            this.externalBalanceListener= l;
            this.externalBalanceListener(this.balance);
    };
    this.getBalance = function() {
        return this.balance;
    };
    this.setBalance = function (newBal) {
        if (newBal != this.balance) {
            this.balance = newBal;
            if (this.externalBalanceListener != undefined) {
                this.externalBalanceListener(newBal);
            }
        }
    };
};
function DemoEngine() {
    this.setBalance(1000);
    this.startGame = function(stake, numLines) {
        var won;
        this.setBalance(this.getBalance() - stake*numLines);
        won = Math.round(Math.random() * 10) * stake;
        this.setBalance(this.getBalance() + won);
        return won;
    };
}
DemoEngine.prototype = new Engine();
function DemoGame() {
    function balanceListener(balance) {
        console.log(balance);
    }
    var engine = new DemoEngine();
    engine.registerBalanceListener(balanceListener); // This throws an exception: Uncaught TypeError: Object [object Object] has no method 'registerBalanceListener'
    engine.startGame(10, 25);
}

var game = new DemoGame();

对于来自Java的人来说,这可能看起来很奇怪,但在您的尝试中,您会想要更改以下内容:

DemoEngine.prototype = Engine;

对此:

DemoEngine.prototype = new Engine();

如果你想了解更多信息,这个答案很好:什么是';新';JavaScript中的关键字?