Win a copy of Classic Computer Science Problems in Swift this week in the iOS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Why 'Object clone()' can not be overridden in a functional interface?  RSS feed

 
Ranch Hand
Posts: 118
1
Chrome IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following functional interface works since toString is implemented by Object class already.

But the following code does not. I am wondering why. Is it because the implementation of clone method is not included in the body of Object class?

At the location of @Override, IDE reports error saying "Method does not override method from it's superclass". And at the location of @FunctionalInterface, IDE reports error saying "Multiple non-overriding abstract methods found in interface functionalIterface"

 
Ranch Foreman
Posts: 486
12
Java Notepad
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This note in Java SE 8 Language Specification describes: https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8
 
Marshal
Posts: 58829
179
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Quazi Irfan wrote:. . . At the location of @Override . . . "Method does not override method from it's superclass".

Don't know. What I do know is that all interface methods are implicitly public (at least as far as Java8) and clone() has protected access, so it must be implemented as public so you must give your implementing classes a new implementation, so it isn't an abstract method. If I try to compile this sort of code:-I get this error message:-

. . . error: clone() in Object cannot implement clone() in functionalInterface
class Foo implements functionalInterface
^
  attempting to assign weaker access privileges; was public
1 error

And at the location of @FunctionalInterface, IDE reports error saying "Multiple non-overriding abstract methods found in interface functionalIterface"

Which IDE? Have you tried it on Eclipse? That sometimes gives you better error messages than NetBeans, which uses the standard Oracle compiler. I got exactly the same error messages from the command line with the Oracle compiler (JDK10.0.1)

  * * * * * * * * * * * * * * *

And I have remembered something, which comes up if I take the annotations out and compile your interfaceNotice what it says about “extends” and about “java.lang.Object”. That's right: nothing. Try javap -c on an ordinary class and see the difference. Interfaces don't extend Object. They only extend other interfaces if that is explicitly mentioned with an extends XXX clause. The reason @Override produces that error is that there is no superclass to have a clone() method. There is an exception made for the public methods from Object because all interfaces implicitly have those nine methods. You will find more information in the Java® Language Specification (=JLS). The JLS also explains why you cannot declare a method like void notify(); in any interfaces. You are impicitly overriding a final method.
 
Quazi Irfan
Ranch Hand
Posts: 118
1
Chrome IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, I think I've got it - Methods in Object class have different relationship with interfaces.

In the 1st code: Multiple abstract methods are allowed only if other methods are public methods from Object class. That's why the first code with toString() works.

In the 2nd code: clone() is not a public method of Object, therefore IntellijIDEA think it's a second abstract method in a functional interface, which is not allowed.

Am I right?
 
Prasad Saya
Ranch Foreman
Posts: 486
12
Java Notepad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Quazi Irfan wrote:Ok, I think I've got it - Methods in Object class have different relationship with interfaces.
In the 1st code: Multiple abstract methods are allowed only if other methods are public methods from Object class. That's why the first code with toString() works.
In the 2nd code: clone() is not a public method of Object, therefore IntellijIDEA think it's a second abstract method in a functional interface, which is not allowed.
Am I right?



Yes.

The methods Object class's clone() and finalize() are non-public methods. And, the remaining are public methods. Thats the difference!
 
Saloon Keeper
Posts: 8727
162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Quazi Irfan wrote:In the 2nd code: clone() is not a public method of Object, therefore IntellijIDEA think it's a second abstract method in a functional interface, which is not allowed.

Am I right?


Not exactly. The method is not abstract, it's just that you're trying to implement a public method declaration with a protected method. You can not lower visibility of a method.
 
Quazi Irfan
Ranch Hand
Posts: 118
1
Chrome IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:You can not lower visibility of a method.



Because of changing the visibility, IDE is considering it as a non-overridden method, right?
 
Campbell Ritchie
Marshal
Posts: 58829
179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Quazi Irfan wrote:. . . Because of changing the visibility, IDE is considering it as a non-overridden method, right?

No. Because of the lower visibility, it is regarded as a syntax error.
 
Campbell Ritchie
Marshal
Posts: 58829
179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I wasn't clear in my last post. Sorry.

Quazi Irfan wrote:. . . IDE is considering it as a non-overridden method, right?

Go back to the JLS section I posted yesterday. You will there find that interfaces don't have clone() and finalize() methods implicitly, so in the case of the interface, that is a new method, so it can't be considered to override aything. In the implementing classes, clone() and finalize() would have to be overridden specifically, otherwise it is a syntax error because they have protected visibility and they are claiming to implement a method inherited from the interface with public visibility.
 
Quazi Irfan
Ranch Hand
Posts: 118
1
Chrome IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am a bit confused. You said "Because of the lower visibility, it is regarded as a syntax error." But you also said "interfaces don't have clone() and finalize() methods implicitly". How come you lower the visibility of a method you do not have?

 
Campbell Ritchie
Marshal
Posts: 58829
179
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry; I wasn't clear, was I?

If you have a class Foo, it will have a clone() method. If Foo is supposed to implement some interface or other with clone() declared, that interface will have that method with public access. That makes clone() an abstract method and Foo must implement it with public access. Try compiling this code and see what happens:-As you will see, that becomes a compiler error because of the access modifier.
Did you read the JLS llink from Friday? The interface doesn't have an implicit clone() method to override.
 
Quazi Irfan
Ranch Hand
Posts: 118
1
Chrome IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:As you will see, that becomes a compiler error because of the access modifier.
Did you read the JLS llink from Friday? The interface doesn't have an implicit clone() method to override.



Yes I did it. But I think you don't show an implementation of the interface to answer my question. The simplest answer IMO is that unlike 'public String toString()', 'protected native Object clone()' is not visible in an interface and therefore @Override annotation can not resolve what method is being overridden. The functional interface would work if the annotation is removed.
 
Stephan van Hulst
Saloon Keeper
Posts: 8727
162
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, it wouldn't. If you leave @FunctionalInterface and remove @Override, you get this error message:
 
Quazi Irfan
Ranch Hand
Posts: 118
1
Chrome IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:No, it wouldn't. If you leave @FunctionalInterface and remove @Override, you get this error message:



Right, sorry I meant if the clone() is the only method in the functional interface.
 
Campbell Ritchie
Marshal
Posts: 58829
179
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that would be a functional interface, yes.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!