Overriding Object class methods within an interface in Java - java

Let's consider the following simple code in Java.
package temppkg;
interface Interface
{
#Override
public abstract boolean equals(java.lang.Object arg);
#Override
public abstract String toString();
public void show();
}
final class Demo implements Interface
{
public void show()
{
System.out.println("Method invoked.");
}
}
final public class Main
{
public static void main(String...args)
{
new Demo().show();
}
}
In the above code snippet, the interface named Interface has some Object class methods from JDK and they are with the #Override annotation even though they are abstract. Now, the class Demo has implemented Interface and has not implemented the equals() and the toString(); methods. Still the compiler doesn't complain and the program is running successfully. Why?
What is the relation between interfaces and the object class in Java?

The Java Language Specification clearly says that the members of an
interface are those which are declared in the interface and those
which are inherited from direct super interfaces. If an interface has
no direct superinterface then the interface implicitly declares a
public abstract member method corresponding to each public instance
method declared in the Object class, unless a method with the same
signature, same return type, and a compatible throws clause is
explicitly declared by that interface. This is what makes the
signatures of the Object methods available to the compiler and the
code compiles without any error. Remember if the interface tries to
declare a public instance method declared 'final' in the Object class
then it'll result into a compile-time error. For example, 'public
final Class getClass()' is a public instance method declared 'final'
in the Object class and therefore if an interface tries to declare a
method with this signature then the compilation will fail.
http://geekexplains.blogspot.com/2008/06/do-interfaces-really-inherit-from-class.html

Check out JLS 9.2:
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.
In other words, every interface implicitly defines each of Object's methods, and you can therefore #Override those methods. The other methods aren't defined in Object, so you can't override them.

In Interface you're not actually overriding anything - an interface by definition can not provide implementations for any of its methods. The class Demo just inherits the equals and toString implementation from Object.
In essence an interface in Java contains a set of zero or more method signatures (all of them are implicitly abstract, in your code you made it explicit by adding the keyword abstract), and the concrete classes that implement the interface must provide an implementation for those methods. In the case of your code, that implementation comes from Object, since all the classes implicitly extend Object, which provides default implementations for equals and toString (among other methods).
You really shouldn't mark the methods in an interface with #Override, as you have seen, it's confusing and serves for no practical purpose. Instead, use #Override in the methods in the concrete class that implement the methods of the interface, like this:
class Demo implements Interface {
#Override
public void show() {
System.out.println("Method invoked.");
}
}
Also, it's completely unnecessary to declare equals and toString in an interface, so you're better off with this definition:
interface Interface {
public void show();
}

#Override can only be used for functions defined in the base class, Object. Object defines equals and toString, so you can use #Override with them, but not with, say, the function show. It indicates a relationship between the #Override functions in a class and its base classes, not it's derived classes.

Related

Error in java at adding methods

I read that you can add extra methods for an object, or override the abstract methods in this way, yet I have an error. Can you tell me if this is even possible or what I have done wrong?
public abstract class Pesti {
public abstract void ud();
}
public class EX2 {
public static void main(String[] args) {
Pesti p = new Pesti() {
public void ud() {
System.out.println("Pestele este ud!");
}
public void inn() {
System.out.println("Innoata!");
}
};
p.ud();
p.inn();
}
}
It tells me that it cannot find method inn.
What you are doing is creating an anonymous sub-class of your Pesti. However, since your p variable is of type Pesti, you can only call methods declared in the Pesti class (or any of its super-classes). Therefore you can call ud(), but not inn().
If you could cast p to the type of the sub-class, you could have called inn(), but since this is an anonymous sub-class instance, you can't cast to that type.
You could declare inn() as an abstract (or concrete) method in Pesti. Then your code would pass compilation, and the implementation of this method in the anonymous sub-class instance will be executed.
public abstract class Pesti {
public abstract void ud();
public abstract void inn();
}
You declared p as an instance of Pesti, but tried to use a method not defined in Pesti. When you declare your object as the abstract class you can only use the methods defined in this class. To use your inn() method you have to declare this method in the Pesti class as well. Alternativly you can write a class extending Pesti which implements the inn() method and declare your object as the extending class.
Pesti is an abstract class with exactly one method (which is abstract): ud(). As such, a variable declared with the type Pesti can only be used to call ud() or any method from the class Object (Pesti's implicit superclass). p is declared with this type, so despite actually being an instance of an anonymous class with the method inn(), this method is not available in the context of having a variable of declared type Pesti.
Perhaps you intended to add the inn() method to Pesti so all instances must implement it:
public abstract class Pesti {
public abstract void ud();
public abstract void inn();
}
Or perhaps you don't really want to use anonymous classes at all and want to create a subclass of Pesti with the inn() method available:
public class PestiImpl extends Pesti {
#Override
public void ud() {
System.out.println("Pestele este ud!");
}
public void inn() {
System.out.println("Innoata!");
}
}
(or you could have a layer of inheritance between the two; some abstract class extending Pesti with inn() declared as an abstract method, if you have other classes like this with the inn() method but some Pestis without).
Side note: I strongly recommend using the #Override annotation where appropriate to make your code more readable and to avoid mistakes like typos when trying to override a method. You can get most IDEs to insert it automatically.
Think you need to look at this link, I don't know what do you want to do , but you can't instantiate abstract class, you can find detailed description in my link, hope it'll help you

How Interface have accessibility to Object class methods?

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).

How it is possible to call methods of Object class on a reference of Interface type?

interface TestInterface{
public void sayHello();
}
class A implements TestInterface{
public void sayHello(){
System.out.println("Hello");
}
public void sayBye(){
System.out.println("Hello");
}
public String toString(){
return "Hello";
}
public static void main(String args[]){
TestInterface ti=new A();
ti.sayHello();
ti.sayBye();//error
ti.toString();//How toString method can be called as it is not the part of the interface contract.
}
}
From this section in the Java Language Specification:
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.
So Object's public methods like toString are implicitly declared in all interfaces.
toString can be called because any implementation of any interface must be a sub-class of Object, which contains the toString method.
In order to call any other method that doesn't appear in the interface or in any super-interface your interface extends (and is not defined in Object class), you must cast the interface to the type of the class that contains that method.
Every object is an Object :) It would make sense to call Object methods on objects.
That's the heart of the matter - all reference types are subtypes of Object. Reference types include
class type
interface type
array type
type variable (T)
null type (for null)
intersection type ( A&B )
A subtype inherits methods from the supertype. Therefore all reference types inherit Object methods.
This is the nature of OO Languages. Interfaces only define a set of method signatures that a concrete class needs to implements. They don't restrict the nature of the class (abstract v concrete).
So when you declare TestInterface ti, in your example A implements TestInterface, so it is an instance of TestInterface. Likewise class B implements TestInterface {...} is also valid.
TestInterface ti = new A(); // Valid
ti = new B(); // Also valid (given the above definition)

Interface does not see concrete implementation

I have
ISomeInterface
public interface ISomeInterface{
public void myMethod();
}
AbstractClass
public abstract class AbstractClass implements ISomeInterface{
public void myMethod(){
//...here goes implemetations
}
}
ConcreteClass
public class ConcreteClass extends AbstractClass {
//...
}
Compiler prints than ConcreteClass is not abstract and does not override abstract method myMethod in ISomeInterface.
The idea is to give implementation to one abstract class and then inherit it in classes that extend it.
I think that ConcreteClass should gets implementation form AbstractClass since it's extending it. Right? What's the matter?
UPDATE
I haven't noticed until now that method is wrong and it has to be myMethod. Anyways, same error.
UPDATE2
The problem was that in AbstractClass them method had correct name but incorrect signature. After changing it according with interface the problem was solved :)
In AbstractClass you are creating a method myMethod(), but your interface method method() is not being implemented in ConcreteClass. The names are different.
Assuming that your sample code is complete, you need to implement method from your interface. In AbstractClass you have called it myMethod instead.
You can use the #Override annotation on any override methods. This will tell you if you have used the wrong parameter types, method name, or an incompatible return type (parameters and return types don't have to be the same; they can, for example, be covariant).
Additionally, in Java, we don't tend to prefix interface names with I (unlike the convention in C#). Your interface would usually be called SomeInterface and not ISomeInterface.
Also, the public on methods on interfaces is implicit, so you can leave it out. If you do include it you should probably include the abstract as well to include all of the implicit modifiers.
An updated code sample would be:
public interface SomeInterface{
void method();
}
public abstract class AbstractClass implements SomeInterface {
#Override
public void method(){
//...here goes implemetations
}
}
You are probably overriding the wrong method. What happens is that you are probably attempting to override a method in your abstract class but what you are actually doing is to just define a new method with a new name. In the interface, the method is named method but in your abstract class your method is named myMethod.
So, check this out:
public abstract class AbstractClass implements ISomeInterface{
// Not the same name as in the interface
public void myMethod(){
//...here goes implemetations
}
}
In order to solve it, simply change the method name in the subclass to the correct name.
public abstract class AbstractClass implements ISomeInterface{
// Now you have the correct name and inheritance will
// work as expected
#Override
public void method(){
//...here goes implemetations
}
}
This is the perfect case for explaining the #Override annotation as well ;)
When overriding a method, you might want to use the #Override annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, then it will generate an error.
When you declare a method with the annotation #Override the overridden method must match the signature of the interface-method (or superclass method). Read more about #Override in the Oracle Docs.
And, if you are not trying to override the method named method in your abstract class you simply need to add that method to your concrete class like this:
public class ConcreteClass extends AbstractClass {
// Now we are implementing the correct method from the interface
// If not, there will be a compiler error.
#Override
public void method() {
}
//...
}
On a side note which may be relevant: methods can have the same name but with different argument lists. This is known as overloading (or overloaded methods) which you can read more about in this article.
Edit: Since the OP is using Java 5 this question may be interesting. The #Override annotation changed between Java 5 and Java 6. In Java 5 it was not allowed to use the #Override annotation when implementing a method from an interface, it was just allowed when overriding a method from a superclass.
Your interface defines
public void method();
but your abstract class has
public void myMethod(){
//...here goes implemetations
}
Which isn't the same! Add the Override annotation to catch that kind of issue at compile time.
#Override
public void myMethod(){ // <-- compile error.
//...here goes implemetations
}
From the linked Javadoc,
Indicates that a method declaration is intended to override a method declaration in a supertype.
Well the first thing that I notice is that your method is not named the same thing in the interface and the abstract class.

Accessing the java Object class methods using an interface reference

Let's consider the following example.
public interface SimpleInterface {
public void simpleMethod();
}
public class SimpleClass implements SimpleInterface{
public static void main(String[] args) {
SimpleInterface iRef = new SimpleClass();
SimpleClass cRef = new SimpleClass();
iRef.simpleMethod(); // Allowed. Calling methods defined in interface via interface reference.
cRef.specificMethod(); // Allowed. Calling class specific method via class reference.
iRef.specificMethod(); // Not allowed. Calling class specific method via interface reference.
iRef.notify(); // Allowed????
}
public void specificMethod(){}
#Override
public void simpleMethod() {}
}
I thought, in Java using interface reference we may access only methods that are defined in this interface. But, it seems that it is allowed to access method of class Object via any interface reference. My concrete class "SimpleClass" inherits all the methods that class Object has and definitely the class Object doesn't implement any interface (one would assume that Object implements some interface with methods like notify, wait and etc.). My question is, why it is allowed to access methods of the class Object via interface reference, taking into consideration that other methods in my concrete class are not allowed?
why it is allowed to access methods of the class Object via interface reference
You can invoke the Object class methods using an interface reference although an interface doesn't extend from Object class, because every root interface in Java has implicit declaration of method corresponding to each method of Object class.
JLS §9.2 - Interface members:
The members of an interface are:
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.
This is because Java ensure that any class which has implemented the X interface is definitely is a Object class too, so this is possible to call the wait(), notify() and other Object guys.

Categories

Resources