Reputation: 23
I am learning polymorphism but not able to understand how it works
When I try to create an object Car car = new Audi();
, overriding prints "This is Audi". But with same object I am not able to call first(int x, int y)
of Audi
class... I am able to call only Car
class first()
.
Overriding prints the Audi method, Overloading prints Car method.. when calling with same object..
Class Car
class Car {
public void carName() {
System.out.println("Parent of car");
}
public int first() {
System.out.println("Base - Parent");
return 2;
}
}
Class BMW
class BMW extends Car {
public void carName() {
System.out.println("This is BMW");
}
public int first(int x) {
System.out.println("BMW override");
return x;
}
}
Class Audi
class Audi extends BMW {
public void carName() {
System.out.println("This is Audi");
}
public int first(int x, int y) {
System.out.println("AUdi Override");
return x;
}
}
Class PloyMor
public class PolyMor extends Audi {
public static void main(String args[]) {
Car car = new Audi();
car.carName();
car.first();
}
}
Upvotes: 0
Views: 143
Reputation: 308763
You are not overriding first from Car
in Audi
, because the signatures are different.
The signature includes the method name, parameters, and throws clause.
The method first()
from Car
takes no arguments.
In Audi
it takes two ints as arguments. Not the same.
Even your simple hierarchy is not a good design. You are having problems because your implementation is bad.
Try this:
public abstract class Car {
private String name;
private int id;
public Car(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() { return this.name; }
public int getId() { return this.id; }
public static void main(String [] args) {
List<Car> cars = new ArrayList<>();
cars.add(new Audi());
cars.add(new Bmw());
System.out.println(cars);
}
}
class Audi extends Car {
public Audi() {
super("Audi", 1);
}
}
class Bmw extends Car {
public Bmw() {
super("BMW", 2);
}
}
Upvotes: 1
Reputation: 1121
Calling a method depends on the compile-type rather than the runtime type.
Car car = new Audi();
^ ^
compile-type runtime type
Compiled Type vs Runtime Type: Source
Credit: @duffymo
Let's say we have
A test = new B();
at compile time: the compiler only knows that the variable test is of the type A. He does not know that we are actually giving him an instance of B. Therefore the compile-type of test is A.
at run time: the type of test is known to be B and therefore has the run time type of B
Since compiler does not know what type will be stored at runtime it only allows us to call methods of Class A
Solution:
If you want to call methods from instantiated type do this
then you will be able to access method first(int x, int y)
Audi car = new Audi();
car.carName();
car.first(); // Original Method
car.first(3, 3); // Overloading
Output:
This is Audi
Base - Parent
AUdi Overload
P.S Like OldProgrammer mentioned Audi should extend Car instead of BMW
Upvotes: 1
Reputation: 124225
Important: I am assuming that class BTW
extends Car
not Audi
(which would makes no sense IMO).
But with same object i am not able to call first(int x, int y) of Audi class.
You need to distinguish between variable type and value (object) type. In case of
Car car = new Audi();
variable type is Car
while type of object it holds is Audi
.
You need to realize that compiler doesn't assume what is the value of variable. It applies same rules as if it was parameter of method like
void someMethod(Car car){
//do something with `car`
}
where inside of that method we don't know if it will be used with someMethod(new Audi());
or someMethod(new BMW());
.
So which methods can be safely invoked via car
variable inside someMethod
body? Only those which are guaranteed to be implemented (to appear) in all objects which can be used as method arguments. If that method would let us write car.first(1, 2);
it will work for scenario like someMethod(new Audi())
but will fail for someMethod(new BMW())
because BMW doesn't have first(int x, int y)
method.
Upvotes: 2
Reputation: 11
It would have worked if you had another method defined in the base class like follows:
public int first(int a, int b) {
System.out.println("Base - Parent");
return 2;
}
As the final object you are trying to create is an object of class Car
, it only has the methods from the Car
class which if are present in Audi
class, will override the methods in Car
class.
Upvotes: 1