Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I recently found out that I can have two interfaces, one containing a method with the same signature as a method in the other interface. And I can have an interface or class that implements both of afore-mentioned interfaces. So the descendant class/interface implicitly implements two different methods as one method.

Why is this allowed in Java?

I can see numerous problems arising from this. Eclipse, for example, can only find out about implementations for one interface method, but for the second one it doesn't show any implementations at all. Also, I believe that there would be problems with automatic refactoring, like when you want to change the signature of the method in one of the interfaces and the IDE will be unable to correctly change that signature in all implementations (since they implement two different interfaces, and the IDE cannot tell which interface method the implementation is referring to.)

Why don't just make a compiler error like 'interfaces method names clashes' or something like that?

share|improve this question
3  
And then I can have an interface or class that implements both of that interfaces. Interfaces don't implement anything, they declare or extend other interfaces. Only a class implements a method signature and if it implements the same method signature of a base class then it overrides it. –  maple_shaft Nov 28 '12 at 11:54
2  
"Eclipse only can find out about implementations for only one interface method, but for the second one it doesn't show any implementations at all" if this is so, that's a bug in Eclipse –  gnat Nov 28 '12 at 15:27
    
I just meant that a third interface extending both that interfaces will contain both methods from that interfaces which is actually a single method. And that's I can't undertand too. –  dhblah Dec 2 '12 at 12:20

5 Answers 5

up vote 19 down vote accepted

There is no reason why this should be forbidden. The only point of an interface is to ensure that a method with particular signature exists in each implementing class. This is satisfied by any implementing class even if the condition is posed twice.

Granted, when you write an interface you presumably expect a certain meaning for the action of invoking the method, and presumably you document it above the declaration in the interface, but that is not the concern of the compiler. It cannot check whether the implementing class does the right thing, only whether it copies the signature exactly. Asking "Why doesn't the compiler forbid one method to satisfy two interface declarations?" boils down to "why doesn't the compiler prevent me from implementing the wrong semantics when I implement an interface?", and the answer to that question is much easier to see: because it can't! (If the compiler were able to judge your method implementation and forbid it if it contained a bug, then we wouldn't need programmers in the first place, we'd need only the specifications and the compiler.)

Obviously we would like it if implementing an interface guaranteed that the implementing class does the right thing, but that's not something that interfaces can do for you. In fact, I'd argue that it would be a bad thing to add a feature to the compiler that might give the impression that it is!

share|improve this answer
    
Thank you for the reply, but I don't believe you that compiler cannot check whether two different implemented interfaces have methods with the same signature. Yet it can tell when implemented interfaces contain methods with the same signature, but different return types. –  dhblah Dec 2 '12 at 21:30

Technically there is nothing wrong with this from the language point of view. There would have been problems if you have inherited from two classes, where the base classes are implemented.

If you consider it a design issue where one interface has one contract for that method and the other interface has other contract then not allowing it would not solve the issue. The end solution would be to disallow multiple inheritance.

Regarding the automatic refactoring problem, there is a problem with the IDE (Intellij has the same behavior); it should ask you which base method do you want refactored.

share|improve this answer
    
"If you consider it a design issue where one interface has one contract for that method and the other interface has other contract then not allowing it would not solve the issue." Why not? It would force you to rename one of the interface methods. If the interfaces are coming from third-party code, that might involving asking that third party to change it, but it would effectively solve the problem, wouldn't it? –  MatrixFrog Nov 29 '12 at 4:10
    
@MatrixFrog Because it would not permit multiple inheritance and thus still not letting you inherit from the two interfaces. –  m3th0dman Nov 29 '12 at 6:41

Why should that be a bad thing?

Just because it makes refactoring in Java harder, doesn't mean it is bad. For example, if I want refactoring in C++, it would be almost impossible in cases of some heavy template-dependent code, since the templates are Turing-complete. And in C++, templates are like the best thing in the language. Should we remove them to make refactoring easier?

The major concern in language design should be for the language to make the life/work of its users easier. I think your rule is too narrow, and not intuitive at that.

Plus this strikes me as too stringent: say I am using two libraries, closed source (as much as it's possible in Java anyway). I have a class that needs to implement two interfaces, one from each library. But the interfaces have a method with the same name/signature.

By your logic, I'm doomed! And to think of it, the library designers did nothing wrong: is it their job to know all method names in all classes of all other libraries? There is no chance to ensure this, even if you try hard...

You might say that this should be split in two classes, but what if the library designers actually meant the same thing with the two methods? Having a class implement both interfaces is the proper way in this situation.

share|improve this answer
    
Thank for your reply, but in case when there is two interfaces with two methods with the same signature but different return type, you couldn't implement bot of them. And nobody couldn't predict that. –  dhblah Dec 2 '12 at 21:20
    
@SoftwareEngeneeringLearner In Java method signature includes return type –  K.Steff Dec 3 '12 at 3:34
1  
"Definition: Two of the components of a method declaration comprise the method signature—the method's name and the parameter types." from here: docs.oracle.com/javase/tutorial/java/javaOO/methods.html - so it includes method name and number and types of parameters, no return type unfortunately/fortunately (there is a whole different question on this). –  dhblah Dec 3 '12 at 11:44
    
@SoftwareEngeneeringLearner Sorry, my bad here. You are correct and your question makes more sense now, but I really think you should either rephrase, or even better, ask a new question about this, specifying the differing return types. Having two methods with the same signature, but different return types (IMO) can be an issue. –  K.Steff Dec 3 '12 at 22:26

Well, I'm more of a .Net guy but I though of chipping in.

So, forgive me if the syntax is incorrect.

Suppose you have to talk to different two DBs in your class. Each DB has a different interface.

interface IOldDB
{
   string GetConnectionString()
   void OpenConnection()
   void OpenSession()
   ...
}

interface IOldDB
{
   string GetConnectionString()
   bool Connect()
   void NewSession()
   ...
}

Making it illegal would mean that I'd have to have two classes, one per Interface. All because one "apparently" conflicting method.

And if the methods of some interfaces have the same signature and you are implementing both, they are probably there for the same reason, right? If not, you're probably violating the SRP. Even if you are violating it, there's no reason for the compiler to stop you.

By the way, if I'm not mistaken, the compiler will throw an error if the signature of any of the methods conflict. Trying to implement those two interfaces

interface IAnotherDB
{
   void GetConnectionString(string cs)
}

interface IYetAnotherDB
{
   void GetConnectionString(string ConnectionString)
}

Will throw an error.

In .Net you could do that, by Implementing the Interface explicitly.

Instead of:

public void GetConnectionString(string ConnectionString)

You could do

IAnotherDB.GetConnectionString(string cs) 
IYetAnotherDB.GetConnectionString(string ConnectionString)

And go on.

Hope it helps.

share|improve this answer
    
If you highlight your code and click the {} button, then the site will format it to look like code. –  MatrixFrog Nov 29 '12 at 4:12
    
Thank you for your answer. You can implement two interfaces containing methods with different signatures in Java. But I found out that if you're extending two interfaces both having a method with a same signature but different returning types, then it'll be a compile time error: The return types are incompatible for the inherited methods Fooable.foo(int), AnotherFooable.foo(int). –  dhblah Dec 2 '12 at 13:45

It seems like it would imply a certain lazyness, but not really be a problem.

If you have two interfaces, each with methods you need for a given scenario then you either need to have interfaces implement each other, cast between them (yuck) or have them declare each others methods redundantly.

I guess I could imagine cases where extending wasn't practical or possible, so perhaps in that case you'd go for the option you are describing.

The better way to do it would probably be interface inheritance where one interface might implement 2 or 3 more specific interfaces, but this would annoy many people...

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.