I have some questions as to which overloaded method would be called in certain cases.
Case 1:
public void someMethod(Object obj){
System.out.println("Object");
}
public void someMethod(InputStream is){
System.out.println("InputStream");
}
public void someMethod(FilterInputStream fis){
System.out.println("FilterInputStream");
}
I know that if I pass it a String
it will print "Object". However, what if I pass it an InputStream? It gets more confusing if I pass it something such as BufferedInputStream. Will this call the Object one, the InputStream one, or the FilterInputStream one? Does the order that the methods appear matter?
Case 2:
This is a little more tricky, because it takes advantage of multiple interface inheritance. Neither BlockingQueue and Deque are sub/supertypes of each other, but both are supertypes of BlockingDeque. Sun added multiple inheritance with interfaces because they don't need a tree structure. The declaration for BlockingDeque is
public interface BlockingDeque extends BlockingQueue, Deque {
.
public void someMethod(BlockingQueue bq){
System.out.println("BlockingQueue");
}
public void someMethod(Deque bq){
System.out.println("Deque");
}
public void someCaller(){
BlockingDeque bd = new LinkedBlockingDeque();
someMethod(bd);
}
Will this Call someMethod(BlockingQueue) or someMethod(Deque)?
Case 3:
You can combine these two with this:
public void someMethod(Queue q){
//...
}
public void someMethod(Deque q){
//...
}
public void someMethod(List p){
//...
}
public void someCaller(){
someMethod(new LinkedList());
}
Same question: someMethod(Queue), someMethod(Deque), or someMethod(List)?
Case 4:
You can make things very complicated too, by introducting two arguments:
public void someMethod(Collection c1, List c2){
//...
}
public void someMethod(List c1, Collection c2){
//...
}
public void someCaller(){
someMethod(new ArrayList(), new ArrayList());
}
Will this call someMethod(Collection, List) or vice versa?
Case 5:
It gets worse when they have different return types:
public Class<?> someMethod(BlockingQueue bq){
return BlockingQueue.class;
}
public String someMethod(Deque bq){
return "Deque";
}
public void someCaller(){
BlockingDeque bd = new LinkedBlockingDeque();
System.out.println(someMethod(bd));
}
These can get pretty bad. What will someCaller print in this case? someMethod(BlockingQueue).toString(), or someMethod(Deque)?