我遇到了Java OOP问题.我想出了一些玩具代码来解释这个问题.这是我的课程 -
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
}
Run Code Online (Sandbox Code Playgroud)
第2类 - Truck.java
public class Truck {
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo("Truck", 6, problem);
}
//bunch of other methods
}
Run Code Online (Sandbox Code Playgroud)
第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));
}
}
Run Code Online (Sandbox Code Playgroud)
第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");
}
}
Run Code Online (Sandbox Code Playgroud)
我想将"Car"和"Truck"中的"reportProblem"方法实现抽象为父类.这就是我做的 -
第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;
}
}
Run Code Online (Sandbox Code Playgroud)
第2类 - Car.java
public class Car extends Vehicle {
//bunch of other methods
}
Run Code Online (Sandbox Code Playgroud)
第3类 - Truck.java
public class Truck extends Vehicle {
//bunch of other methods
}
Run Code Online (Sandbox Code Playgroud)
第4类 - 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));
}
}
Run Code Online (Sandbox Code Playgroud)
第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");
}
}
Run Code Online (Sandbox Code Playgroud)
这实现了我想要的(我已经抽象了"reportProblem"的实现).但我知道这不是最好的方法.一个原因是,如果不调用"setName"和"setNumWheels"方法,则不应调用"reportProblem"方法.否则将传递'null'.有没有一种方法可以使用一些OOP技术在调用reportProblem之前执行两个方法调用(setName和setNumWheels)?
我希望我已经说清楚了.如果我不是,请告诉我你将如何做到这一点,以便我可以从中学习.
是的,make name和numWheelsfinal然后在构造函数中赋值.所以...
第1类 - Vehicle.java
public abstract class Vehicle {
public final String mName;
public final int mNumWheels;
protected Vehicle(String name, int numWheels){
this.mName = name;
this.mNumWheels = numWheels;
}
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo(mName, mNumWheels, problem);
}
...
}
Run Code Online (Sandbox Code Playgroud)
第2类 - Car.java
public class Car extends Vehicle {
public Car(){
super("Car", 4);
}
//bunch of other methods
}
Run Code Online (Sandbox Code Playgroud)
第3类 - Truck.java
public class Truck extends Vehicle {
public Truck(){
super("Truck", 6);
}
//bunch of other methods
}
Run Code Online (Sandbox Code Playgroud)
此外,public字段不是良好的OO实践,因为它们公开了类的实现的细节,可以由类的用户修改.这些领域应该是private.如果类的客户端需要知道它们(或更改它们),那么您应该允许公共getter(或setter)方法.