Cyclic Inheritance Of Interfaces - java

I understand why cyclic inheritance of classes is not allowed in Java but I did not understand why cyclic inheritance of interfaces is not allowed. To illustrate:
interface Foo extends Bar {/*methods and constants*/}
interface Bar extends Foo {/*methods and constants*/}
Interfaces do not need instantiation, then what prevents them from extending each other?
By the way, I read this question but this is not about interfaces but classes:
Cyclic inheritance hierarchy in Java
Thanks in advance.

No, but extension of an interface is a way of splitting up the agreement. Remember, an interface is an agreement to provide an implementation of a set of methods.
public interface A extends B {
public void myMethod();
public void myOtherMethod();
}
You're saying interface A is defined by these methods and all the methods in interface B. Now if interface B says..
public interface B extends A {}
you're saying that interface B is defined by the methods in interface A. Well what defines interface A. A couple of methods and interface B. And what defines interface B? Interface A, which is defined by a couple of methods and interface B! See where this is going?
It makes no logical sense to allow this.

Probably there are no theoretical difficulties, but this would create unnecessary complications. A few to name:
Currently traversal of class interfaces (via recursive calls of Class.getInterfaces()) is guaranteed to produce finite result, probably with repeats, but nevertheless. For example, such code is valid:
private static void fillInterfaces(Class<?> clazz, Set<Class<?>> set) {
if(clazz == null) return;
for (Class<?> iclass : clazz.getInterfaces()) {
set.add(iclass);
fillInterfaces(iclass, set);
}
fillInterfaces(clazz.getSuperclass(), set);
}
public static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
Set<Class<?>> result = new HashSet<>();
fillInterfaces(clazz, result);
return result;
}
Similar code is already written and working in many places. With your proposal supplying the circular interface here would cause an infinite recursion.
Currently (in Java-8) interface can define a default implementation for its parent interface as well, replacing parent implementation if necessary. For example:
interface A {
default public String getX() {return "A";}
}
interface B extends A {
default public String getX() {return "B";}
}
static class C implements A, B {} // ok, C.getX() returns "B"
If now A extends B, then A wins:
interface A extends B {
default public String getX() {return "A";}
}
interface B {
default public String getX() {return "B";}
}
static class C implements A, B {} // ok, C.getX() returns "A"
But what if both A extends B and B extends A? Who will win? What new C().getX() will print? Or should it be new type of compilation error?
In general it seems that such feature would bring more problems than produce benefits.

See Java Language Specification 9.1.3 Superinterfaces and Subinterfaces :
An interface I depends on a reference type T if any of the following is true:
I directly depends on T.
I directly depends on a class C that depends on T (§8.1.5).
I directly depends on an interface J that depends on T (using this definition recursively).
It is a compile-time error if an interface depends on itself.
If circularly declared interfaces are detected at run time, as interfaces are loaded, then a ClassCircularityError is thrown (§12.2.1).
As for why, I like Andy Turner's comment:
If Foo extends Bar, then every instance of Foo is also a Bar. If Bar extends Foo, then every instance of Bar is also a Foo. If both were allowed to be true, then the only way the two conditions can be satisfied is if Foo == Bar.

Related

java and multiple inheritance

Can we call this code as multiple inheritance ?
interface Interface {
public int alpha = 0;
public int calculA(int a, int b);
public int calculB(int a, int b);
}
interface InterfaceA extends Interface {
public default int calculA(int a, int b) {
return a + b;
}
}
interface InterfaceB extends Interface {
public default int calculB(int a, int b) {
return a - b;
}
}
class TestInterface implements InterfaceA, InterfaceB {
public TestInterface() {
System.out.println(alpha);
System.out.println(calculA(5, 2));
System.out.println(calculB(5, 2));
}
public static void main(String[] args) {
new TestInterface();
}
}
It look like the default keyword permit to have a multiple inheritance.
It is correct or this concept have an another name ?
Thank's
Edit
It's not a duplicate of Are defaults in JDK 8 a form of multiple inheritance in Java? because this thread talking about the feature called Virtual Extensions.
My question is to ask if my implementation is called multiple inheritance or something else.
java doesn't supports multiple inheritance.
What you are doing is implementing an interface. You can't extend multiple classes in java but you can implement multiple interfaces.
An interface is a reference type and it is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. An interface may also contain constants, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods.
A class describes the attributes and behaviors of an object and an interface contains behaviors that a class implements.
For more on interface, click here
Java doesn't support multiple inheritance.
What you have currently done is implement multiple interfaces which is absolutely permittable.

Multiple Inheritance with Base Class and Interface having same function with different return types

I have written a class which is a base class of Class A and implements an interface of Class B.
Now my compiler is giving a wierd kind of error saying that "The return types of functiona from Class A is not compatible with return type of functiona in class B."
My Code is as below,
public class X extends A implements B
{
}
public class A
{
public Enumeration<String> test(){}
}
public interface B
{
public Enumeration<Object> test();
}
Now I can't understand why the compiler is giving such an error since already String is a type of an object, so what i understood is that automatic type conversion should happen in runtime because of that. Am i right? or my conceptual understanding has gone wierd on me?
If you can change the definition of the interface, you can broaden it and get what you want. The return type would be Enumeration<? extends Object>
What you're trying to do is possible in Java. As Ernest stated, an Enumeration is not a subclass of Enumeration, since Java genercis lacks the concept of variance.
Anyway, you can express you intention using type wildcard. You have to change you interface this way:
public interface B
{
public Enumeration<?> test();
}
Now your code compile fine. Just to let you know, you can also restrict your interface to some other type than Object. For example, if you have to build an interface that return Enumerations
of Number:
class X extends A implements B
{
}
class A
{
public Enumeration<Long> test(){return null;}
}
class C
{
public Enumeration<String> test(){return null;}
}
//This doesn't compile! String does not extend Number
/*class Y extends C implements B
{
}*/
interface B
{
public Enumeration<? extends Number> test();
}
String is a subclass of Object, but Enumeration<String> is not a subclass of Enumeration<Object>. If it were, then I could cast an Enumeration<String> to an Enumeration<Object>, then cast it to an Enumeration<Integer>, all without a warning; but when I tried to use it as an Enumeration<Integer>, I'd get ClassCastExceptions.
Note that Java arrays behave as I've described above, and this is widely considered a significant flaw in the design of the language.

Is it possible to make type safe Java Collections whose members merely implement several interfaces?

If I have:
interface A{ void a(); }
interface B{ void b(); }
I can hava a generic method like this:
class C {
<T extends A & B> void c(T t) {
t.a();
t.b();
}
}
But i can't hava a generic collection like this:
class D{
List<? extends A & B> l;
}
I know that I could make an empty interface E that extends both A and B, and have a List that contains E's... but I'd rather leave my classes marked with just A and B, and not have to have an E. This is even more problematic when there are many more A's and B's that can be combined in 2^n ways.
I would rather be able to define a type on the fly, as a union of interfaces, and have the collections recognize objects that implement all of the interfaces as instances of that type.
Is there a way to do this in Java? I'm open to any kind of work around or hack at this point in order to avoid making a new interface, and tagging my classes with it, just so that they can live together in a collection. Or, if someone could clarify for me why this is impossible, that would be equally appreciated.
public class Foo<T extends A & B> {
private List<T> list;
//getters, setters, etc.
}
As Jeffrey also said somehow, you have to parameterize your class D:
class D<T extends A & B> {
List<T> l;
/**
* this is just a method for the sake of example
*/
public T getSomeMember() {
return l.iterator().next();
}
}
This way you are deferring your choice of the actual type T to the method which actually insntatiates D. If that information is not available even at that point you will have to parameterize that method too with <T extends A & B>:
private <T extends A & B>
void doSomething() {
D<T> d = new D<T>();
T v1 = d.getSomeMember();
A v2 = d.getSomeMember();
B v3 = d.getSomeMember();
}
If there is a field of type D in some class, then that class must know the actual type that extends A & B, or be itself parameterized if it doesn't. In principle you propagate the type parameter up until you know the actual type.
Be warned that this process is likely to become unmanageable for large codes. It may also result in ugly code, but of course that depend on your conception of aesthetics.

How can I get the implementing class for a given method?

Given a few classes/interfaces.
public interface A {
public int doSomthing(int x);
}
public class B implements A {
int doSomthing(int x){
//actually do something
};
}
public class C extends B {
//does some specific implementations of what B does
// but does NOT override "int doSomething(int)"
}
How in a code using implementation C (or any subClass of C) may I determine (programatically) that B was the class implementing int doSomething(int).
Or if any of B's subclasses (lets say D which extends C) overrid "int doSomething(int)" how, when working with E (which extends D, yeah ... this is one large family of classes) may I define first parent that implemented "int doSomething(int)" ?
Thank you all in advance :)
You can do that using reflection, i.e. you start at the class the object has and check whether that class defines the method which is identified by the methodname and parameter types. If the class doesn't define that method you get its super class and check this, until you hit Object in which case the method isn't available at all.
For public methods, it's easier since Java has already a built-in method for this:
Class<?> mostSpecificImplementor =
yourObject.getClass().getMethod( "doSomthing", int.class ).getDeclaringClass();
Note that this only works for public methods, otherwise you'd have to search up the class hierarchy yourself (use getDeclaredMethod(...) in this case).

What (not) to declare when implementing an interface with an abstract class?

I have an interface A, for which I have to supply a few different
implementations. However, those implementations share some helper methods, so
I moved those methods to an abstract base class.
Interface A {
void doX();
}
abstract Class B implements A {
protected void commonY() {
// ...
}
#Override
public abstract void doX();
}
Class C extends B {
#Override
public void doX() {
// ...
}
}
Class D extends B {
#Override
public void doX() {
// ...
}
}
My code works as expected, but I have a few questions:
Should I declare the abstract Method doX() in Class B? Why (not)?
Should I also explicitly declare "implements A" on Class C and D? Why (not)?
I think it would be better to do it as follows:
Interface A {
void doX();
}
abstract Class B {
protected void commonY() {
// ...
}
}
Class C extends B implements A{
public void doX() {
// ...
}
}
Class D extends B implements A{
public void doX() {
// ...
}
}
You shouldn't mix the interface (signature of methods) with the implementation.
Should I declare the abstract Method doX() in Class B? Why (not)?
No. It's an abstract class - defining the interface will mean that all subclasses will need to implement those methods. In other words, it's redundant.
Should I also explicitly declare "implements A" on Class C and D? Why (not)?
No, again - because your superclass (Abstract base class) implements that interface, your concrete subclasses will be guaranteed to implement that interface.
I'll just throw in the other option.
Turn abstract class B into an AUtil class that doesn't implement A. The method signatures may require an additional argument of type A to work with.
C and D implement A, and instantiate an AUtil internally. This does allow C and D to extend other classes.
I agree with JeeBee: consider implementing your helper methods somewhere other than an abstract base class.
If your helper method commonY() only exists in abstract base class B, all classes which implement Interface A will have to also extend base class B in order to take advantage of that implementation of commonY(). But, you might not always want to be forced to extend class B.
Also, what if you want to change the implementation of commonY() in the future? You will then affect lots of implementations of interface A. But if you don't control all these implementations of interface A, you may affect their functionality (in a bad way) without intending to.
Using an abstract base class in this situation may simply take away some flexibility without giving you anything in return.
An abstract class implementing an interface must implement that interface. Specifically, it must have a public method for every method-name-and-signature specified in that interface.
Inheritance is transitive. You do not need to write that class C implements interface A if class C derives class B which implements interface A. However, there isn't much harm to it either.
I would not declare doX() in B and not add "implements A" on C and D because you should not repeat yourself.
The abstract doX() in B adds nothing, as it's already specified by "implements A". The same is true for adding "implements A" to C and D.
The only possible use for those clauses would be documentation: If you want to make it very explicit that C (or D) is-a A, then you could add the implements, but you should be aware that it really doesn't matter to the compiler.

Categories