java - 继承实现

标签 java oop inheritance

如何在本练习中实现继承?

一家汽车经销商想要一个计算机系统来管理他们的车辆数据并按类型对其进行分类。

  • 所有汽车都有以下数据

    1. 发动机序列号
    2. 品牌
    3. 年份
    4. 价格
  • 车辆分为小型车豪华车卡车旅行车

  • 对于汽车和货车,存储乘客数量也很重要;而对于卡车,负载能力应该以公斤为单位进行控制。以及轴数轮数

  • 对该系统建模并实例化每个类,通过它们各自的属性分配数据。为每个类添加参数化构造函数以初始化其数据并从每个派生类的构造函数调用基类构造函数(不要使用默认构造函数)。

  • 实现 toString() 方法的覆盖以显示每种汽车类型的数据。 注意:类或空类(无元素)中不允许有重复的组件。

我试过的:(我不知道继承是否正确)

interface Passegers {

    int CantidadPasajeros(int n);

    int Pasajeros();
}

class Vehicle {}

class Auto extends Vehicle implements Passegers {

    private int numSerieMotor;
    private String marca;
    private int año;
    private double precio;

    public int CantidadPasajeros(int n) {
        return n;
    }
}

class CompactAutos extends Auto {
    public int CantidadPasajeros(int n) {
        return n;
    }
}

class LuxuryAutos extends Auto {
    public int CantidadPasajeros(int n) {
        return n;
    }
}

class Truck extends Auto {
    private int capacity;
    private int axes;
    private int rounds;
}

class Wagon extends Vehicle implements Passegers {
    public int CantidadPasajeros(int n) {
        return n;
    }
}

public class Tarea22ago {
    public static void main(String[] args) {
        Vehicle x[] = new Vehicle[3];
        x[0] = new Auto();
        x[1] = new Wagon();
        x[2] = new Truck();
    }
}

但是,Vehicle 类将是空的。我仍然需要在每个类中编写构造函数,但我只是想确定这种继承用法是否正确。

最佳答案

我会从头到尾检查您的代码并进行评论。 一般注意事项是遵循 Java 代码约定。

你的接口(interface)本身就很好,但是命名和 setter 不返回值的约定使它成为可能

interface Passengers {
    void setPassengers(int count);
    int getPassengers();
}

您不妨添加一个与载重车辆的接口(interface)。

interface LoadVehicle {
    int getCapacity();
    int getAxes();
    int getRounds(); // what is this anyway?
}

请注意,此接口(interface)中没有 setter ;这些项目不会改变(cfg GhostCat 在下面的评论)。

Vehicle 类也可能是一个标记接口(interface)(“标记”说它只是表示它是一个车辆,但没有定义任何方法)。

interface Vehicle {}

(这可以让其他两个接口(interface)扩展它,如 interface Passengers extends Vehicleinterface LoadVehicle extends Vehicle)。

Auto 类没有所需的构造函数。 并非所有 Autos 似乎都有 Passenger,因此没有必要实现该接口(interface)。

class Car implements Vehicle {
    private int motorNumber, makeYear;
    private String brand;
    // add getter/setters for the price? This is something that can change.
    private double price;

    // constructor. This needs to be called from all subclasses as well
    Car(String brand, int year, int engNum, double price) {
        // assign parameters to variables
    }            
}

我看不出创建 CompactCar 和 LuxuryCar 类有什么意义,因为它们本身似乎没有区别。一般类应该可以做到。

class PassengerCar extends Car implements Passengers {
    // add getter and setter for this to implement the interface
    private int passengers;
    PassengerCar(String brand, int year, int engNum, double price) {
        super(brand, year, engNum, price);
    }
}

您可以只创建 LuxuryCars 或 Compacts 作为它的实例。

同样,您现在可以为卡车创建 Car。

class LoadCar extends Car implements LoadVehicle {
    // again, getters for these for the interface
    private int capacity, axes, rounds;
    // and constructor
    LoadCar(String brand, int year, int engNum, double price, 
        int cap, int axCount, int roundCount) {
        super(brand, year, engNum, price);
        // assigs the other parameters to variables
    }
}

如果没有其他区别,可以将卡车创建为 LoadCar。

现在对于货车,您的 Wagon 类没有所需的加载函数。 您必须决定是继承 LoadCar 还是 PassengerCar;毕竟,两者都是。在这两种情况下,您都需要实现其他缺少的接口(interface)。 我会选择这个,因为 Passengers 界面更简单:

class Wagon extends LoadCar implements Passengers {
    // again, getter and setter for this for the interface
    private int passengers;
    Wagon(String brand, int year, int engNum, double price, 
        int cap, int axCount, int roundCount) {
        super(brand, year, engNum, price, cap, axCount, roundCount);
}

扩展哪个并不重要,因为在您使用这些类的系统中,您只会使用接口(interface)。

编辑: 下面是创建对象的方式:

// create a luxury car
PassengerCar luxuryCar = new PassengerCar("BMW", 2017, 322131, 49_999.99);
// create a compact
PassengerCar compactCar = new PassengerCar("Smart", 2014, 55231, 25_999.99);
// create a truck
LoadCar truck = new LoadCar("Mercedes", 2014, 2113321, 99_999.99, 10_000, 6, 4);
// create a wagon
Wagon wagon = new Wagon("Dodge", 2005, 551223, 19_999.99, 3_000, 6, 4);

并可能展示这种继承的影响:

List<Vehicles> vehicles = new ArrayList<>();
List<Passenger> passengerVehicles = new ArrayList<>();
List<LoadCar> loadVehicles = new ArrayList<>();

// everything is a vehicle:
vehicles.add(luxuryCar); // fine
vehicles.add(compactCar); // fine
vehicles.add(truck); // fine
vehicles.add(wagon); // fine

// you can only add passenger vehicles the the passenger car list:
passengerVehicles.add(luxuryCar); // fine
passengerVehicles.add(compactCar); // fine
passengerVehicles.add(wagon); // fine
passengerVehicles.add(truck); // NO! a truck is not a passenger car.

// you can only add load cars to the load car list:
loadVehicles.add(luxuryCar); // NO! a PassengerCar is not a LoadCar.
loadVehicles.add(compactCar); // NO, same reason
loadVehicles.add(wagon); // fine
loadVehicles.add(truck); // fine

顺便说一句,这是另一个列表:

List<Car> cars = new ArrayList<>();
// everything is a car:
cars.add(luxuryCar); // fine
cars.add(compactCar); // fine
cars.add(truck); // fine
cars.add(wagon); // fine

那么 Vehicle 和 Car 之间的区别有什么意义呢? 好吧,假设您开始销售船只...

class Boat implements Vehicle, Passenger {
    // add getter/setter
    private int passengers;
    public Boat(int keelDepth) {
    }
}

这意味着:

Boat boat = new Boat(15);
vehicles.add(boat); // fine
cars.add(boat); // NO! it's not a car.
passengerVehicles.add(boat); // well yes that works.

关于java - 继承实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45830867/

相关文章:

C++,菱形继承(钻石问题),何时/何地需要实现纯虚拟?

java - Spring 3 中通过注解注入(inject)与通过 XML 文件注入(inject)的对比。与继承相关的限制

java - Object 是抽象类的父类(super class)吗?

java - 无法使双向链表工作

java - (我不知道如何比较字符串)用 while 循环写入文件

php oop文件上传

php - 如何以正确的方式设计模型 : Object-oriented or "Package"-oriented?

java - PDF 'Itext User Agent' 缓存大小以及如何清除它

java - Netbeans:java.lang.UnsatisfiedLinkError:java.library.path中没有闪屏:

java - 为什么不能使用 super 关键字引用接口(interface)变量