7

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?

3
  • 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, 2012 at 11:54
  • 3
    "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, 2012 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, 2012 at 12:20

5 Answers 5

23

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!

1
  • 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, 2012 at 21:30
6

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.

4
  • 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, 2012 at 21:20
  • @SoftwareEngeneeringLearner In Java method signature includes return type
    – K.Steff
    Dec 3, 2012 at 3:34
  • 2
    "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, 2012 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, 2012 at 22:26
5

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.

2
  • "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?
    – Tyler
    Nov 29, 2012 at 4:10
  • @MatrixFrog Because it would not permit multiple inheritance and thus still not letting you inherit from the two interfaces.
    – Random42
    Nov 29, 2012 at 6:41
1

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.

2
  • If you highlight your code and click the {} button, then the site will format it to look like code.
    – Tyler
    Nov 29, 2012 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, 2012 at 13:45
0

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...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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