Java OOP问题 - 与接口/抽象类相关

Med*_*One 1 java oop

我遇到了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)?

我希望我已经说清楚了.如果我不是,请告诉我你将如何做到这一点,以便我可以从中学习.

Joh*_*n B 6

是的,make namenumWheelsfinal然后在构造函数中赋值.所以...

第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)方法.