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
Related
Why cant we declare an instance method in sub Class B which shares the same signature of a static method in parent Class A?
It throws a compile time error if i try to do that.
My question is, since static method of parent class is restricted to parent class, why does instance method of child class does not compile.
Lets see by code:
`
public class A{
static void testStatic(){}
}
public class B extends A{
void testStatic (){}
}
public class Test{
public static void main (String[] args){
A a = new B()
a.testStatic();
}
`
In the above code,since A does not have an instance method by that name, and since Java allows static methods to be accessed by objects, Object a of type 'A' pointing to 'B' can call static method present in it(class A). But complier throws an error "The instance method cannot override a static method" why?
Note: I can understand if a class does not allow same method name for two methods, even if one is instance and other is static. But I fail to understand why it does not allow a sub class to have an instance of same name. Especially considering the fact that static methods cannot be overridden. And yet, Java allows subclass to have same name as parent class static method, which is called information hiding, but not overriding.
The compiler throws an error because those are the rules of the language. From the Java Language Specification §8.4.8.2:
If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible to code in C.
It is a compile-time error if a static method hides an instance method.
(emphasis in the original). The language is dense (as in most places in the JLS) but it matches the situation you are describing. The JLS doesn't provide a rationale for this rule that I could find on first reading. But a little thought about how one might try to make this rule unnecessary shows why it's there.
It's illegal in Java. The call to the static method is allowed on an instance as well, so there'd be no way to distinguish which method to call in some cases:
A a = new A ();
B b = new B ();
A.testStatic (); // ok
B.testStatic (); // ok
a.testStatic (); // ok calling static
b.testStatic (); // undefined. What to call? Based on what?
Last call is the reason why it's not allowed.
Calls to static methods are resolved at compile time itself. So, they cannot be overridden. And by defining another method with the same signature as the static method, the compiler complains.
static method is bound with class whereas instance method is bound with object.
Static belongs to class area and instance belongs to heap area.
I am not hundred percent sure but I guess answer as below.
Static method means it can be used without an instance of the the class in which it is defined. Also static method can access only static variables of the class. Now if we override non static method and create an instance of sub class with reference of the super class, compiler will be confused for above two basic functioning of static method. Please debate if any thing wrong in this.
4 line showing error. so do this
public class B extends A
I am looking for a way to call different definitions of a (overridden) method depending on the type of the objects that are calling the method. This should make more sense when I labour the point below.
I have two classes defined as follows:
public class SuperClass{
public method1(){
if (objects are of type SuperClass and not SubClass){ //pseudocode
method2();
}
//do some more stuff
}
public method2(){
//do stuff
}
}
public class SubClass extends SuperClass{
#Override
public method1(){
method2();
super.method1();
}
#Override
public method2(){
//do stuff
}
}
From these two classes I am working with 3 objects, call them dog, cat, and bird. dog and cat are both objects of type SuperClass, whereas bird is of type SubClass.
You notice that all the objects follow the same basic procedure in the code, their method1() calls upon method2() before doing anything else. The difference between them is obviously that SubClass overrides method2(): bird has a different method2().
Currently my code is working how I want it, but I'm looking for a more elegant solution (if there is one). You can see from my code above how I've stepped around the issue at hand: in SuperClass I basically check that the objects are of type SuperClass. In my actual program that pseudocode line looks more like this (still "pseudocodey"):
if(this.toString().equals("Dog") || this.toString().equals("Cat")){
method2();
}
And bird calls it's own definition of method2() before calling the original definition of method1(). Basically both classes are dealing with their own local definition of method2().
My idea of a more elegant is as follows: completely remove the overridden definition of method1() from SubClass and be able to call the overridden definition of method2() from within SuperClass at the appropriate time (i.e. when the object I'm dealing with is bird).
I basically tried the above exactly as I wrote it, but the bird object ended up using the definition of method2() that is in SuperClass rather than the one in SubClass.
Can this be done, if so, how?
Inheritance and Overriding works exactly as you want it to, without you having to check if the instance if super or sub class.
Just do,
public class SuperClass{
public method1(){
method2(); // Note that you don't need any instance check here.
//do some more stuff
}
public method2(){
SOP("Super method2");
}
}
public class SubClass extends SuperClass{
#Override
public method2(){ // Note that you don't have to override method1
SOP("SUB method2")
}
}
In this case, if you call, method1() with an Super class object, it will call method2() of super class and print Super method2.
If you call, method1() with a Sub class object, it will call method2() of sub class and print Sub method2.
You should not check for the type in the superclass method. Not with the posted ugly toString() method, not with instanceof either. Let polymorphism work for you.
The whole concept of polymorphism is that you can call a method on a superclass type, and the object will behave as it's actual type. The standard textbook example goes something like this:
Cat cat = new Cat();
Animal animal = cat;
animal.speak();
Imagine you didn't see the animal = cat assignment. You just have an Animal. You don't know if it's a cat, or a dog or an elephant, all you know is that has a speak method. The object will behave according to its actual type, without needing to check types inside, thanks to polymorphism.
You can use the instanceOf() method to check if an object is an instance of another class. However this will return true for all super classes as well.
However I believe what you are saying is that you want sub classes to call their own version of a method if they have over ridden it. This will happen automatically due to Polymorphism
In order to call different definitions of a method depending on the type of the objects that are calling the method you might to do overloading, This is how it works
If a suitable function is found, that function is called. "Suitable" in this context means one of the following:
• An exact match was found.
• A trivial conversion was performed.
• An integral promotion was performed.
• A standard conversion to the desired argument type exists.
• A user-defined conversion (either conversion operator or constructor) to the desired argument type exists.
• Arguments represented by an ellipsis were found.
The compiler creates a set of candidate functions for each argument. Candidate functions are functions in which the actual argument in that position can be converted to the type of the formal argument.
A set of "best matching functions" is built for each argument, and the selected function is the intersection of all the sets. If the intersection contains more than one function, the overloading is ambiguous and generates an error. The function that is eventually selected is always a better match than every other function in the group for at least one argument. If this is not the case (if there is no clear winner), the function call generates an error.
Since this object(stated in title) can invoke overridden methods in child class, why it can't invoke other methods of child class?
I need answer as detailed as possible like memory organization, internal logic in JVM etc.
below code will give you clear understanding of my question.
class A
{
int x=10;
public A()
{
System.out.println("Constructor of class A called!!!");
}
public void sayGreetings()
{
System.out.println("accept hye from class A");
}
}
class C extends A
{
int x=30;//why this is not accessed by stated object.
public C()
{
System.out.println("Constructor of Class C caled!!!");
}
public void sayGreetings()
{
System.out.println("accept hye from class C");
}
public void ssa()
{
System.out.println("Sat Sri Akal ji from class C");
}
}
public class ParentClassTypeObject
{
public static void main(String[] args)
{
C cObj=new C();
cObj.sayGreetings();
cObj.ssa();
A aCObj=new C();//this is let say stated object,main object
aCObj.sayGreetings();/*here we invoked method will be child class's
overriden method.*/
//aCObj.ssa(); //why this line gives error
System.out.println("x="+aCObj.x);
}
}
Because the interface you have to the object is the one you chose when you wrote:
A aCObj = new C();
If you want access to the C properties via the aCObj variable, declare it as a C.
By making it an A, you make it possible to write this later:
aCObj = new A();
So since the variable can point to an A, or a C, the compiler restricts you to accessing the methods defined by the interface exposed by the A type.
You still access C's definition of those methods, because that's one of the main points of OOP (polymorphism).
Reference Variable points to the object which is of same type or the Sub set of same type.
Please consider Parent and Child are two classes Where Parent is Super Class and Child inherits the Parent Class. The below image will give you a detailed explanation.
In the above picture, The Parent class Reference variable will search for the Parent Class Object in Child Object.It will find it , as it is there.So will give the output.And if you have the Same method in Child Class(Method Overriding) It will execute the child class overrided method.
But for the Child Class reference Variable ,It can not find out the child class object in Parent Class Object.So here,It's Not possible.
Hope This clear your Confusion.
If you compile the code you will get compile time error(not runtime error). The reason behind this is that
A aCObj=new C();
aCObj.sayGreetings();/* The compiler knows that aCobj is a reference of type A while compiling. Since compiler thinks aCobj is of type A and sayGreetings() method is present in class A so no error while calling this method */
aCObj.ssa(); /* As I mentioned above that compiler have no knowledge about run time. At run time aCobj will point to the object of type class C, but while compiling the compiler only knows that aCobj is of class A type and since class A have no such method called ssa(), you will get compile time error. */
One simple rule for object : Left side of assignment operator checking at compile time. Right side of assignment operator at run time.
Consider this statement:
Parent obj =new Child();
obj.method1();
obj.method2();
Whatever method u want to call using obj reference of Parent type, those method should present in Parent class because during compile time the compiler will strictly check for those methods presence in Parent class even though it may be present in Child class.
The compiler decides IF you can call a method based on the type of the reference variable.So if the reference variable is of class A you can only call methods of class A.
But also
the compiler decides WHICH method to call based on the actual type of the object and not the type of the reference variable starting a bottom up check on the inheritance tree.(it starts from the subclasses all the way up)
So in this case when you say aCObj.sayGreetings(); the compiler firstly checks the reference type of aCObj which is A.Class A has the sayGreetings() method so its ok.But the actual object is a C.So the compiler starts from subclass (C) to find whether this method is implemented all the way to the superclass (A).The method `sayGreetings() is overriden at C class. So it calls the C class sayGreetings() method(of the subclass).
On the other hand the ssa() method is of class C and since the reference variable is of class A the compiler gives an error when you try aCObj.ssa();
It's just polymorphism.Since an A class reference variable can be either A or C object the compiler restricts the access only to the methods that are common which are the methods of the superclass A.Next it checks whether this method is implemented at the class of the actual object (C).if it is not it moves up to the superclass (A) and calls the method of the superclass.But if it is implemented it calls the method of the subclass (C)
The Object is of type A not C so you cannot access the instance variable i think if you make it public then you can.
Because aCObj is declared as type A so only methods declared in type A are accessible. The compiler cannot guarantee it is also of type C.
E.g.
You may also have
public class B extends A {
public void sayGreetings() {
...
}
}
This does not have the ssa method, but could still be assigned to an object declared as type A
Case 1. The reference variable of a parent class can point to an object of its child class..
Case 2. The reference variable of a parent class that is pointing to an object of its child class can be typecasted to an object of its child class.
In case 1: reference variable of a parent class can only call the methods that are defined within the parent class and also it can call the methods of child class that are overriding the methods of parent class.But cannot call the methods that are exclusively only in child class.
In case 2: reference variable of a parent class can call the methods of its child class also.
This is due to the principle of Polymorphism.
here is the detailed explanation of your stated query:
The answer is the intersection of "polymorphism" and "static typing". Because Java is statically typed at compile time you get certain guarantees from the compiler but you are forced to follow rules in exchange or the code won't compile. Here, the relevant guarantee is that every instance of a subtype (e.g. Child) can be used as an instance of its supertype (e.g. Parent). For instance, you are guaranteed that when you access employee.getEmployeeDetails or employee.name the method or field is defined on any non-null object that could be assigned to a variable employee of type Parent. To make this guarantee, the compiler considers only that static type (basically, the type of the variable reference, Parent) when deciding what you can access. So you cannot access any members that are defined on the runtime type of the object, Child.
The answer has been taken from the following link:
Why do we assign a parent reference to the child object in Java?
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
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.