簡體   English   中英

如何在JavaScript中實現這種Java模式(使用繼承)?

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

這是有效的Java代碼,用於為各種游戲使用的多種引擎實現提供處理余額監聽器注冊的基本引擎類。 例如,將有一個演示引擎維護一個演示游戲的演示余額,以及該引擎的現金版本,該現金版本從后台獲得余額等。這里的關鍵不是實際的Java,而是如何實現這種JavaScript中的模式。 我已經嘗試了大約30種不同的方法,包括使用John Resigs的“簡單JavaScript繼承”和“ JavaScript:權威指南”中定義的extend()糖,使用各種模塊模式,使用that = this等。為這個問題工作。

這是有效的Java代碼:

文件Engine.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);
}

文件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書)。 我假設我可以使用合成而不是嘗試繼承,但是這限制了語言的使用以及可以實現的模式。

編輯:這是Shaun West的答案的工作版本。 參見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中的“ new”關鍵字是什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM