Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I can't write "implements AClass" in Java?

In Java people often define an interface together with a class and use interface name instead of class name where possible, in order to allow new implementations later. Here the logical interface is duplicated.

This kind of "just in case" duplication would not be necessary if Java allowed using a class as an interface eg: class MyScanner extends MyStuff implements java.util.Scanner. Also this would ease the situation where I need to provide a class-type but I don't want to extend that class.

As I understand, "implementing a class" would be rejected not only by the compiler but also by the JVM (if I hacked this declaration into classfile). Are there some technical difficulties for this or it's not regarded as important thing? It doesn't look like a backward-compatiblity problem (I mean, old code would run fine if JVM supported this).

EDIT: for clarification, I will copy here StriplingWarrior's much better wording of the same questions:

Why can't a class "implement" another class's method contract without actually extending that class? Is it a technical issue? Would it somehow open us up to some issues that the OP can't foresee?
like image 417
Aivar Avatar asked Jan 14 '11 22:01

Aivar


3 Answers

Do I understant correctly that MyClass implements AClass would mean that MyClass must provide (or inherit) implementations for all public methods that AClass has? I.e. each class implicitly defines an interface consisting of its public methods?

If so, then the problem I see with that is that interfaces are really something very different from classes, and the two should not be mixed like that. Interfaces define a contract, classes an implementation. A consequence of that: The functionality of classes can be extended relatively freely, but not so interfaces with existing implementations.

So there you have a very concrete reason why your suggestion would be bad: you could never add any public method to any class without risking to break some code that implements that class.

And on the other hand, what problems would it solve? The code duplication when you have an interface with a single implementation? How about solving that by not doing it? IMO it's usually something done by people doing TDD dogmatically while using outdated mocking frameworks not capable of mocking concrete classes.

like image 190
Michael Borgwardt Avatar answered Oct 10 '22 09:10

Michael Borgwardt


The issue is multiple inheritance. If you try to extend or implement two classes, there are potential semantic issues.

You CAN implement multiple interfaces, as well as extend from one class. But you can only implement interfaces, which get around most of the problems with multiple inheritance simply by forcing the specification to be declarative in nature, requiring the implementer to implement the methods directly. In that case, method conflicts are resolved by the simple expedient of implementing one method and having it count for both interfaces.

like image 34
Platinum Azure Avatar answered Oct 10 '22 08:10

Platinum Azure


As has been stated before, this is how the standard is defined and not being a part of the decision making process I can only chip in with my $0.02.

This is not as much about duplicate logical interfaces, but a standard for creating an API that you would like to be flexible. It is considered a good design practice, even in languages that support multiple inheritance, to expose interfaces from an API.

Given the current state of IDE's it is quite easy to not do this up front and then refactor later when you decide you need multiple implementations of a given type.

There may also be use cases against this where inside your code you have a strong dependency on the functionality of a class and by having a different implementation your code could break. This is the point of being able to do:

ClassA a = new ClassA();

rather than

InterfaceA a = new ClassA();

This may lead to unexpected behavior.

like image 38
Shane Avatar answered Oct 10 '22 10:10

Shane