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.
Related
I have these interface and classes:
public interface AlternateLight {
public String change(long time);
}
public abstract class AbstractLight {
public String change(int time) {
return "AbstractLight Method was used";
}
}
public class DistinctAlternateLight extends AbstractLight implements AlternateLight {
public String change(long time) {
return "DistinctAlternateLight Method was used";
}
}
Now I call the method change() with following main-method:
public class WhatUsedTest {
public static void main(String[] args) {
AlternateLight al = new DistinctAlternateLight();
System.out.println(al.change(100));
}
}
It prints "DistinctAlternateLight Method was used", but why? I thought since I didn't put a "L" behind the 100 as argument, it would call the method of the abstract class, because its method takes integers. With missing out on the "L", I guessed the compiler wouldn't handle the 100 as a long value and call the method taking longs, but it does. Why is that so?
It's due to the polymorphism, if you declare your variable with AlternateLight class and this type has only acces to change(long time).
be careful. If you use interface as reference type and assign an object of implementing class to it then you can call only those methods that are declared inside the interface. This is quite obvious because the implementing class can define methods of its own that are not a part of the contract between the interface and class. So, to call those methods you have to use the class as reference type as following:
DistinctAlternateLight al =new DistinctAlternateLight();
The method with the closest match to your type arguments will be used.
But for compatible numerical, the deepest declared one.
You can also see that the type of "al" object is an interface type, so you can`t call the method from super class without casting, you also can`t call any method from AbstractLight without casting. You can only call methods there were declared in interface class. In that case, compiler will favour the method from the interface class.
You can force the compiler to call a method from abstract class if you write something like that:
System.out.println(((AbstractLight)al).change(100));
I have parent and child classes in which the parent class has a method- getData. I can call this method directly from the child class with or without creating an object.
I am wondering how does the method become available in child class without creating an object. (It is not static method either)
It was my understanding that we have to create an object to access the methods. Can anyone please explain why?
public class testbase {
public void getData(String Data) throws IOException{
Properties prop1;
prop1= new Properties();
FileInputStream f= new FileInputStream("C:\\file.properties");
prop1.load(f);
String data= prop1.getProperty(Data);
System.out.println(data);
}
}
class testproperties_file extends testbase {
#Test
public void test_class() throws IOException{
getData("name");
}
}
I am wondering how can the method gets available in child class
without creating an object.
class testproperties_file extends testbase {
#Test
public void test_class() throws IOException{
getData("name");
}
}
Here test_class() is an instance method. It means that all code invoked in this method may invoked methods available for an instance of the current class (here testproperties_file). So, you are already in a object when this method is executing.
A instance of testproperties_file inherits from the testbase class.
It means that all public and protected instance methods of testbase may be invoked here. The public getData() instance method of testbase is so callable.
As a side note you should use uppercase and camelcase to name your class.
TestBase and TestPropertiesFile are better as they follow the java coding convention.
As per
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
A subclass inherits all the members (fields,methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.
I would suggest you to read more abour inheritance
Sub child inherits all the member methods from its super class.
If execution control reaches any non static method , it implies there is an object created and upon it that method is being invoked. this is the implicit reference to the currently executing object upon which any method is invoked. As the object of derived class has the behaviour of super class, then more behaviours gets added as per the defination of actual derived class and also if any behaviour is overriden then the behaviour derieved from super class gets modified.
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).
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)
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.