Interface Implicitly inherit the Object class. Because interface SubInterface default Method call the Objectclass hashCode Method. It's possible then How & Why..?
package com.oca.test.exam;
interface SuperInterface {
default void printStuff() { System.out.println("Default Method"); }
}
interface SubInterface extends SuperInterface {
default void doStuff() {
this.printStuff();
System.out.println(this.hashCode());
}
}
public class InterfaceAbstractCombination implements SubInterface{
public static void main(String[] args) {
SubInterface sub = new InterfaceAbstractCombination();
sub.doStuff();
}
}
The interface is not inheriting the Object clas. The class which implements the interface SubInterface is inheriting the Object class.
Just think about it, will you be able to call doStuff() of SubInterface directly? You need to implement that interface in another class, create an instance of that class then you can call doStuff().
So InterfaceAbstractCombination class implements the SubInterface and when you call doStuff() you calling it on the instance of InterfaceAbstractCombination which is supplying the this.hashCode() inherited from the Object class, so this will refer to the instance of the class implementing the interface.
One thing to note, If you check the JLS spec
If an interface has no direct superinterfaces, then the interface
implicitly declares a public abstract member method m with signature
s, return type r, and throws clause t corresponding to each public
instance method m with signature s, return type r, and throws clause t
declared in Object, unless a method with the same signature, same
return type, and a compatible throws clause is explicitly declared by
the interface.
So this is why you are able to call SuperInterface.super.hashCode();.
The hashCode of InterfaceAbstractCombination class is provided in your inheritance hierarchy. this does not belong to interface, even if it has default method.
Consider running below code you'll see same hashCode getting printed:
package com.oca.test.exam;
public class InterfaceAbstractCombination implements SubInterface {
public static void main(String[] args) {
SubInterface sub = new InterfaceAbstractCombination();
sub.doStuff();
System.out.println(sub.hashCode());
}
}
interface SuperInterface {
default void printStuff() {
System.out.println("Default Method");
}
}
interface SubInterface extends SuperInterface {
default void doStuff() {
this.printStuff();
System.out.println(this.hashCode());
}
}
Related
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.
Below example runs without any errors, can any one explain me how this works?, as interface doesn't contain any toString()/hashcode/equals method declaration how compiler will resolve method call?,as per my understanding toString()/hashcode/equals or Object class methods will be declared by default inside interface? please correct me if am wrong
interface int1
{
public void show();
}
class inttest implements int1
{
public void show()
{
System.out.println("inttest.show()");
}
#Override
public String toString()
{
return "tostring called";
}
}
public class MainClass1
{
public static void main(String[] args) {
int1 i=new inttest();
System.out.println(i.toString());
}
}
Any interface has all the public methods of the Object class (it either inherits them from a super-interface or declares them implicitly if it doesn't already declare them explicitly).
This makes sense, since any implementing class of any interface must be a (direct or in-direct) sub-class of the Object class, and therefore will inherit an implementation of all the Object methods.
9.2. Interface Members
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
As all objects extend Object and Object has a toString() you are calling that method.
I got the below info from Oracle docs:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
can someone tell me how an interface is able to implicitly declare public abstract methods to each and every public instance methods which are not-final avaliable in Object class ?
interface Test {
public void functionA();
}
class child implements Test{
public void functionA() {
}
public static void main(String[] args) {
Test test = new child();
test.toString(); // since toString is Objects class method, How it's visible for Test interface ref?
}
}
how an interface is able to implicitly declare public abstract methods to each and every public instance methods which are not-final avaliable in Object class ?
An interface isn't able to do this -- only a concrete object can. My guess is that you're looking at code that shows creation of an anonymous inner class from an interface and think that this is instantiation of the interface -- but it isn't. Rather it's a concrete class, one without a name, that implements the interface, and that extends from Object, as all concrete classes do.
And now I'm not so sure as this compiles:
public interface MyInterface {
void foo();
#Override
String toString();
#Override
boolean equals(Object o);
}
The correct answer may be: because that is how the authors of Java willed it to be.
How Interface have accessibility to Object class methods?
As always, the answer is in the JLS:
4.10.2. Subtyping among Class and Interface Types
Given a non-generic type declaration C, the direct supertypes of the type C are all of the following:
The direct superclass of C (§8.1.4).
The direct superinterfaces of C (§8.1.5).
The type Object, if C is an interface type with no direct superinterfaces (§9.1.3).
So the 3rd point answers your question. As a subtype of Object, the interface inherits its methods.
Note: this is true also for generic interfaces (explained in the rest of 4.10.2).
We know that each class extends from Object which means that we can use all Object's methods
in any class. My problem is the following:
interface B{
}
public class A implements B{
public static void main(String[] args){
B i = new A();
i.display();//we can't do this : because the interface B doesn't define such a method
System.out.println(i.toString());// we can do this although the interface doesn't extend from Object
}
public void display(){
}
}
so I think the problem is clear , why I could invoke the toString method although the interface B can't extend from Object?
This is spelled out in the JLS §9.2. Interface Members:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
This ensures that it is possible to call Object methods via any interface.
interface A {
void hi();
}
class AImpl implements A {
public void hi() {
System.out.println("hi");
}
public void to() {
System.out.println("Test");
}
}
public class InterfaceTest {
public static void main(String[] args) {
A a = new AImpl();
a.hi();
System.out.println(a.hashCode());
//a.to();
}
}
here interface A has no inheritance relationship with Object class but all the mehods of Object class can be access through the interface.
why?
From the Java Language Specification section 9.2:
The members of an interface are:
Those members declared in the interface.
Those members inherited from direct superinterfaces.
If an interface has no direct superinterfaces, then the interface implicitly declares a public
abstract member method m with
signature s, return type r, and throws
clause t corresponding to each public
instance method m with signature s,
return type r, and throws clause t
declared in Object, unless a method
with the same signature, same return
type, and a compatible throws clause
is explicitly declared by the
interface. It is a compile-time error
if the interface explicitly declares
such a method m in the case where m is
declared to be final in Object.
The third bullet is the important one - basically interfaces which don't extend any other interfaces automatically inherit hashCode etc.