Q:

Why method is not found?

Hi I created an object but its method is not found by the compiler.
The Test class :
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

This is the class which I ran and I got the following output: 
$ 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

Other classes:
MouseMat class:
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 class:
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 class:
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

 Some informations:
 The MouseMat class extends TextDescription class
 The TextDescription class extends StockItem class
 The setDescription method is in TextDescription class
 The MouseMat object is assigned to StockItem object
 May I know why the setDescription method is not found? Thanks.

A:

You check whether your StockItem is a TextDescriptionStockItem:
  private static void testItem(StockItem item){
    if(item instanceof TextDescriptionStockItem){
      testDescription(item);
    }//if
  }//testItem

But then you declare your method to generally take StockItem:
private static void testDescription(StockItem item){

Since this method now declares that it works for all StockItems, it can not call TextDescriptionStockItem specific methods.
You should explicitly say that this method requires an item with descriptions:
private static void testDescription(TextDescriptionStockItem item){

and then call it accordingly by casting the item, since you've already verified that it's of the correct type:
  private static void testItem(StockItem item){
    if(item instanceof TextDescriptionStockItem){
      testDescription((TextDescriptionStockItem) item);
    }//if
  }//testItem

Note that using instanceof like this is a bit of a code smell. Chances are that since your TestStockItemSubclasses class appears to assume that all the items it deals with are TextDescriptionStockItem and not just StockItem, it should explicitly declare this by using TextDescriptionStockItem everywhere instead.
The benefit of this is that the compiler can check your objects at compile time, instead of you having to do an instanceof at runtime. If someone comes along and adds a non-descriptive StockItem to your array, the compiler will say that this won't work, instead of the item being silently skipped over by your current code ("guess it must be free then!", hurr hurr).

