充分利用Java中的多态性

时间:2019-12-23 20:49:21

标签: java polymorphism abstract-class

我有以下问题:

考虑我们有3个课程:

  • 一个名为Vehicle的抽象类
  • 一个名为Motorcycle的类,它扩展了Vehicle
  • 一个名为Car的类,它扩展了Vehicle

这意味着Vehicle个对象可以同时容纳MotorcycleCar个对象。

我还有一个名为VehicleDatabase的类,该类基本上是“模拟”数据库(我希望我可以使用数据库,但这是一个大学项目),并拥有一个名为ArrayList<Vehicle>的{​​{1}}字段以及提供一些基本操作的一些方法,以便我可以与数据库进行交互(CRUD操作和其他一些操作)。

我要实现的一种方法是db。为了简化并弄清楚我的问题,假设此方法必须简单地将由函数的参数指定的所有对象的showVehicles()打印到控制台。

示例:

用户中显示一个菜单:

.toString()

此后,我们的函数Select which type of vehicles you want to be shown: 1.Motorcycles 2.Cars Make your choice: 必须采用参数showVehicles并打印存储在showVehicles(CarSomething) ArrayList上的所有汽车。我只是真的找不到更优雅的方法来实现该功能。下面是我当前的实现方式:

db

并像这样调用它:public void showVehicles(Class<?> cls) { for(Vehicle v : db) { if(v.getClass().equals(cls)) System.out.println(v.toString()); } } showVehicles(Car.class)

是否有更好的方法来做到这一点?请提出您的建议。我只是觉得我不应该使用多态性。

2 个答案:

答案 0 :(得分:1)

这里是一种可能性。

我创建了一个Map<Class<?>, List<Vehicle>>来保存库存。

该地图是根据车辆列表创建的,但可以直接将其添加到地图中来创建。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

abstract class Vehicle {
}

class MotorCycle extends Vehicle {
   String name;

   MotorCycle(String name) {
      this.name = name;
   }
   public String toString() {
      return name;
   }
}

class Car extends Vehicle {
   String name;

   Car(String name) {
      this.name = name;
   }

   public String toString() {
      return name;
   }
}

public class CarMapper {

   public static void main(String[] args) {
      List<Vehicle> list = new ArrayList<>();
      list.add(new MotorCycle("Honda"));
      list.add(new MotorCycle("Harley-Davidson"));
      list.add(new Car("Ford"));
      list.add(new Car("Chrysler"));

      Map<Class<?>, List<Vehicle>> inventory = list.stream().collect(
            Collectors.groupingBy(Object::getClass));

     }
}

这是否合理,取决于您(和其他发表评论的人)。您可能仍需要一张地图,才能从用户菜单中获取正确的类。

  Map<String, Class<?>>  menuMap = new HashMap<>();
  menuMap.put("Car", Car.class);
  menuMap.put("MotorCycle", MotorCycle.class);

  Class<?> lookup = menuMap.get("Car");

  for (Vehicle v : inventory.get(lookup)) {
     System.out.println(v.toString()); 
  }

答案 1 :(得分:0)

实际上,这不是通常使用面向对象方法的方式。这是一个使用多态方法的示例。 “ printName”函数在抽象类中定义(在这种情况下也可以是接口):

import java.util.ArrayList;

abstract class Vehicle {
    public abstract void printName(); // virtual function
}
class Car extends Vehicle {
    public void printName() { // function implementation in the class Car
        System.out.println("I am a car");
    }
}
class Bike extends Vehicle {
    public void printName() { // function implementation int the class Bike
        System.out.println("I am a bike");
    }
}


public class T1{
    ArrayList <Vehicle> vehicles = new ArrayList<Vehicle>();

    void create() {
        vehicles.add(new Car());
        vehicles.add(new Bike());
    }
    void list() {
        for (Vehicle v: vehicles)
            v.printName();  // use the function at the show time
    }
    public static void main(String args[]) {
        T1 t1 = new T1();
        t1.create();
        t1.list();
    }
}

如果要使用真实的数据库,将会有很大的不同。后者只能保存Java类中的data字段并将它们还原到该类中。因此,您的应用程序必须在读取时了解这些类,并确保正确的类中填充了正确的数据。在这种情况下,序列化可以提供帮助。