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,但变量指向的对象Person的类型仍然是 要么要么BidStatistics

于 2013-04-03T03:17:21.177 回答
0

因为它指向类的实际实例。

于 2013-04-03T03:17:39.897 回答
0

它不知道。您通过提供适当类型的对象来告诉它。

于 2013-04-03T09:26:35.553 回答