Java - two interfaces with the same method, one just common

I always thought that two interfaces with the same method cannot be inherited by the same class, as indicated in many such issues.

Java jre 7, jdk 1.7

But this code works here.

Example:

Interfaces:

public interface IObject { public Object create(Object object) throws ExceptionInherit; } public interface IGeneric<T> { public T create(T t) throws ExceptionSuper; } 

Class implementation:

 public class Test implements IGeneric<Object>, IObject { @Override public Object create(final Object object) throws ExceptionInherit { return object; } } 

Don't these two method declarations have the same body?

Exceptions:

Exceptions are simply additive for this design, which makes it more complex.

 public class ExceptionSuper extends Exception {} public class ExceptionInherit extends ExceptionSuper {} 

It also works without any exceptions.

In addition: If both method interfaces throw different inheriting exceptions, I can use UserLogic for either of the two interfaces and catch another subset of the exceptions!

Why does it work?

Edit:

 The generic implementation is not even necessary: public interface IA { public void print(String arg); } public interface IB { public void print(String arg); } public class Test implements IA, IB { @Override public void print(String arg); { // print arg } } 
+4
source share
5 answers

You can "implement" two interfaces that have methods of the same signatures. You are having trouble trying to “extend” two classes that have identical method implementations. Multiple Interface Inheritance - GOOD; Multiple Implementation Inheritance - TRICKY.

The ExceptionInherit object can be used instead of the ExceptionSuper object because it inherits it. The ExceptionInherit object has all the information that the ExceptionSuper object does (plus more). This is not true. You cannot use the ExceptionSuper object instead of the ExceptionInherit object because the ExceptionInherit code expects more than your base object (well, maybe, but not in your case).

Your implementation of the "create" method fills the "create" ICreateUser signature because it throws an "ExceptionInherit", which can be thrown into the "ExceptionInherit" and "ExceptionSuper" traps to get all the information they need (only the base class) from the object.

You cannot change your implementation to throw an "ExceptionSuper" because traps waiting for an "ExceptionInherit" will receive an object with insufficient information.

0
source

Now I can use UserLogic for either of the two interfaces and get a different set of exceptions!

No, you can’t. See “Java Puzzlers: Traps, Traps, and Corner Cases” by Joshua Bloch and Neil Gafter, Puzzle 37 Extremely Secret:

Each interface limits the set of checked exceptions that can throw. A set of checked exceptions, which can be the intersection of sets of checked exceptions, which is declared to throw all applicable types, not a union.

So, in your case, the implementation

create (User User) throws an ExceptionInherit

is correct. But

create (User) throws an ExceptionSuper

will not compile

+3
source

You will not get other exceptions because ExceptionInherit extends ExceptionSuper . But consider the following:

 interface X { public void foo() throws ExceptionA; } interface Y { public void foo() throws ExceptionB; } class ExceptionA extends Exception {} class ExceptionB extends Exception {} class Z implements X, Y { public void foo() throws ExceptionA { } } 

Note that ExceptionA and ExceptionB not related through inheritance. In this case, you will get a compilation error because ExceptionA not compatible with the throws in Y

+2
source

This will work without general, without exceptions. Even before Java 1.4 and possibly earlier.

I always thought that two interfaces with the same method cannot be inherited by the same class, as indicated in many such issues.

This is actually not true, and I'm not sure what questions you are referring to.

Of course, there are reasons not to use two interfaces with the same method signature, which is most important that the implementation can only do one, so if both interfaces expect a different result from the method, you will not be able to satisfy both interfaces, but this will not be an error compilation.

There are also reasons why it would be perfectly fair to have 2 interfaces with the same methods. If two interfaces extend each other, the implementation can perfectly implement both interfaces. Even in a simpler situation, when the interfaces simply exchange names, there are no technical limitations.

An interface only requests specific methods, so it does not require other interfaces to be absent.

Valid code:

 public interface IDo { public void does(); } public interface ITwo { public void does(); } public class Test implements IDo, ITwo { public void does() { } } 
+1
source
 I always thought that two interfaces with the same method cannot be inherited by one class, as stated in many so questions. 

If you want to be more precise, you must replace "the same method" with " methods with equivalent signature equivalents ." The signature is the "method name" + "parameter list" (some rules also apply to the return type and throw clause). You need to know what is equivalent to an equivalent equivalent.

This is fine if the class implements two or more interfaces with such methods, provided that:

1- They all have the same return type, or one of these methods has a return type, which is a subtype of all the others. This is the type of return you should use in your implementation.

For instance:

 interface A { Integer x(); } interface B { Number x(); } interface C { Object x(); } class Foo implements A, B, C { Integer x() { //... } } 

and

2- the implementation should satisfy the casting proposals of all such methods that each superinterface has declared.

So, the examples you gave adhere to these rules and are great.

+1
source

Source: https://habr.com/ru/post/1438163/


All Articles