嗨,我创建了一个对象,但编译器未找到其方法。
测试类:

public class TestStockItemSubclasses{
  public static void main(String[] args) {
    StockItem[] itemArray = new StockItem[2];
    itemArray[0] = new MouseMat("A colorful black mouse mat", 499, 10);
    itemArray[1] = new MouseMat("A really fake mouse mat", 299, 10);

    for(StockItem item : itemArray){
      testItem(item);
    }//for
  }//main

  private static void testItem(StockItem item){
    if(item instanceof TextDescriptionStockItem){
      testDescription(item);
    }//if
  }//testItem

  private static void testDescription(StockItem item){
    item.setDescription("A really fake but colorful black mouse mat");
    System.out.printf("%-99s%-2s%n", "change description of the item", "||");
    System.out.printf("%-99s%-2s%n", item, "||");
  }//
}//TestStockItem


这是我运行的课程,并获得以下输出:

$ javac TestStockItemSubclasses.java
TestStockItemSubclasses.java:58: error: cannot find symbol
    item.setDescription("A really fake but colorful black mouse mat");
        ^
  symbol:   method setDescription(String)
  location: variable item of type StockItem
1 error


其他班:
MouseMat类:

public class MouseMat extends TextDescriptionStockItem{
   public MouseMat(String description, int price, int quantity){
     super(description, price, quantity);
   }//MouseMat

   @Override
   public String getStockType(){
     return "Plain blue cloth, foam backed";
   }//getStockType
}//class


TextDescription类:

public abstract class TextDescriptionStockItem extends StockItem{
  private String description;
  public TextDescriptionStockItem(String description, int price, int amount){
    super(price, amount);
    this.description = description;
  }//TestDescriptionStockItem

  @Override
  public String getDescription(){
    return description;
  }//getDescription

  public void setDescription(String description){
    this.description = description;
  }//setDescription

}//class


StockItem类:

public abstract class StockItem{
  private static int stockCodeCount = 0;
  private final int stockCode;
  private int price;
  private int quantity;

  public StockItem(int price, int quantity){
    this.price = price;
    this.quantity = quantity;
    stockCode = ++stockCodeCount;
  }//constructor


  public int getStockCode(){
    return stockCode;
  }//getStockCode

  public abstract String getStockType();

  public abstract String getDescription();

  public String toString(){
    return "SC" + getStockCode() + ": " + getStockType() + ", "
           + getDescription() + " (" + getQuanityInStock() + " @ "
           + getPriceExVat() + "p/" + getPriceIncVat() + "p)";
  }

}//class


 一些信息:
 MouseMat类扩展了TextDescription类
 TextDescription类扩展了StockItem类
 setDescription方法在TextDescription类中
 MouseMat对象分配给StockItem对象
 我可以知道为什么找不到setDescription方法吗?谢谢。

最佳答案

您检查您的StockItem是否为TextDescriptionStockItem

  private static void testItem(StockItem item){
    if(item instanceof TextDescriptionStockItem){
      testDescription(item);
    }//if
  }//testItem


但是然后您声明您的方法通常采用StockItem

private static void testDescription(StockItem item){


由于此方法现在声明适用于所有StockItem,因此无法调用TextDescriptionStockItem特定方法。

您应该明确地说此方法需要带有说明的项目:

private static void testDescription(TextDescriptionStockItem item){


然后通过投射项目来相应地调用它,因为您已经验证了它的类型正确:

  private static void testItem(StockItem item){
    if(item instanceof TextDescriptionStockItem){
      testDescription((TextDescriptionStockItem) item);
    }//if
  }//testItem




请注意,像这样使用instanceof有点代码味道。可能是因为您的TestStockItemSubclasses类似乎假定它处理的所有项目都是TextDescriptionStockItem而不只是StockItem,所以它应该在所有地方都使用TextDescriptionStockItem明确声明这一点。

这样做的好处是,编译器可以在编译时检查对象,而不必在运行时执行instanceof。如果有人出现并向您的数组中添加了一个非描述性的StockItem,编译器会说这是行不通的,而不是您的当前代码无声地跳过了该项目(“猜想它一定是免费的!” )。

07-27 15:16