Page 1 of 1

About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Wed Sep 06, 2017 7:21 am
by Javier
Hi there!

I would like to make sure the meaning of "this" keyword inside the interface like in this example:


interface Account{
public default void getId(){

}
}

interface PremiumAccount extends Account{
public default void getId(){ this.getId(); }}



is "this" refering to the interface (PremiumAccount) member getId() ?

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Wed Sep 06, 2017 7:26 am
by admin
"this" always refers to the the instance of the object on which the method has been invoked.
In this case, unless the class implementing PremiumAccount interface overrides the getId method sensibly, call to getId will be a recursive call and will result in a StackOverflowError.

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Mon Jan 07, 2019 5:11 pm
by crazymind

Code: Select all

interface A {    void hello() { } } 

public class TestClass implements A {    

      void hello{ System.out.println("hello");}

     public static void main(String [] args){
      
            A a = new TestClass();
            ((A) a).hello; 

    }

}
Is this possible? Since hello is an abstract method in A

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Mon Jan 07, 2019 9:53 pm
by admin
What happened when you tried it out?

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Tue Jan 12, 2021 8:36 am
by Denyo1986
When I read the question, I was super clear that class Bankaccount inherits the default method String getId() from interface Account and since interface only requires for its implementors( >> Bankaccount class) to have a method named String getId() everyone is satisfied.

What am I missing?
Why is that not the case? I went through all responses, did some research, ran the code.....cant find the answer to it, even though I see the outcome.
Any help is highly appreciated.

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Tue Jan 12, 2021 9:30 am
by admin
It is a rule of the Java language. If a class inherits an abstract method from its super class, then it doesn't get the default method having the same signature from an interface that it might implement. You may go through Section 8.4.8.4 Inheriting Methods with Override-Equivalent Signatures for a detailed discussion.

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Tue Jan 12, 2021 9:58 am
by Denyo1986
I read the link but still dont unterstand it.
I understand that if a class inherits two (non-abstract) methods with same signature then the compiler doesnt know which implementation to use > compiler-error. Clear.

here, though, the class inherits one implemented method and one "obligation" to have a method named "String getId()".
Since it inherits the default from account and fulfills the requirement from PremiumAccount to have this one method, I do not understand why this is not allowed. There are no conflicting implementations.

And in your explanation above you speak about class inheriting from its super class. That would be another case, as it would inherit an implementation (assuming the inherited method is not abstract). But here, in this question, the class only implements two interfaces and of the two method signatures it inherits, there is only one implementation and no conflict. What exactly does the compiler not like about it?

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Tue Jan 12, 2021 11:36 am
by admin
Yes, but PremiumAccount has made the getId(); abstract. It is not default anymore. So, when BankAccount implements PremiumAccount, it doesn't get the default getId implementation that is available in Account interface. Regarding why is it so, I am sorry, I do not have a definitive answer for that. Only the language designers can tell what exactly their reasoning was for this. To me, it seems quite intuitive. The subinterface has overridden the default method of its super interface as abstract, and so any class that implements the subinterface would not get the default implementation.

Re: About Question enthuware.ocajp.i.v8.2.1478 :

Posted: Tue Jan 12, 2021 1:00 pm
by Denyo1986
This helps me a lot, thank you.
When I read your response, I first thought it's because of the relationship between the interfaces (one extends the other) that the default method first gets overridden by the abstract method of the super-interface but I tried with two interfaces that are not related and its the same result.

So the conclusion is that whenever a method is declared abstract by an interface], any default methods of other interfaces with same signature get overridden by this abstract method and its mandatory for the implementing class to provide an own implementation.

However, when an abstract class provides a default method with implementation and an interface defines an abstract method with the same signature, then the case is different. Here the subclass inherits the implementation of the superclass and does not need to provide an own implementation as shown in the following example (no compiler or runtime errors):

Code: Select all

abstract class Account
{
    public String getId()
    {
        return "0000";
    }
}

interface PremiumAccount 
{
     public String getId();
}

class BankAccount extends Account implements PremiumAccount
{
    public static void main(String[] args)
    {
        Account acct = new BankAccount();
        System.out.println(acct.getId());
    }
}

That was new to me.
Thanks for helping me to get my head around it.