1

メソッドが呼び出されたときにどのインターフェースの実装が使用されるかを Java がどのように認識しているかに興味があります。

以下は、「魔法のように」どのように機能するかを理解するのに苦労しているコードのスニペットです。

インターフェース「LotListener」:

public interface LotListener
{

    public void bidUpdate( Lot lot, Bid bid);
}

「LotListener」の実装は BidStatistics と Person です。

BidStatistics と Person をすべてインターフェイスに変更する前のコードは次のとおりです。

public class Lot
{

    private HashSet<**Person**> bidders;

    private **BidStatistics** bidStats;


    public Lot(int number, String description, **BidStatistics** bidStats)
    {
        bidders = new HashSet<**Person**>();

        this.bidStats = bidStats;   

    }


    public boolean bidFor(Bid bid)
    {
        **Person** nextBidder;

        bidders.add( bid.getBidder() );
        Iterator iterateBids = bidders.iterator();

        if(highestBid == null) {
            // There is no previous bid.
            highestBid = bid;
            bidStats.bidUpdate( this, bid );
            return true;
        }
        else if(bid.getValue() > highestBid.getValue()) {
            // The bid is better than the previous one.
            highestBid = bid;
            while ( iterateBids.hasNext() )
            {
                nextBidder = (LotListener) iterateBids.next();
                nextBidder.bidUpdate( this, bid );
            }
            bidStats.bidUpdate( this, bid );
            return true;
        }
        else {
            // The bid is not better.
            return false;
        }
    }

ここで、すべての Person と BidStatistics をインターフェイス LogListener に変更すると、次のようになります。

public class Lot
{
    private HashSet<**LotListener**> bidders;

    private **LotListener** bidStats;


    public Lot(int number, String description, **LotListener** bidStats)
    {
        bidders = new HashSet<**LotListener**>();

        this.bidStats = bidStats;   

    }

    public boolean bidFor(Bid bid)
    {
        **LotListener** nextBidder;

        bidders.add( bid.getBidder() );
        Iterator iterateBids = bidders.iterator();

        if(highestBid == null) {
            // There is no previous bid.
            highestBid = bid;
            bidStats.**bidUpdate**( this, bid );
            return true;
        }
        else if(bid.getValue() > highestBid.getValue()) {
            // The bid is better than the previous one.
            highestBid = bid;
            while ( iterateBids.hasNext() )
            {
                nextBidder = (LotListener) iterateBids.next();
                nextBidder.**bidUpdate**( this, bid );
            }
            bidStats.**bidUpdate**( this, bid );
            return true;            
    }

このコードは引き続き機能します。私の質問はなぜですか?

Person からの bidUpdate の実装をいつ使用するか、および BidStatistics からのbidUpdate の実装をいつ使用するかをどのように知るのでしょうか??

編集: 一部のコードの周りの ** については本当に申し訳ありません。強調するためにそれらを太字にしようとしましたが、うまくいかないと思います。

4

4 に答える 4

3

これを仮想ディスパッチと呼びます。

インターフェイスとして宣言された変数でメソッドを呼び出すと、Java はインスタンスのvtableで呼び出すメソッドを検索します。これは、クラスに基づいてインスタンスを作成するときに設定されます。

したがって、実行時にそのオブジェクトがインスタンスであるクラスによって定義された実装を実際に呼び出します。

于 2013-04-03T03:17:09.997 に答える
3

変数の型は ですが、変数が指すオブジェクトLotListenerの型は依然としてまたはです。PersonBidStatistics

于 2013-04-03T03:17:21.177 に答える
0

それはわからない。適切なタイプのオブジェクトを提供することで、それを伝えます。

于 2013-04-03T09:26:35.553 に答える
0

クラスの実際のインスタンスを指しているからです。

于 2013-04-03T03:17:39.897 に答える