I’m stuck with a Java OOP problem. I have come up with some toy code to explain the problem. Here are my classes –
Class 1 – Car.java
public class Car {
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo("Car", 4, problem); //4 is number of wheels
}
//bunch of other methods
}
Class 2 – Truck.java
public class Truck {
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo("Truck", 6, problem);
}
//bunch of other methods
}
Class 3 – ReportUtil.java
public class ReportUtil {
public static void reportVehicleInfo(String name, int wheels, String problem){
System.out.println(String.format("%s %s %s", name, wheels, problem));
}
}
Class 4 – Test.java
public class Test {
public static void main(String[] args) {
Car c = new Car();
c.reportProblem("puncture");
Truck t = new Truck();
t.reportProblem("engine missing");
}
}
I want to abstract the “reportProblem” method implementation in “Car” and “Truck” to a parent class. This is what I did –
Class 1 – Vehicle.java
public abstract class Vehicle {
public String mName;
public int mNumWheels;
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo(mName, mNumWheels, problem);
}
public void setName(String name){
mName = name;
}
public void setNumWheels(int numWheels){
mNumWheels=numWheels;
}
}
Class 2 – Car.java
public class Car extends Vehicle {
//bunch of other methods
}
Class 3 – Truck.java
public class Truck extends Vehicle {
//bunch of other methods
}
Class 4 – ReportUtil.java (No change made to this class).
public class ReportUtil {
public static void reportVehicleInfo(String name, int wheels, String problem){
System.out.println(String.format("%s %s %s", name, wheels, problem));
}
}
Class 5 – Test.java
public class Test {
public static void main(String[] args) {
Car c = new Car();
c.setName("Car"); //NOTE : Can be missed!
c.setNumWheels(4); //NOTE : Can be missed!
c.reportProblem("puncture");
Truck t = new Truck();
t.setName("Truck"); //NOTE : Can be missed!
t.setNumWheels(6); //NOTE : Can be missed!
t.reportProblem("engine missing");
}
}
This achieves what I want (I have abstracted the implementation of “reportProblem”). But I know this is not the best way to do it. One reason is that the “reportProblem” method should not be called without calling “setName” and “setNumWheels” methods. Otherwise ‘null’ will be passed. Is there a way of enforcing, using some OOP technique, the two methods calls (setName and setNumWheels) BEFORE reportProblem is called?
I hope I have made myself clear. If I am not, just let me know how you would have done it so that I can learn from it.
Yes, make
nameandnumWheelsfinal and assign then in the constructor. So…Class 1 – Vehicle.java
Class 2 – Car.java
Class 3 – Truck.java
Also,
publicfields are not good OO practice, because they expose details of your class’ implementation that could be modified by users of the class. Those fields should beprivate. If the clients of the class need to know about them (or change them), then you should allow public getter (or setter) methods.