BeeHive
BeeHive

Reputation: 23

Polymorphism - Method overriding and overloading not clear

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

Answers (4)

duffymo
duffymo

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

Yoshikage Kira
Yoshikage Kira

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

Pshemo
Pshemo

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

Vineeth Karanam
Vineeth Karanam

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

Related Questions