user2895567
user2895567

Reputation:

Difference between declaring object as its superclass and its class?

I've read through the inheritance section of my java book and I tried the following example as practice:

public class Car {
private int wheels;
private int doors;
public Car(int initWheels, int initDoors){
    wheels = initWheels;
    doors = initDoors;
}
public int getWheels(){
    return  wheels;
}
public int getDoors(){
    return doors;
}

protected int calculateMaterials(){
    return wheels + doors;
}
}

public class Ford extends Car{
private String color;
private String type;
private int horsePower;
public Ford(int initWheels, int initDoors, String initColor, String initType, int initHorsePower){
    super(initWheels, initDoors);
    color = initColor;
    type = initType;
    horsePower = initHorsePower;
}
public String getColor(){
    return color;
}
public String getType(){
    return type;
}

protected int calculateMaterials(){
    return getWheels() + getDoors() + horsePower;
}
}

Main:

public class Main {
public static void main(String [] args){
    Car car = new Car(4,4);
    Car myCar = new Ford(6,2,"black", "pickup", 2);
    System.out.println(myCar.getWheels());
    System.out.println(myCar.calculateMaterials());
  }
}

However after re-looking at the code I came to question my-self if this was possible: Car myCar = new Ford(6,2,"black", "pickup", 2); . . . I ran it and saw that the output was exactly the same and now I am wondering if this:

Car myCar = new Ford(6,2,"black", "pickup", 2);

and this

Ford myCar = new Ford(6,2,"black", "pickup", 2);

the same thing, if so which was is preferable or more common? If not how come I get the same output?

Upvotes: 0

Views: 111

Answers (5)

Samhain
Samhain

Reputation: 1765

Running the following example will print 8, 10, and 10. The instantiation of the object(new) is what tells the JVM which code to run, not the type. In this example, myCar and myCarToo are both instantiated as type Ford, even though they are stored in variabled typed as Car and Ford.

Main:

public class Main {
public static void main(String [] args){
    Car car = new Car(6,2);
    Car myCar = new Ford(6,2,"black", "pickup", 2);
    Ford myCarToo = new Ford(6,2,"black", "pickup", 2);

    System.out.println(car.calculateMaterials());  //Car.calculateMaterials
    System.out.println(myCar.calculateMaterials());  //Ford.calculateMaterials
    System.out.println(myCarToo.calculateMaterials());  //Ford.calculateMaterials
  }
}

Upvotes: 0

ford prefect
ford prefect

Reputation: 7388

The problem is that you declare the reference type as Car You would get what I think is the desired result from

Ford myCar = new Ford(6,2,"black", "pickup", 2);

Several people bring up the good point that you are not actually overloading the constructor. That is really the larger problem here. Overloading the constructor only truly happens when you have the same arguments for the constructor of both the top class and the inheriting class. As a result you are always calling the Ford Constructor whenever you include five arguments

Upvotes: 1

MadConan
MadConan

Reputation: 3767

which was is preferable or more common?

It depends on how you intend to use the reference. If the methods necessary are only specific to something of type Car, then the reference should be declared as such. However, if you will need to get details associated with a subclass (Ford in your example), then that is the type that should be declared. In other words, always use the least specific type necessary.

If not how come I get the same output?

Because you are using the values only associated with type Car in both cases. If you don't add any more type-specific information to Ford then it probably shouldn't be it's own type.

Upvotes: 0

blackpanther
blackpanther

Reputation: 11486

You get the same output because car is a reference of type of Car not Ford. As a result, you cannot pass the Ford's methods to the reference car because it's reference type is Car not Ford. Therefore, to get what you want, you have to change the reference type of the reference variable car to Ford such as:

Ford fordCar = new Ford(6,2,"black", "pickup", 2);

But, this: Car myCar = new Car(6,2,"black", "pickup", 2); should not compile at all, because the Car constructor does not have the 5 argument constructor defined in Car

Upvotes: 0

rec
rec

Reputation: 10895

As a rule of thumb:

  • within a method, use the type which you need (if you need Ford-specific stuff, use Ford, otherwise Car)
  • in a return value of a function, use the same type you used in the method
  • when passing a value as a parameter, use the type you need in the parameter declaration, e.g. print(Car car) if you want to use only Car-specific stuff, otherwise print(Ford ford) if you need Ford-specific stuff

Upvotes: 0

Related Questions