I have an ArrayList with a certain class (Piece) from which I want to pick items with a subclass (Miner and Bomb). However, when I pick some items it will use the methods of the super class (Piece), and not it's subclasses.
Since ArrayList<Pieces> will contain several subclass objects of pieces, it is not possible to define a more specific class for ArrayList. Is it possible to pick some elements from ArrayList and still use the methods from the subclasses?
(I found it a little hard to find the solution for this simple problem. I searched for overriding, arrayList, methods along some other things, but couldn't find it. If it was too obvious to found, I'd like to know where you found it.)
Class Main:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Piece> pieceList = new ArrayList<>();
pieceList.add(new Miner());
pieceList.add(new Bomb());
// create new classes to test canDefeat
if (new Miner().canDefeat(new Bomb())) {
System.out.println("Yes! This line will be printed.");
}
System.out.println();
// test canDefeat with pieces from the pieceList
if (pieceList.get(0).canDefeat(pieceList.get(1))) {
System.out.println("No, this line will not be printed");
}
}
}
Class Piece:
public abstract class Piece {
public boolean canDefeat(Piece opponent) {
return false;
}
}
Class Miner:
public class Miner extends Piece {
public boolean canDefeat(Bomb opponent) {
return true;
}
}
Class Bomb:
public class Bomb extends Piece {
}
Minerdoes not override thecanDefeat-method ofPiecebecause the parameter type is narrowed. You can check this easily by addingto the method you think you are overriding to verify it at compile time.
Furthermore, it is not good OO style to provide default behavior in abstract super classes but rather move the behavior into concrete children where possible because otherwise you may involuntary inherit behavior you otherwise would like to overwrite. In your case, make
canDefeatabstract and letBombimplement it with the behavior currently present inPiece.