Accessing subclass method from arraylist of superc

2019-08-11 11:28发布

For an assignment, I have an ArrayList of type "Reference". Reference is a parent class to the "Book" class and "Journal" class. If I am allowed to add objects of type "Book" and "Journal" to the Arraylist, why would I be getting an error if I want to access methods of Book and Journal via the following code?

          ArrayList.get([someindex]).someBookorJournalMethod()

The arraylist itself is of the parent class, and the methods I want to access are only defined for either book or either journal.

EDIT: Here is some code

  public class Books extends Reference{

   private String Authors;
   private String Publishers;


      public Books(String CallNum, String Author, String Title, String Publisher, int year,String type)
      {

          super(CallNum,Title,year,type);

          Authors= Author;
          Publishers=Publisher;
      }

public String getAuthor()
{
    return Authors;
}



 public class LibrarySearch {


      private ArrayList<Reference> Library;


      public LibrarySearch()
      {
          Library = new ArrayList<Reference>(100);
      }


      public outputLibrary(){

      for (int i = 0 ; i < Library.size(); i+++)
      {
        if (Library.get(i).getType().equals("Book"))
        {
            System.out.println("Type:book\n" + "Call Number:" +  Library.get(i).getCallNumber() +"\n" + "Authors:" + Library.get(i).getAuthors();)
        }
    }

}

IntelliJ is having issues with the line Library.get(i).getAuthors() because it is a method specific to Books. How would I resolve this?

2条回答
看我几分像从前
2楼-- · 2019-08-11 11:28

You can't access the method of a subclass from the superclass. So you'll need to cast to a Book or a Journal.

Reference r =ArrayList.get([someindex]);
if (r instanceof Book) {
    ((Book) r).someBookMethod();
} else if (r instanceof Journal) {
     ((Journal) r).someJournalMethod();
} 
查看更多
疯言疯语
3楼-- · 2019-08-11 11:50

Because when you specify the type of a variable, you can only invoke methods that are defined for this type. For example, if you have

public class A {
  public void methodA() {
    System.out.println("A");
  }
}

public class B extends A {
  public void methodB() {
    System.out.println("B");
  }
}

public class Main {
  public static void main(String[] args) {
    A ab = new B();
    ab.methodB();
  }
}

This will not compile, since the type defined for the variable ab is A and the only visible methods are those that are defined in A.

In your case you can simply add a blank method in Reference(if you don't want to make the class abstract):

public void someBookorJournalMethod() {}

Or you can explicitly cast the object you're trying to invoke the method for.

However, it is important to note that both approaches are usually bad practices and should be avoided. If it does not make sense to instantiate Reference objects, than make the class abstract and define someBookorJournalMethod as an abstract method. In your code you're most probably using inheritance in a wrong way.

查看更多
登录 后发表回答