3
votes

I'm newbie in Java. So question might sound simple, but I'm stuck and can not figure out why this code returns null and 0.0 ?

file: Transport.java

public class Transport {

        private String name;
        private double price;

    public Transport(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String carName() {
        return name;
    }

    public double carPrice(){
        return price;
    }
}

file: Car.java

public class Car extends Transport{

    protected String name;
    protected double price;

    public Car(String name, double price) {
        super(name, price);
    }

    @Override
    public String carName(){
        return name;
    }

    @Override
    public double carPrice(){
        return price * 1.5;
    }
}

file: Main.java

public class Main {
    public static void main(String[] args) {

        Car c = new Car("CarBrand", 1000);

        System.out.println("Name: " + c.carName());
        System.out.println("Price: " + c.carPrice());
    }
}

Output

Name: null
Price: 0.0
6
If your class is called "Car", there usually is no need to put the "car" in property names. You also might want to get used to the important bean pattern early and prefix property accessors by "get" and "set". Consider names like this: Car myCar = new Car(...), myCar.getname()Amadán

6 Answers

11
votes

You've declared separate name and price variables in Car, and never assigned a value to them - they're not the same as the name and price variables declared (and initialized) in Transport. So you're seeing the default values for String and double, basically. Get rid of those extra variables in Car, and use super.carPrice() to get the original price from Transport:

public class Car extends Transport {    
    public Car(String name, double price) {
        super(name, price);
    }

    @Override
    public double carPrice(){
        return super.carPrice() * 1.5;
    }
}

Note that there's no need to override carName() at all unless you really want it to change behaviour.

I'd also suggest changing carName() and carPrice() to getName() and getPrice() to be more idiomatic.

1
votes

You are passing both the values to parent class Transport through super(). So

Car c = new Car("CarBrand", 1000);

will eventually set

Transport class attributes name & price.

You dont need to declare both the attributes in Car class. Car will have both attributes implicitly through inheritance. Here you are creating separate attributes for Car.

0
votes

The problem is that you have two different variables for name, one in Car and one in Transport. c.carName() returns Car.name which has not been initialized.

If your car class is the one below, it will work

public class Car extends Transport {
    public Car(String name, double price) {
        super(name, price);
    }

    @Override
    public double carPrice(){
       return price * 1.5;
    }        
}

the same goes for the variable price

0
votes

The derived class Car is hiding the instance variables of class Transport .So although you are inheriting the correctly initialized data members from Transport class ,but the Car class instance variables initilized to their default values are getting returned from Car class methods

0
votes

When you create the 'c' object of type Car, you assign values only for 'name' and 'price' variables of class Transport (because in your constructor you call super(name, price) that will call the constructor from your Parent class).

Here: c.carName() you call the method from your Car class (because is marked as @Override) and this one returns the value of the 'name' variable from class Car. And this variable in your case, is null because you didn't assign any value for it yet. You assigned the value "CarBrand" for 'name' variable of type Transport. The same for 'price' variable.

0
votes

The use of super will return the values which you already stored in the parent class by calling the constructor super(name, price), the use of super followed by dot notation will access the parent class method. So super.carPrice() will return the value stored in the parent class.

Also, @Override annotation should only used to change an existing method from the parent class with a new functionality in the child class with out changing the name. So in case of the @Overide for carname() you need to call the super.carname() because you are returning the value from the parent class.

In short, The reason why you are getting null and 0.0 because you are accessing the child class values when you should be accessing the parent class values.

    public class Car extends Transport{
        
        protected String name;
        protected double price;
    
        public Car(String name, double price) {
            super(name, price);
        }
    
        @Override
        public String carName(){
            return name;
        }
    
        @Override
        public double carPrice(){
            return price * 1.5;
        }
    }

Your class should be 

       public class Car extends Transport{
        
         
        
            public Car(String name, double price) {
                super(name, price);
            }
        
            
            public String getName(){
                return super.carName();
            }
        
            @Override
            public double carPrice(){
                return super.carPrice()* 1.5;
            }
        }

your main class should now be

public class Main {
  public static void main(String[] args) {

    Car c = new Car("CarBrand", 1000);
    System.out.println("Name: " + c.getName());
    System.out.println("Price: " + c.carPrice());

  }
}