2

I have an abstract class that subclasses will inherit. I want to have a get method that returns the amount of passengers. I declare this method in the abstract class and it will return the passengers.

The class member passengers is not defined but instantiated, so the get method knows what variable to return.

In the subclasses, I want this variable to have different values.

However, the get method returns 0 even when the amount of passengers is not 0.

I have tried writing: passengers = random.nextInt(4) + 1;

Abstract class vehicle

import java.util.Random;

public abstract class Vehicle {
    protected Random random = new Random();
    protected int passengers;

    public int getPassengerAmount() {
        return this.passengers;
    }
}

Class Car

public class Car extends Vehicle {
    private String name = "Car";
    private int size = 1;
    public int passengers = random.nextInt(4) + 1;
}
Kaan
  • 5,434
  • 3
  • 19
  • 41
FatDog
  • 153
  • 1
  • 9
  • whats the use of `getPassengerAmount` in the `Car` class – Arun Sudhakaran Jan 28 '20 at 10:52
  • My idea was that it should return the amount of passengers that it gets through the random number in the child class. Each sub class has a different max value. So I am not required to type the getPassengerAmount in every sub class it will inherit this method instead and return the class members value – FatDog Jan 28 '20 at 10:53
  • `passengers` field in `Car` is not the same as `passengers` field in `Vehicle`, they are two separate things. You can't override fields in the same way as you could with methods. – M. Prokhorov Jan 28 '20 at 11:01

4 Answers4

2

You are masking the parent variable by redeclaring the passengers variable in the Car class.

You should initialize the parent variable in the constructor of the child instead:

public class Car extends Vehicle {

    private String name = "Car";
    private int size = 1;

    public Car() {
        this.passengers = random.nextInt(4) + 1;
    }

}

If you want it to be public, then you should make it public in the Vehicle class, but to be honest I wouldn't recommend it and I would rather go with protected variables but public getters / setters.

AntoineB
  • 4,535
  • 5
  • 28
  • 61
0

The answer to your question will be that you are initializing passengers variable directly. you have to create a constructor for it and assign a default value there. plus there is no need for you to create a public variable again in the subclass otherwise the abstract class makes no sense of existing. Note, an abstract class must have an abstract function.

Farrukh
  • 153
  • 1
  • 8
0
public class Car extends Vehicle {
    private String name = "Car";
    private int size = 1;
    public int passengers = random.nextInt(4) + 1; // this is not passengers of the superclass
    void setPassengers() { passengers = random.nextInt(4) + 1; } // this is passengers of the superclass
}
lainatnavi
  • 1,453
  • 1
  • 14
  • 22
  • I can not write passengers = random.nextInt(4) + 1; I get syntax errors – FatDog Jan 28 '20 at 11:03
  • @FatDog edited answer. Since extending the `Vehicle` class inherits the protected members, you can access `passengers` without a setter method. – lainatnavi Jan 28 '20 at 11:16
  • If `passengers` where private you would need a superclass setter to achieve the same result: `super.setPassengers(random.nextInt(4) + 1);` – lainatnavi Jan 28 '20 at 11:21
  • I was unable to access them directly in the subclass, I copied what you wrote prior to the edit and it did not work. – FatDog Jan 28 '20 at 11:32
  • my error; it was not working because you can initialize a class member outside a method only uplon declaration, and the declaration was in the superclass. – lainatnavi Jan 28 '20 at 11:56
-1

You are not using the good approach to calculate how many passengers are in a certain vehicle.

It's nice to have your Vehicle as an abstract class as it will have only common caracteristic that all Vehicle share and let the specificities of each one being implemented in their respective classes.

For the Car. You have to implement your specific conception of how many passengers should be in a Car. Thus, getPassengerAmount() should be declared abstract in your Vehicle and be implemented in each specific vehicle.

That means :

import java.util.Random;

public abstract class Vehicle {
protected Random random = new Random();
protected int passengers;

public Vehicle() {
   initializeVehiculeOptions();  
}

public abstract int initializeVehiculeOptions();    
}

and

import java.util.Random;

public class Car extends Vehicle {

     private String name = "Car";
     private int size = 1;

     public Car() {
          super();
     }

     @Override
     public int initializeVehiculeOptions() {
          // Here you initialize for 
          this.passengers = random.nextInt(4) + 1;
     }
}

You will use a Car instance

Car ford = new Car();
Hassam Abdelillah
  • 2,246
  • 3
  • 16
  • 37
  • While this does solve the problem it is conceptually wrong on multiple counts: the getter does not need to be abstract and can be declared in the parent just like OP does, and the getter shouldn't change anything to the variables, it makes literally no sense for a "getter" to set anything. – AntoineB Jan 28 '20 at 10:56
  • I Agree on the fact that it can be better explained. Especially, for the 'passengers' property initialization. But from an other POV. It highlight a more other important concept of abstract classes and methods and inheritance. – Hassam Abdelillah Jan 28 '20 at 10:59
  • It's not about explaining it well or not, it is a working, but very bad solution, period. Nothing justifies reimplementing the getter in each child class, and nothing justifies setting values in a getter. If your getters are not just the single line `return this.var;` you are wrong 95% of the time. – AntoineB Jan 28 '20 at 11:00
  • 2
    How do you feel about a car that has a random number of seats every time you look at it? – M. Prokhorov Jan 28 '20 at 11:02
  • Giving some arguments of why you think it's a bad solutions. It will be helpful for me and also for the OP on things that should not be done :) – Hassam Abdelillah Jan 28 '20 at 11:03
  • I let that for the OP appreciation. It was not the subject of the question. – Hassam Abdelillah Jan 28 '20 at 11:03
  • 1
    You don't seem to understand @M.Prokhorov's comment. What he means is that every time you call the getter on the SAME object, you'll get a different value, which makes no sense. OP wants to randomize the number of passengers ONCE per object, that's it. This is just another highlight of why your solution is wrong. – AntoineB Jan 28 '20 at 11:07