Default implementations VS inherited methods in Java 8 - java

In Java 8 we were introduced to a feature called "Default Methods"
How does Java behave when i try this:
An Interface that has an implementation of doStuff
public interface MyInterface {
default void doStuff() {
System.out.println("MyInterface ");
};
}
And an abstract class that has an implementation of doStuff
public abstract class MyAbstract {
public void doStuff() {
System.out.println("MyAbstract ");
};
}
And a class that extends the abstract class and implements my interface:
public class MyClass extends MyAbstract implements MyInterface {
//this can just be empty
}
Does this even compile? If so, what will be printed when:
new MyClass().doStuff();

Does this even compile?
Yes
If so, what will be printed when... ?
It will print MyAbstract
How does Java behave when I try this:
If the function is not implemented in your class/its parent class, then and only then the default method will be executed. Comment out the method doStuff() in abstract class and then you have MyInterface printed out. This way, if someone adds a default method to an interface that you had already implemented with the same method name of a method in your class/parent class, your implementation is not broken

Related

Implementing and extending, Interface and Abstract class respectively with same method name in java

I am trying to understand how default methods deal with diamond problem in various scenarios. And, this is one of the scenario which I'm not able to understand.
Following is the description,
1. Interface with a default method method()
2. Abstract Class with a method method()
3. Concrete Class implementing the above interface and extending the abstract class.
interface Interface {
default void method() {
System.out.println("Interface method");
}
}
abstract class AbstractClass {
void method() {
System.out.println("Abstract class method");
}
}
// Concrete class definition first starts
public class ConcreteClass extends AbstractClass implements Interface {
#Override
public void method() {
super.method();
}
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition first ends
// Concrete class definition Second starts
public class ConcreteClass extends AbstractClass implements Interface {
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition Second ends
My queries,
1. Why does definition first always gives output as "Abstract class method" even when I use the Interface type for concrete class object?
2. Why definition second doesn't compile?
If compiler is using abstract class implementation in definition first, then it should be able to identify that it will always use Abstract class implementation in definition second.
This behavior is very confusing to me and any help is greatly appreciated.
Otherwise, the more I delve deeper into this, the more confusing it gets.
Edit 1 :
Compilation error in second definition is "The inherited method AbstractClass.method() cannot hide the public abstract method in Interface"
Default methods are just that: defaults. If there is an implementation, it will be used. If there isn't, the default will be used. There is no diamond problem here (there can be with multiple defaults, however).
1) Dynamic dispatch
2) The abstract class gives the method named method package-private access; the interface demands it be public.

Does abstract class hide or override the method of the interface?

I am studying for OCA and I try to find answer for every question I encounter in my head.
This is the code:
interface InterfaceA {
public default Number method(){
return 5;
}
}
abstract class AbstractB {
public Long method() {
return 3L;
}
}
public class Foo extends AbstractB implements InterfaceA {
public static void main(String[] args) {
System.out.println(new Foo().method());
}
}
}
In this situation I don't have to override in the class Foo.
I know if I implement 2 interfaces with same methods I have to explicitly override in the class Foo. In the example above I get the result from AbstractB (3). My question: is abstract class implicitly overriding or hiding the method from the interface? What is the reason that class Foo prints the result from AbstractB and not from InterfaceA?
Abstract classes implement methods from interfaces. This does not count as an override, because there is no base method to override. In other words, if you try to do this
abstract class AbstractB {
public Long method() {
return super.method(); // <<==== Does not compile!
}
}
the call to base class method() would not compile.
Hiding does not apply either, because only static methods in Java can be hidden.
why class Foo gets the result from his parent class and not from interface?
Because interface provides a default implementation, i.e. what you get when there's nothing else provided in the line of inheritance. In this case, abstract base class provides an implementation, so it "wins" over the default implementation from the interface.
in this specific case the call to println prints 3 because AbstractB implements the method method of the interface InterfaceA in which case the class Foo inherits this bevahior. However, had AbstractB not implemented the interface method the println call would delegate to the default method of InterfaceA. Lastly, to answer your question AbstractB does not hide the method of the interface rather implements it as it has the same signature as the method in InterfaceA.

JAVA - define a method in interface

I would like to define a method in JAVA interface. The reason is that every time I implement interface the method is the same, but I need to implement two interfaces for particular classes. Example:
interface A
method A()
interface B
method B()
class first implements A,B
class second implements A
method A() has same body everywhere.
As of Java 8, you can put method implementations into interfaces.
http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
interface A {
default void aMethod() {
// method body
}
}
In earlier versions, you would have to make A a class instead of an interface. An abstract class if that suits your model better.
abstract class A {
public void aMethod() {
// method body
}
}
class first extends A implements B {
...
}

Partial interface implementation when you cannot extend a abstract class in java

Suppose I have an interface which has 3 methods. This interface is to be implemented by many classes but the implementation of say method1 will be same in all classes.
I can make an abstract class and give a concrete implementation for method1 and let my classes extend this class.
My question is when I am already extending a class, how do I also extend this abstract class. Java doesn't support it. How should I design in such a scenario?
interface Inf{
void method1();
void method2();
void method3();
}
public abstract class Abs implements Inf{
void method1(){
//concrete implementation
}
}
class Test extends SomeClass implements Inf{
//here I need method1 implementation and other methods Ill implement
}
class SomeClass{
}
With java 8, you can define default implementation of a method inside the interface.
public interface A {
default void method1() { System.out.println("Default method1 implementation"); }
void method2();
void method3();
}
Java doesn't support Multiple Inheritance. i.e A Class cannot have more than one Base class. What you can do is make the SomeClass to extend Abs class
class SomeClass extends Abs{
}
class Test extends SomeClass implements Inf{
//here you can get method1 implementation since Someclass extends Abs
}
Note : As said by #anonymous , you can make use of default methods of interface if you work in Java 8
Java doesn't support multiple inheritance.
You can make your Abs class to extend SomeClass
class Abs extends SomeClass {
}
class Test extends Abs implements Inf {
}

Same method in Interface and Abstract class

I came to situation :
public interface Intr {
public void m1();
}
public abstract class Abs {
public void m1() {
System.out.println("Abs.m1()");
}
// public abstract void m1();
}
public class A extends Abs implements Intr {
#Override
public void m1() {
// which method am I overriding, well it is Abs.m1() but why?
// if method implemented is Abs.m1(), then why I am not getting error for Intr.m1() not implemented.
}
}
You are satisfying both conditions at once; ie. the one implementation is at the same time fulfilling the abstract class requirements and the interface requirements.
As a note, unless you are using Intr in another inheritance chain, you don't need it. Also, it might make sense to move the implements Intr up to the abstract class definition.
You can only override methods defined in another class.
Methods declared in an interface are merely implemented. This distinction exists in Java to tackle the problem of multiple inheritance. A class can only extend one parent class, therefore any calls to super will be resolved without ambiguity. Classes however can implement several interfaces, which can all declare the same method. It's best to think of interfaces as a list of "must have"s: to qualify as a Comparable your cluss must have a compareTo() method but it doesn't matter where it came from or what other interfaces require that same method.
So technically you override Abs.m1() and implement Intr.m1() in one fell swoop.
Note that this would be fine too:
public class B extends Abs implements Intr {
//m1() is inherited from Abs, so there's no need to override it to satisfy the interface
}
Here, both the interface and abstract class have the same method.
You have one class with named Derived which extends an abstract class and implement an interface. It's true and you override print method on Derived class it's fine and it compiles correctly and does not give any error but here you can't identify which class method is overridden like abstract class or interface.
This is runtime polymorphism you can't create an instance of an abstract class or interface but you can create a reference variable of that type. Here the solution is you can't identify that on compile-time it's actually overridden at run time.
interface AnInterface
{
public void print();
}
abstract class Base
{
public abstract void print();
}
public class Derived extends Base implements AnInterface
{
public void print(){
System.out.println("hello");
}
AnInterface iRef = new Derived();
iRef.print(); // It means interface method is overridden and it's decided when we call the method.
Base base = new Derived();
base.print(); // It means abstract class method is overridden.
}
#Override ensures you override the method with no difference Interface or abstract superclass. So no error with override.
On the other hand Interface method is also implemented in the superclass which is enough for Interface contracts.

Categories

Resources