1

I am curious as to how Java knows which implementation of an interface will be used when a method is called.

So below are snippets of the code where I have trouble understanding how it "magically" works:

The Interface "LotListener":

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

The Implementations of "LotListener" are BidStatistics and Person.

Now here is the code I had before changing all the BidStatistics and Person to the interface:

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; } } 

Now when I change all the Person and BidStatistics to the interface 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; } 

This code still works. My questions is why?

How does it know when to use the implementation of bidUpdate from Person, and when to use the implementation of bidUpdate from BidStatistics??

EDIT: Really sorry about the ** around some of the code. I tried to bold them to highlight it but I guess that doesn't work.

4 Answers 4

5

This is called virtual dispatch.

When you call a method on a variable declared as an interface, Java will look up which method to call in the instance's vtable, which is set when you create the instance based on the class.

Thus, it actually calls the implementation definde by the class that that object is an instance of at runtime.

Sign up to request clarification or add additional context in comments.

Comments

4

The type of the variable is LotListener, but the type of the object pointed to by the variable is still either Person or BidStatistics.

2 Comments

Ah ok thank you! I didn't look hard enough to see that there was a bidders.add( bid.getBidder ); Thanks!
Yup, that's why you can't do new LotListener(), because the interface has no implementation - you need to create an instance of an actual class.
0

Because it points to the actual instance of the class.

Comments

0

It doesn't know. You tell it, by supplying an object of the appropriate type.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.