This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Do interfaces inherit from Object class in java
package inheritance;
class A{
public String display(){
return "This is A!";
}
}
interface Workable{
public String work();
}
class B extends A implements Workable{
public String work(){
return "B is working!";
}
}
public class TestInterfaceObject{
public static void main(String... args){
B obj=new B();
Workable w=obj;
//System.out.println(w.work());
//invoking work method on Workable type reference
System.out.println(w.display());
//invoking display method on Workable type reference
//System.out.println(w.hashCode());
// invoking Object's hashCode method on Workable type reference
}
}
As we know that methods which can be invoked depend upon the type of the reference variable on which we are going to invoke. Here, in the code, work() method was invoked on "w" reference (which is Workable type) so method invoking will compile successfully. Then, display() method is invoked on "w" which yields a compilation error which says display method was not found, quite obvious as Workable doesn't know about it. Then we try to invoke the Object class's method i.e. hashCode() which yields a successful compilation and execution. How is it possible? Any logical explanation?
The intuitive answer is that regardless of what interface you refer to, the object implementing the interface must be a subclass of Object.
Section 9.2 of the JLS specifically defines this behaviour: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#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.
i.e. all interfaces are assumed to contain method signatures corresponding to methods in the Object class.
I think what's happening here is that even though w is known only to be Workable, all objects must derive from Object, so no matter what class w eventually is, it must have the Object methods.
The reason w.display() doesnt work is as you have save the reference as your interface type. The compiler only sees the methods exposed by the interface. If you were to call ((B)w).display() this would work. You are able to call hashCode() as the compiler is smart enough to know that interfaces are inherited by Objects and all object's superclass is Object
Related
I am new in Functional Interface and today i am learning from few of tutorial sites. I have a question plz provide your suggestions and guide me.
Below mentioned code have an question for me.
#FunctionalInterface
interface Demo {
Object clone(); // protected
//int hashCode(); // public
//boolean equals(Object c); // public
//public void wait(); // final so we cannot override this one.
}
Object class is parent for all java classes.
Here wait() method says not overrided because this one is final. So it means Demo interface also child of Object class (in general terms).
> #FunctionalInterface means interface with exact one method declaration.
Question: So, Now code is working when Object clone(); method is not commented. So means this method is declared in interface Demo. But when we click on its implementation we move on Object class's clone() method.
When we comment clone() method and un-comment equals() method, then we get compile time error, interface is not FunctionalInterface. Why ?????? and why its functional interface with clone() method.
Please don't say clone() is protected, what's the matter if clone is protected in Object class. Please explain for me.
Thanks,
sawai
It's because clone() is protected. I know you asked me not to say that, but I'm going to say it anyway because it's the answer.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8 specifically says:
For an interface I, let M be the set of abstract methods that are
members of I that do not have the same signature as any public
instance method of the class Object. Then, I is a functional interface
if there exists a method m in M for which both of the following are
true:
The signature of m is a subsignature (§8.4.2) of every method's
signature in M.
m is return-type-substitutable (§8.4.5) for every method in M.
Note that it says public instance. When you've uncommented clone(), this is a method that does not have the same signature as a public instance method, because clone() in Object is a protected instance method. Thus, your clone() method will satisfy the conditions. You can't say the same about equals(), since equals() is a public instance method in Object. That means that the set M referred to by this rule is empty, and therefore the method m that must be in this set cannot exist.
There's a comment in the JLS a couple paragraphs down which explains why they decided to treat clone() differently.
Since public boolean equals(Object c) already exists in Object, Demo doesn't declare any new method. To be a FunctionalInterface, it should declare only one method.
When instead you declare public Object clone(), it is a new method because the original one in Object is protected. Therefore it can be considered as a FunctionalInterface.
I'm new to Java Programming and learning polymorphism.
__EDIT__
As per the answers I received from everyone,I have code:
Here I'm typecasting my Derived object (obj) to Base type and then calling method().
public class Tester {
public static void main(String[] args) {
Base obj=(Base)new Derived();
obj.method();
}
}
class Base{
public void method(){
System.out.println("In Base");
}
}
class Derived extends Base{
public void method(){
System.out.println("In Derived");
}
}
Output I'm getting is: "In Derived".
So after typecasting my object should become of type Base referenced by Base type.
But it's not happening? Why?
Does typecast work on child->parent conversion or it has no effect here?
Base obj=new Derived();
In the above statement, the reference part points to type Base. This is how the compiler identifies which class to consider. But your code will create an error. Let me explain the structure of the above statement before explaining why will it show an error.
Structure of the above statement:
Declaration-The reference part is Base obj.
Instantiation: The new keyword is a Java operator that creates the object/allocates space in the memory.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Since, Derived is a sub-class of Base, you are allowed to call the constructor in the Derived class. This is how inheritance and polymorphism works.
Okay, Now let us go back to the error part.
The obj.method() in your code is looking for a function method() in Base class but the method(int a) function in Base class requires an argument of type integer to be passed. So for the code to work, the calling statement has to be something like obj.method(5).This statement works because the calling statement is actually passing 5 to the function.
There is an easy fix for your code:
Derived obj=new Derived();
Have you noticed?
I have relaced the reference to type Derived.
Why does that work?
Because there is method() function in your Derived class which doesn't require an integer argument.
There is one more amazing fact about inheritance in Java:
Everything possessed by a super-class is also possessed by the sub-class but the reverse is not true. And yes, the sub-class has the right to redefine any method/function it has inherited from super-class.
The above statement means the following code will work:
Derived obj=new Derived();
obj.method(5);
You must be wondering-How come this code works even though method() in Derived requires no argument. In fact, Derived has no method(int a).
Well, the answer to this is the amazing fact I have mentioned above.
Yes, method(int a) also belongs to Derived since it's a sub-class of Base.
But How does the code mentioned below work?
Derived obj=new Derived();
obj.method(5);
Simple, the JVM looks for the method(int a) in class Derived and it finds the function since Derived has inherited the function from Base class.
Remember this too, the sub-class also has a privilege to over-ride a method in super class. This means that you can add method(int a) function in class Derived which over-rides the original method inherited from Base.
How inheritance works?
When you call obj.method(5) in the above code, the JVM first looks for any over-ridden method of the same type in Derived. If it does not find any over-ridden method, it moves up in the inheritance hierarchy chain to the super class and looks for the same method. But the reverse is not the true.
how does compiler comes to know which method is to be called & too from which class?
The compiler searches for the method in the class (in this case Base) of the object (in this case obj). If the method is not found in that class, then it looks for the method in the super class (in this case Object). If still not found, it flags an error.
Is it that compiler checks the reference type class & if method to be invoked is not present in reference type class it gives error??
Yes. But, as said before, If the method is not found in that class, then it looks for the method in the super class (in this case Object). If still not found, it flags an error.
Your obj.method() will fail, because Base does not have a method with the signature method() (it has method(int))
If your obj was of type Derived, then both these case will work:
obj.method(); // will call this method from the Derived class
obj.method(1); // will call this method from the Base class
when there are same method names in different classes , the compiler comes to know by:
1-if you are passing any argument , then the type of argument which you are passing will tell the compiler which method to be called
2-if there are two classes , then make the object of that class for which you want to call the method
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
The concept of shadowing
I am confused about how the fields of classes are handled in Java during upcasting. For example:
class SuperClass
{
String myString = "String in SuperClass";
public void myMethod()
{
System.out.println("Method in SuperClass");
}
}
class SubClass extends SuperClass
{
String myString = "String in SubClass";
public void myMethod()
{
System.out.println("Method in SubClass");
}
}
class Question
{
public static void main(String[] args)
{
SuperClass test = new SubClass();
// object test is an instance of SubClass
// but I am telling the compiler to treat it as SuperClass
test.myMethod();
System.out.println(test.myString);
}
}
Output:
Method in SubClass
String in SuperClass //Why is "String in SubClass" not used?
When I create an object test it is an instance of SubClass class; however, I am telling the compiler to treat it as SuperClass. Everything is clear to me about methods work: I will only be able to use the methods of the SubClass, if a given method is defined for SuperClass.
However, I am lost as to why a field of a SuperClass is used when I try to access myString of test. Since test is an instance of SubClass I would expect myString defined in SubClass to be used, why is this not happening? What am I missing?
I know that I can access, myString of SubClass by using this operator. For example, I could define printMyString method in SuperClass, and overwrite it with
public void printMyString()
{
System.out.println(this.myString);
}
In the SubClass, so my question is mostly about how come the field of the SuperClass is used in test. Maybe I am missing something obvious?
I tried to search for the answer, and the closest topic I found was Upcasting in Java and two separate object properties, though helpful, it did not answer my question.
Thank You in Advance
Attributes cant be overloaded like methods.
test.myMethod();
Here method invocation depends on the type of actual object. Here object is of type SubClass so method of SubClass is invoked.
test.myString
While accessing attributes,it depends on the type of reference variable. Here reference variable ie test is of type SuperClass so attribute from SuperClass is accessed.
What you are looking is class variable hiding / shadowing.
Fields in Java are only hidden and not actually overridden (that doesn't mean that we'll get a compile time error while trying this, instead they are not overridden in its true sense).
Overriding means the member should be invoked based on the run time
type of the object and not based on the declared type.
But binding for fields in Java is always static and hence it's based on the declared type of the object reference only.
In the example you've given, by declaring the class variable with the name 'myString' in class SubClass you hide the class variable it would have inherited from its superclass SuperClass with the same name 'myString'.
Java language specification :
If the class declares a field with a certain name, then the
declaration of that field is said to hide any and all accessible
declarations of fields with the same name in superclasses, and
superinterfaces of the class.
A hidden field can be accessed by using a qualified name if it is static, or by using a field access expression that contains the keyword super or a cast to a superclass type.
in java, is it possible to access the instance to which a method belongs, given only the method?
for example:
public class ClassA {
private ClassB instanceB = new ClassB();
// ...
private void sendMethod () {
instanceB.receiveMethod(foo);
}
public void foo () {}
}
public class ClassB {
public void receiveMethod (Method method) {
Object o = foo.getInstanceOwner(); // just made that part up...
}
}
my feeling is that methods belong to classes, not instances of a class, so the answer is no, but maybe there's some sneaky reflection technique i don't know about. i could always pass 'this' along with method foo, but that seems like extra baggage.
Taken from
A Method provides information about, and access to, a single method on a class or interface. The reflected method may be a class method or an instance method (including an abstract method).
A Method permits widening conversions to occur when matching the actual parameters to invoke with the underlying method's formal parameters, but it throws an IllegalArgumentException if a narrowing conversion would occur.
You can call Method#invoke but you will need the instance of the object you want to call the method on, from the method doc:
Invokes the underlying method
represented by this Method object, on
the specified object with the
specified parameters. Individual
parameters are automatically unwrapped
to match primitive formal parameters,
and both primitive and reference
parameters are subject to method
invocation conversions as necessary.
If the underlying method is static,
then the specified obj argument is
ignored. It may be null.
If the number of formal parameters
required by the underlying method is
0, the supplied args array may be of
length 0 or null.
If the underlying method is an
instance method, it is invoked using
dynamic method lookup as documented in
The Java Language Specification,
Second Edition, section 15.12.4.4; in
particular, overriding based on the
runtime type of the target object will
occur.
If the underlying method is static,
the class that declared the method is
initialized if it has not already been
initialized.
If the method completes normally, the
value it returns is returned to the
caller of invoke; if the value has a
primitive type, it is first
appropriately wrapped in an object.
However, if the value has the type of
an array of a primitive type, the
elements of the array are not wrapped
in objects; in other words, an array
of primitive type is returned. If the
underlying method return type is void,
the invocation returns null.
So the TL:DR is unless you have the actual object you want you call the method on, it is not possible.
public class ClassA {
private ClassB instanceB = new ClassB();
// ...
private void sendMethod () {
Method m = ClassA.class.getMethod("foo", null);
instanceB.receiveMethod(m);
}
public void foo () {}
}
public class ClassB {
public void receiveMethod (Method method) {
Class c = method.getDeclaringClass();
}
}
gives you the owning Class. An instance doesn't own methods.
You can do this, but the proper way in your example would be the use of an interface, because that seems to be what you want: You want to pass in an object that ClassB knows how to operate on.
interface Callback {
void foo();
}
public class ClassA implements Callback {...}
public class ClassB {
public void receiveMethod(Callback cb) {...}
}
This is like asking:
"Given an apple from an Apple orchard, which tree owns this apple?"
The answer to which is:
"No idea, since all apple trees produce apples, it could belong to any tree".
... in other words - you must supply an instance from which the method will be called
EDIT
From one of your comments, I gather you are looking for an alternative of the Observer pattern. You say you don't like the messiness of the Observer pattern and that it is not "generic" enough for you.
I would argue that it is probably one of the least messiest patterns in existence, AND interfaces are by definition as generic as things get!
So, perhaps its an implementation problem you're having. Luckily, I have already posted on SO an Observer implementation in JAVA, to demonstrate how powerful and elegant it is.
Polymorphism and Interfaces in Java (can polymorphism be used to implement interfaces...why?)
In fact: reflection is messier than using an interface, since you can't guarantee at compile time that the type of Object you are invoking an instance of a Method on, even supports that method! (without some error checking code). Versus with interfaces, its not possible to even have that problem.
We always say that method overloading is static polymorphism and overriding is runtime polymorphism. What exactly do we mean by static here? Is the call to a method resolved on compiling the code? So whats the difference between normal method call and calling a final method? Which one is linked at compile time?
Method overloading means making multiple versions of a function based on the inputs. For example:
public Double doSomething(Double x) { ... }
public Object doSomething(Object y) { ... }
The choice of which method to call is made at compile time. For example:
Double obj1 = new Double();
doSomething(obj1); // calls the Double version
Object obj2 = new Object();
doSomething(obj2); // calls the Object version
Object obj3 = new Double();
doSomething(obj3); // calls the Object version because the compilers see the
// type as Object
// This makes more sense when you consider something like
public void myMethod(Object o) {
doSomething(o);
}
myMethod(new Double(5));
// inside the call to myMethod, it sees only that it has an Object
// it can't tell that it's a Double at compile time
Method Overriding means defining a new version of the method by a subclass of the original
class Parent {
public void myMethod() { ... }
}
class Child extends Parent {
#Override
public void myMethod() { ... }
}
Parent p = new Parent();
p.myMethod(); // calls Parent's myMethod
Child c = new Child();
c.myMethod(); // calls Child's myMethod
Parent pc = new Child();
pc.myMethod(); // call's Child's myMethod because the type is checked at runtime
// rather than compile time
I hope that helps
Your are right - calls to overloaded methods are realized at compile time. That's why it is static.
Calls to overridden methods are realized at run-time, based on the type on which the method is invoked.
On virtual methods wikipedia says:
In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final are non-virtual.
final methods cannot be overridden, so they are realized statically.
Imagine the method:
public String analyze(Interface i) {
i.analyze();
return i.getAnalysisDetails();
}
The compiler can't overload this method for all implementations of Interface that can possibly be passed to it.
I don't think you can call overloading any sort of polymorphism. Overloaded methods are linked at compile time, which kind of precludes calling it polymorphism.
Polymorphism refers to the dynamic binding of a method to its call when you use a base class reference for a derived class object. Overriding methods is how you implement this polymorphic behaviour.
i agree with rachel, because in K&B book it is directly mentioned that overloading does not belong to polymorphism in chapter 2(object orientation). But in lots of places i found that overloading means static polymorphism because it is compile time and overriding means dynamic polymorphism because it s run time.
But one interesting thing is in a C++ book (Object-Oriented Programming in C++ - Robert Lafore) it is also directly mentioned that overloading means static polymorphism.
But one more thing is there java and c++ both are two different programing languages and they have different object manipulation techniques so may be polymorphism differs in c++ and java ?
Method Overloading simply means providing two separate methods in a class with the same name but different arguments while method return type may or may not be different which allows us to reuse the same method name.
But both methods are different hence can be resolved by compiler at compile time that's is why it is also known as Compile Time Polymorphism or Static Polymorphism
Method Overriding means defining a method in the child class which is already defined in the parent class with same method signature i.e same name, arguments and return type.
Mammal mammal = new Cat();
System.out.println(mammal.speak());
At the line mammal.speak() compiler says the speak() method of reference type Mammal is getting called, so for compiler this call is Mammal.speak().
But at the execution time JVM knows clearly that mammal reference is holding the reference of object of Cat, so for JVM this call is Cat.speak().
Because method call is getting resolved at runtime by JVM that's why it is also known as Runtime Polymorphism and Dynamic Method Dispatch.
Difference Between Method Overloading and Method Overriding
For more details, you can read Everything About Method Overloading Vs Method Overriding.
Simple Definition - Method overloading deals with the notion of having two or more methods(functions) in the same class with the same name but different arguments.
While Method overriding means having two methods with the same arguments, but different implementation. One of them would exist in the Parent class (Base Class) while another will be in the derived class(Child Class).#Override annotation is required for this.
Check this :
Click here for a detailed example
Property Over-loading Overriding
Method Names -------------->must be Same----------------must be same
Arg Types------------------>must be Different(at least arg)
Method Signature
Return Type
Private,Static,Final
Access Modifier
try/Catch
Method Resolution
First, I want to discuss Run-time/Dynamic polymorphism and Compile-time/static polymorphism.
Compile-time/static polymorphism:- as its name suggests that it bind the function call to its appropriate Function at compile time. That means the compiler exactly know which function call associated to which function. Function overloading is an example of compile time polymorphism.
Run-time/Dynamic polymorphism:-In this type of polymorphism compiler don't know which functions call associates to which function until the run of the program. Eg. function overriding.
NOW, what are the function overriding and function overloading???
Function Overloading:- same function name but different function signature/parameter.
eg. Area(no. of parameter)
{ -------------
----------------
return area;}
area of square requires only one parameter
area of rectangle requires two parameters(Length and breadth)
function overriding:- alter the work of a function which is present in both the Superclass and Child class.
eg. name() in superclass prints "hello Rahul" but after overring in child class it prints "hello Akshit"
Tried to cover all differences
Overloading Overriding
Method Name Must be same Must be same
Argument Types Must be same Must be different
Return Type No restriction Must be same till 1.4V
but after 1.4V
co- variants
were introduced
private/static/final Can be overloaded Cannot be overridden
Access Modifiers No restriction Cannot reduce the scope
Throws keyword No restriction If child class method
throws a checked
exception the parent
class method must throw
the same or the
parent exception
Method Resolution Taken care by compiler Taken care by JVM based
based on reference types on run-time object
Known as Compile-Time Polymorphism, RunTime Polymorphism,
Static Polymorphism, or dynamic polymorphism,
early binding late binding.