【问题标题】:Object ArrayList For-Loop Error对象 ArrayList For-Loop 错误
【发布时间】:2018-03-14 06:01:56
【问题描述】:

我有一个Object ArrayList,我需要使用Motor对象的toString()方法,它是Vehicle的一个参数> 对象。我的车辆对象位于一个 ArrayList 中,该 ArrayList 使用 for 循环进行迭代(我知道 foreach 循环会更容易,但这是任务的一部分)

这是循环的代码:

for (int i = 0; i < VehicleList.size(); i++) {
    System.out.println();
    String info = VehicleList.get(i).toString();
    Motor m = VehicleList.get(i).motor;
    String motorInfo = m.toString();
    System.out.println(info);
    System.out.println(m);
    }

有一个错误提示“motor 无法解析或不是字段

所有的类都应该允许这个工作,当然除非我遗漏了一个简单的错误。

这是电机类:

 public class Motor {
    protected String name;
    protected int cylinders;
    protected int bhp;
    protected double displacement;

    public Motor(String name, int cylinders, int bhp, double displacement) {
        this.name = name;
        this.cylinders = cylinders;
        this.bhp = bhp;
        this.displacement = displacement;
    }

    public String toString() {
        return "Motor name= " + name + ", cylinders= " + cylinders + ", bhp= 
     " + bhp + ", displacement= " + displacement;
    }
}

在此处初始化汽车和车辆(在 TestVehicle 类中):

        //Motors
        Motor EcoBoost = new Motor("EcoBoost", 6, 310, 2.3);
        Motor Hemi = new Motor("Hemi", 8, 707, 5.7);
        Motor P90D = new Motor("P90D", 0, 762, 0.0);

        //Vehicles
        Vehicle v0 = new PassCar("Ford", "Mustang", 2016, 44500.0, 5, true, EcoBoost);
        Vehicle v1 = new PassCar("Tesla", "Model S", 2016, 121000.0, 2, true, P90D);
        Vehicle v2= new Truck("Dodge", "Ram", 2016, 46000.0, "pickup", 1500, Hemi);

PassCarTruck 是 Vehicle 的继承类,具有更多属性。如果需要,我可以发布 PassCar 或 Truck 类,但我认为这不是问题所在。我相信它来自 For-Loop,特别是 Motor m = VehicleList.get(i).motor; 行,但我不确定如何修复它.

车辆类别:

public class Vehicle {
protected String make;
protected String model;
protected int year;
protected double price;

public Vehicle(String make, String model, int year, double price) {
    this.make = make;
    this.model = model;
    this.year = year;
    this.price = price;
}


public void description() {
    System.out.println("Description");
}

public String toString() {
    return "make= " + make + ", model= " + model + ", year= " + year + 
  ", price= " + price;
 }

}

编辑:根据分配要求,不能有任何 Getter 或 Setter,它必须是 ArrayList,而不是常规 List。当我切换到我收到错误“类型不匹配:无法从 ArrayList 转换为 ArrayList

这是课程的图片:

【问题讨论】:

  • Vehicle 类是否有一个名为 motor 的字段?
  • 显示VehicleList的声明。
  • 请发帖Vehicle班级。
  • 在类Vehicle中创建变量motor
  • @Matthew 这是Object 的列表。将其更改为List&lt;Vehicle&gt;

标签: java inheritance arraylist tostring


【解决方案1】:
ArrayList<Object> VehicleList = new ArrayList<>(Arrays.asList(vehicles));

VehicleList 被声明为包含Object 的实例,因此编译器将只允许您访问它知道存在于所有Object 实例上的方法和字段。

将其更改为ArrayList&lt;Vehicle&gt;

【讨论】:

  • 部分项目要求是我不能使用getter或setter。此外,它不能是 List,它必须是 ArrayList。当我将 切换为 时,出现错误“类型不匹配:无法从 ArrayList 转换为 ArrayList
  • @Matthew 那么大概vehiclesObject[]。将其更改为 Vehicle[]
【解决方案2】:

首先,请注意命名约定。变量应以camcelCase 命名,例如车辆列表instead of车辆列表`

我有一个对象数组列表

我相信你的意思是vehicleList 的声明看起来像ArrayList&lt;Object&gt; vehicleList

然后行为是预期的,因为编译器只知道VehicleList.get(i) 将返回一个Object 引用。它可以是Vehicle,但也可以是其他任何东西。所以它不允许您访问motor 字段,因为Object 中根本没有这样的字段。

将您的声明更改为List&lt;Vehicle&gt; vehicleList


但是,正如其他答案中所述,由于各种原因,直接访问该字段并不是一个好主意。一个稍微不那么邪恶的方法是使用motor 的getter。 (更好的方法是提供有意义的行为,而不是提供对内部数据的访问)

【讨论】:

  • 不能是List,必须是ArrayList。当我将 切换为 时,出现错误“类型不匹配:无法从 ArrayList 转换为 ArrayList
  • @MatthewThibodeau 你需要的是对Java有更多的基础知识,这样你就知道这种类型不匹配的问题和解决方案是什么。当然,您始终可以将其显式转换为 ((Vechicle) (VehicleList.get(i))).motor;,但这几乎不是解决问题的正确方法
【解决方案3】:

创建一个接口IMotor,供Vehicle类使用并在PassCar和其他车辆实现中实现。

IMotor.java

public interface IMotor {
    public Motor getMotor();
}

Motor.java

public class Motor {
    protected String name;
    protected int cylinders;
    protected int bhp;
    protected double displacement;

    public Motor(String name, int cylinders, int bhp, double displacement) {
        this.name = name;
        this.cylinders = cylinders;
        this.bhp = bhp;
        this.displacement = displacement;
    }

    public String toString() {
        return "Motor name= " + name + ", cylinders= " + cylinders + ", bhp=" + bhp + ", displacement= " + displacement;
    }
}

Vehicle.java

public abstract class Vehicle implements IMotor{
    protected String make;
    protected String model;
    protected int year;
    protected double price;

    public Vehicle(String make, String model, int year, double price) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.price = price;
    }

    public String toString() {
        return "make= " + make + ", model= " + model + ", year= " + year + 
      ", price= " + price;
     }
}

PassCar

public class PassCar extends Vehicle{

    protected Motor motor;

    public PassCar(String make, String model, int year, double price, Motor motor) {
        super(make, model, year, price);
        this.motor = motor;
    }

    public Motor getMotor() {
        return motor;
    }
}

Test.java

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        Motor EcoBoost = new Motor("EcoBoost", 6, 310, 2.3);
        Vehicle v0 = new PassCar("Ford", "Mustang", 2016, 44500.0, EcoBoost);

        List<Vehicle> vehicles = Arrays.asList(v0);
        System.out.println(vehicles.get(0).getMotor());
    }
}

【讨论】:

    【解决方案4】:

    您的问题是motor 不是Vehicle 类的成员,但您正试图通过Vehicle 类型的表达式(即vehicleList.get(i))来访问它。这是禁止的,因为编译器无法知道每种可能的Vehicle 都有motor。毕竟,如果你添加一个Bicycle 类会发生什么?

    要完成这项工作,您应该从TruckPassCar 类中删除motor,并将其添加到Vehicle 类中。这样一来,vehicleList.get(i).motor 就有意义了,因为Vehicle 表达式可以保证引用带有MotorVehicle

    还建议对motor 字段使用getter - 即,将motor 作为Vehicle 类的private 字段,并编写一个方法getMotor() 来返回它。然后,您可以编写 vehicleList.get(i).getMotor() 以获取与列表中的一个 Vehicle 关联的 Motor 对象。

    【讨论】:

      【解决方案5】:

      感谢所有 cmets 和我的 Java 教科书的帮助,我设法将它拼凑起来。这是我如何让它工作的:

      for (int i = 0; i < vehicleList.size(); i++) {
          String motorInfo = "";
          String info = "";
          System.out.println();
          if (vehicleList.get(i) instanceof PassCar) {
              info = ((PassCar)vehicleList.get(i)).toString();
              **motorInfo = ((PassCar)vehicleList.get(i)).motor.toString();**
      
          }
          else if(vehicleList.get(i) instanceof Truck) {
              info = ((Truck)vehicleList.get(i)).toString();
              **motorInfo = ((Truck)vehicleList.get(i)).motor.toString();**
          }
      

      基本上我必须使用多态调用并检查它是否是 PassCar 或 Truck 的实例。 至于上课时用到的 Array 和 ArrayList,我是这样编辑的:

      Vehicle [] vehicles = new Vehicle [3]; 
      vehicles[0] = v0;
      vehicles[1] = v1;
      vehicles[2] = v2;
      
      showVehicle(vehicles);
      
      ArrayList<Vehicle> vehicleList = new ArrayList<Vehicle>(Arrays.asList(vehicles));
      System.out.println();
      System.out.println("Output from ArrayList in main: ");
      

      感谢大家的帮助!

      【讨论】:

      • 老实说,最好将Motor 作为Vehicle 的一部分,然后你就不需要上面的丑陋代码了。 TruckPassCar 都有一个引擎。如果您想创建没有Motor(自行车)的车辆,那么可以创建一个非引擎Motor
      • 我完全理解。通常我会这样做,但任务要求我这样做。感谢您的反馈
      • 在调用 toString 之前不需要演员表。这是解决这个问题的一种非常糟糕的方法。
      • 解决问题的方法有很多种,所以请保持开放的心态。也许下次再进一步阅读我明确说明为什么我不能以另一种方式做的地方。 @DawoodibnKareem
      猜你喜欢
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      • 2021-04-09
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多