Two interfaces with same method names and signatures. But implemented by a single class then how the compiler will identify the which method is for which interface?
Ex:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
#Override
public int f() { // from which interface A or B
return 0;
}
}
If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics.
Compatibility example
Here's an example where you have an interface Gift, which has a present() method (as in, presenting gifts), and also an interface Guest, which also has a present() method (as in, the guest is present and not absent).
Presentable johnny is both a Gift and a Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
#Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
The above snippet compiles and runs.
Note that there is only one #Override necessary!!!. This is because Gift.present() and Guest.present() are "#Override-equivalent" (JLS 8.4.2).
Thus, johnny only has one implementation of present(), and it doesn't matter how you treat johnny, whether as a Gift or as a Guest, there is only one method to invoke.
Incompatibility example
Here's an example where the two inherited methods are NOT #Override-equivalent:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
This further reiterates that inheriting members from an interface must obey the general rule of member declarations. Here we have Gift and Guest define present() with incompatible return types: one void the other boolean. For the same reason that you can't an void present() and a boolean present() in one type, this example results in a compilation error.
Summary
You can inherit methods that are #Override-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE #Override-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.
The compiler does not have to identify which method is for which interface, because once they are determined to be #Override-equivalent, they're the same method.
Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.
References
JLS 8.4.2 Method Signature
JLS 8.4.8 Inheritance, Overriding, and Hiding
JLS 8.4.8.3 Requirements in Overriding and Hiding
JLS 8.4.8.4 Inheriting Methods with Override-Equivalent Signatures
"It is possible for a class to inherit multiple methods with override-equivalent signatures."
This was marked as a duplicate to this question https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java
You need Java 8 to get a multiple inheritance problem, but it is still not a diamon problem as such.
interface A {
default void hi() { System.out.println("A"); }
}
interface B {
default void hi() { System.out.println("B"); }
}
class AB implements A, B { // won't compile
}
new AB().hi(); // won't compile.
As JB Nizet comments you can fix this my overriding.
class AB implements A, B {
public void hi() { A.super.hi(); }
}
However, you don't have a problem with
interface D extends A { }
interface E extends A { }
interface F extends A {
default void hi() { System.out.println("F"); }
}
class DE implement D, E { }
new DE().hi(); // prints A
class DEF implement D, E, F { }
new DEF().hi(); // prints F as it is closer in the heirarchy than A.
As far as the compiler is concerned, those two methods are identical. There will be one implementation of both.
This isn't a problem if the two methods are effectively identical, in that they should have the same implementation. If they are contractually different (as per the documentation for each interface), you'll be in trouble.
There is nothing to identify. Interfaces only proscribe a method name and signature. If both interfaces have a method of exactly the same name and signature, the implementing class can implement both interface methods with a single concrete method.
However, if the semantic contracts of the two interface method are contradicting, you've pretty much lost; you cannot implement both interfaces in a single class then.
Well if they are both the same it doesn't matter. It implements both of them with a single concrete method per interface method.
As in interface,we are just declaring methods,concrete class which implements these both interfaces understands is that there is only one method(as you described both have same name in return type). so there should not be an issue with it.You will be able to define that method in concrete class.
But when two interface have a method with the same name but different return type and you implement two methods in concrete class:
Please look at below code:
public interface InterfaceA {
public void print();
}
public interface InterfaceB {
public int print();
}
public class ClassAB implements InterfaceA, InterfaceB {
public void print()
{
System.out.println("Inside InterfaceA");
}
public int print()
{
System.out.println("Inside InterfaceB");
return 5;
}
}
when compiler gets method "public void print()" it first looks in InterfaceA and it gets it.But still it gives compile time error that return type is not compatible with method of InterfaceB.
So it goes haywire for compiler.
In this way, you will not be able to implement two interface having a method of same name but different return type.
Try implementing the interface as anonymous.
public class MyClass extends MySuperClass implements MyInterface{
MyInterface myInterface = new MyInterface(){
/* Overrided method from interface */
#override
public void method1(){
}
};
/* Overrided method from superclass*/
#override
public void method1(){
}
}
The following two approaches can also be taken to implement both the duplicate methods and avoid ambiguity -
APPROACH 1:
App.java -
public class App {
public static void main(String[] args) {
TestInterface1 testInterface1 = new TestInterface1();
TestInterface2 testInterface2 = new TestInterface2();
testInterface1.draw();
testInterface2.draw();
}
}
TestInterface1.java -
public class TestInterface1 implements Circle {
}
TestInterface2.java -
public class TestInterface2 implements Rectangle {
}
Circle.java -
public interface Circle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java -
public interface Rectangle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java -
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
Output -
Drawing circle
Drawing rectangle
APPROACH 2:
App.java -
public class App {
public static void main(String[] args) {
Circle circle = new Circle() {
};
Rectangle rectangle = new Rectangle() {
};
circle.draw();
rectangle.draw();
}
}
Circle.java -
public interface Circle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java -
public interface Rectangle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java -
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
Output -
Drawing circle
Drawing rectangle
I have an abstract super class A with a method doSomething(). A sub-class of A must implement doSomething(), but there is also some common code that should be called every time a subclass calls doSomething(). I know this could be achieved thus:
public class A {
public void doSomething() {
// Things that every sub-class should do
}
}
public class B extends A {
public void doSomething() {
super.doSomething();
// Doing class-B-specific stuff here
...
}
}
There seem to be three issues with this, though:
The method signatures have to match, but I might want to return something in the sub-class methods only, but not in the super-class
If I make A.doSomething() abstract, I can't provide a (common) implementation in A. If I don't make it abstract, I can't force sub-class to implement it.
If I use a different method to provide the common functionality, I can't enforce that B.doSomething() calls that common method.
Any ideas how the methods should be implemented?
What about the following?
public abstract class A {
protected abstract void __doSomething();
public void doSomething() {
// Things that every sub-class should do
__doSomething();
}
}
public class B extends A {
protected void __doSomething() {
// Doing class-B-specific stuff here
...
}
}
The first bullet point however is not so clear. The signature can't match if you want to return something different.
add call back to doSomething()
public class A {
public void doSomething() {
// Things that every sub-class should do
doSomethingMore()
}
}
protected abstract void doSomethingMore()
so all subclusses will have to ipmelment doSomethingMore() with additional actions but external classes will call public doSomething()
For first point alone - you can consider the below answer and for enforcing subclass implementation it can be abstract but calling common code functionality can happen if the base class has some implementation.
Return type can be Object in Base Class and returning null. In SubClass the specific return type can be put as given below.
public class InheritanceTutorial {
static class Base{
public Object doSomething(){
System.out.println("parent dosomething");
return null;
}
}
static class SubClass extends Base{
public Integer doSomething(){
super.doSomething();
System.out.println("child dosomething");
return 0;
}
}
/**
* #param args
*/
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.doSomething();
}
}
I was reading Java SCJP book by Khalid A. Mughal (for JE6), and in topic 7.6 Interfaces and Page number 313, it is given that
A subinterface can override abstract method declarations from its superinterfaces. Overridden methods are not inherited.
I could not quite understand what "Overridden methods are not inherited." means. I tried to do this:
interface A
{
void abc();
}
interface B extends A
{
#Override
void abc();
}
interface C extends B
{
void abc();
}
And I did not get any error. What am I not understanding?
This simply means that overridden methods can have a slightly different signature than the superinterface's methods. For example:
public interface Foo {
Object doSomething(String input) throws IOException;
}
public interface Bar extends Foo {
#Override
String doSomething(String input);
}
As you can see, in the subinterface, I no longer throw a checked exception, and I guarantee that the returned object is a more specific type. The method that did throw a checked exception is not inherited, because it is overridden.
I don't have the context of the entire paragraph, but there's something else related that applies only to implementations and not interfaces, which is that if you override a method without explicitly calling super, the superclass's implementation won't occur.
For example, if I have:
public class Example {
public static class Foo {
public void printSomething() {
System.out.println("Foo");
}
}
public static class Bar extends Foo {
#Override
public void printSomething() {
System.out.println("Bar");
}
}
public static void main(String[] args) {
Bar bar = new Bar();
bar.printSomething();
}
}
This program will simply output:
Bar
but NOT Foo. If I add a call to super.printSomething(), then it will print both.
Below is my code. I have the abstract class Myabatract which has the method myMethod and I have a subclass MySubClass in which I have overridden the myMethod. In my client class
I have a method callMethod from which I want to directly call the myMethod of Myabatract class is this possible?
abstract class Myabatract {
public void myMethod() {
System.out.println("This is from Myabatract");
}
}
class MySubClass extends Myabatract {
public void myMethod() {
System.out.println("This is from MySubClass");
super.myMethod();
}
}
class Client{
public void callMethod(){
}
}
You can create an anonymous implementation of the abstract class. This is particularly easy given the fact that it does not use any abstract methods.
class Client {
public void callMethod() {
Myabatract instance = new Myabatract() { /* nothing to implement*/ };
instance.myMethod();
}
}
As a user of the MySubClass type, you have no way to call the Myabatract method because it has been overridden, unless MySubClass were to expose it. Your only recourse would be to create another method that exposed the super method from within MySubClass (or other child implementations).
It's important to note that this will not work:
class Client {
public void callMethod() {
MySubClass instance = new MySubClass() {
#Override
public void myMethod() {
super.myMethod();
}
};
instance.myMethod();
}
}
super is the non-anonymous class, MySubClass, which means nothing is actually changing. Interestingly, this can be worked around in C++ using the scope resolution operator (::).
It's also worth pointing out that you are calling super.myMethod() in your implementation of MySubClass, which does invoke the Myabatract method.
Lets say I have these two classes, one extending the other
public class Bar{
public void foo(){
}
}
public class FooBar extends Bar {
#Override
public void foo(){
super.foo(); //<-- Line in question
}
}
What I want to do is warn the user to call the super-class's method foo if they haven't in the override method, is this possible?
Or is there a way to know, using reflection that a method that overrides a method of its super-class calls the original method if I pass on the class type to the super?
for example:
public abstract class Bar{
public Bar(Class<? extends Bar> cls){
Object instance = getInstance();
if (!instance.getClass().equals(cls)) {
throw new EntityException("The instance given does not match the class given.");
}
//Find the method here if it has been overriden then throw an exception
//If the super method isn't being called in that method
}
public abstract Object getInstance();
public void foo(){
}
}
public class FooBar extends Bar {
public FooBar(){
super(FooBar.class);
}
#Override
public Object getInstance(){
return this;
}
#Override
public void foo(){
super.foo();
}
}
Maybe even an annotation I can put on the super method so it shows that it needs to be called?
EDIT
Note, its not the super class that needs to call the foo method, it would be someone calling the sub class's foo method, for example a database close method
I would even be happy with making the method "un-overrideable" if it came down to it, but would still like to give it a custom message.
Edit 2
This here is what I wanted in a way:
But it would still be nice to have the above, or even give them a custom message to do something else like, Cannot override the final method from Bar, please call it from your implementation of the method instead
EDIT: To answer the edited, question, which includes:
I would even be happy with making the method "un-overrideable"
... just make the method final. That will prevent subclasses from overriding it. From section 8.4.3.3 of the JLS:
A method can be declared final to prevent subclasses from overriding or hiding it.
It is a compile-time error to attempt to override or hide a final method.
To answer the original question, consider using the template method pattern instead:
public abstract class Bar {
public foo() {
// Do unconditional things...
...
// Now subclass-specific things
fooImpl();
}
protected void fooImpl();
}
public class FooBar extends Bar {
#Override protected void fooImpl() {
// ...
}
}
That doesn't force subclasses of FooBar to override fooImpl and call super.fooImpl() of course - but FooBar could do this by applying the same pattern again - making its own fooImpl implementation final, and introducing a new protected abstract method.
what you could do is something like following
public class Bar{
public final void foo(){
//do mandatory stuff
customizeFoo();
}
public void customizeFoo(){
}
}
public class FooBar extends Bar {
#Override
public void customizeFoo(){
//do custom suff
}
}
foo method made 'final' in superclass so that subclasses can't override and avoid doing mandatory stuff