I am trying to test my player class properly, I have almost done it but I am having issues with my p1.setPlayerHand method. This is the following code I have used for my player class:
Player Class:
package model;
public class Player
{
private String PlayerName;
private Hand PlayerHand;
private boolean Dealer;
public Player(String name)
{
PlayerName = name;
PlayerHand = new Hand();
Dealer = false;
}
public void setName (String name)
{
this.PlayerName = name;
}
public String getName()
{
return PlayerName;
}
public void setDealer (Boolean dealer)
{
this.Dealer = dealer;
}
public boolean getDealer()
{
return Dealer;
}
public void setPlayerHand (Hand hand)
{
this.PlayerHand = hand;
}
public void getHand()
{
PlayerHand.displayCardsinHand();
}
public static void main (String [] args)
{
Player p1 = new Player("player1");
Hand h = new Hand();
//System.out.println(p1);
p1.setName("BARRY");
System.out.println(p1.getName());
p1.setDealer(false);
System.out.println(p1.getDealer());
//this is the error that is preventing my program to run
p1.setPlayerHand(h.addCard(new Card(Suit.CLUBS, CardRank.ACE)));
p1.getHand();
}
}
The following error I receive (after testing the Player Class) is this:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method setPlayerHand(Hand) in the type Player is not applicable for the arguments (void)
at model.Player.main(Player.java:57)
This is the Hand Class underneath (that is linked to the Player Class):
Hand Class:
package model;
import java.util.Vector;
import java.util.Random;
public class Hand
{
private Vector<Card> hand;
public Hand()
{
hand = new Vector<Card>();
}
public void addCard(Card c)
{
hand.add(c);
}
public void displayCardsinHand()
{
for (int card = 0; card < hand.size(); card++)
{
System.out.println(hand.elementAt(card));
}
}
public int getCardsinHand()
{
return hand.size();
}
public Card getCard(int position)
{
if(position >= 0 && position < hand.size())
return (Card)hand.elementAt(position);
else
return null;
}
public int getScore()
{
int value = 0;
boolean ace = false;
for (int i = 0; i < hand.size(); i++)
{
Card c;
c = getCard(i);
value = value + c.getRankValue();
if(c.getRankValue() == 1)
{
ace = true;
}
}
if(ace == true && value + 10 <= 21)
{
value = value + 10;
}
return value;
}
public static void main (String [] args)
{
Hand h = new Hand();
System.out.println(h);
h.displayCardsinHand();
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.HEARTS, CardRank.ACE));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.SPADES, CardRank.JACK));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.DIAMONDS, CardRank.QUEEN));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.CLUBS, CardRank.KING));
System.out.println(h.getCardsinHand());
System.out.println(h.getCardsinHand());
h.displayCardsinHand();
h.getCard(1);
System.out.println(h.getScore());
}
}
I have tried modifying the p1.setPlayerHand testing numerous times. I appreciate any advice and tips on how to solve this issue, thank you.
If my code is too long for this post then I will gladly accept any advice on what I should do to cut it short (for future reference).
If anyone here required to see any other classes that I wrote (that may help them help me solve this error) then please notify me on here, thank you.
The method addCard doesn't return anything (void). So you can't pass the result of this method to setPlayerHand(Hand). That's what you're doing.
The code should compile and run if you change
p1.setPlayerHand(h.addCard(new Card(Suit.CLUBS, CardRank.ACE)));
to
h.addCard(new Card(Suit.CLUBS, CardRank.ACE));
p1.setPlayerHand(h);
This is because the setPlayerHand method needs to be passed an object of type Hand, but the addCard method doesn't return anything (it's declared as void).
Related
I'm trying to create a class that will do everything that a different class can do, but it will use random integers in order to create the objects that would normally require user input. Here I have a Pokemon program where I have class where the user creates a Pokemon trainer by inputting their name, and the program will create an ArrayList where the trainer's Pokemon are stored. I have a subclass called ComputerTrainer where it should have the same functionality, but randomly generated Pokemon will be added to the trainer's list of Pokemon. I created a constructor that accesses the protected variables in the PokemonTrainer class, but I'm getting an error that says "reason: actual and formal argument lists differ in length". Why I am getting this error?
Here is the code for the PokemonTrainer class:
import java.util.ArrayList;
public class PokemonTrainer
{
// private constants
private static final int MAX_POKEMON = 2;
protected ArrayList<Pokemon> pokemonList;
protected String name;
protected int numOfPokemon;
// Write your PokemonTrainer class here
public PokemonTrainer(String name)
{
this.name = name;
pokemonList = new ArrayList<Pokemon>();
}
public boolean addPokemon(Pokemon p)
{
if(numOfPokemon < MAX_POKEMON)
{
pokemonList.add(p);
numOfPokemon++;
return true;
}
else
{
return false;
}
}
public boolean hasLost()
{
int numOfPokemonThatLost = 0;
for(Pokemon p : pokemonList)
{
if(p.hasFainted())
{
numOfPokemonThatLost++;
}
}
if(numOfPokemonThatLost == numOfPokemon)
{
return true;
}
else
{
return false;
}
}
public Pokemon getNextPokemon()
{
int nextPokemon = 0;
int numOfPokemonThatLost = 0;
for(Pokemon p : pokemonList)
{
while(p.hasFainted() && nextPokemon < numOfPokemon)
{
nextPokemon++;
numOfPokemonThatLost++;
if(nextPokemon < numOfPokemon)
{
p = pokemonList.get(nextPokemon);
}
}
}
if(numOfPokemonThatLost == numOfPokemon)
{
return null;
}
else
{
return pokemonList.get(nextPokemon);
}
}
public Pokemon getPokemon(int nPokemon)
{
return pokemonList.get(nPokemon);
}
public int getNumberOfPokemons()
{
return pokemonList.size();
}
public static int getMaxPokemon()
{
return MAX_POKEMON;
}
public String toString()
{
return name;
}
}
and here is the code for the ComputerTrainer subclass:
import java.util.ArrayList;
import java.util.Random;
public class ComputerTrainer extends PokemonTrainer
{
// private constants
// Possible pokemon names and move names to generate random Pokemon
private static final String[] POKEMON_NAMES = {"Pikachu", "Bulbasaur", "Charmander", "Squirtle"};
private static final String[] MOVE_NAMES = {"Tailwhip", "Bodyslam", "Splash", "Shock"};
private static final int MAX_DAMAGE = 25;
private static final int MAX_MOVES = 4;
private PokemonImages images = new PokemonImages();
// Write a Constructor that sets the name of the ComputerTrainer
// and adds 2 randomly generated Pokemon to itself
public ComputerTrainer(String name)
{
this.name = name;
pokemonList = new ArrayList<Pokemon>();
for(int i = 0; i < PokemonTrainer.getMaxPokemon(); i++)
{
Random num = new Random();
int randomNumber = num.nextInt(POKEMON_NAMES.length);
Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
pokemonList.add(p);
numOfPokemon++;
}
}
/*
* Adds a randomly generated Pokemon to this ComputerTrainer's
* collection of Pokemon. A ComputerTrainer can only have 2
* Pokemon. This method returns true if there was room for the
* new Pokemon and it was successfully added, false otherwise.
*/
public boolean addRandomPokemon()
{
if(numOfPokemon < PokemonTrainer.getMaxPokemon())
{
Random num = new Random();
int randomNumber = num.nextInt(POKEMON_NAMES.length);
Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
pokemonList.add(p);
numOfPokemon++;
return true;
}
else
{
return false;
}
}
// Returns a Move randomly chosen from the set of Moves
// that this trainer's current Pokemon knows.
// If all Pokemon have fainted, returns null.
public Move chooseRandomMove()
{
Pokemon currentBattlingPokemon = getNextPokemon();
// This method isn't finished yet
}
}
The program outputs the following error:
ComputerTrainer.java:20: error: constructor PokemonTrainer in class PokemonTrainer cannot be applied to given types;
{
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
The problem is that PokemonTrainer only has a constructor that has one String as parameter:
public class PokemonTrainer
{
public PokemonTrainer(String name) {
...
}
but you are not calling that constructor from ComputerTrainer:
public class ComputerTrainer extends PokemonTrainer
{
public ComputerTrainer(String name) {
this.name = name;
...
}
}
Java does not automatically call the constructor of the superclass that matches the actual constructor, it calls the default (parameter-less constructor) but the superclass does not have it.
Solution: add an explicit invokation of the correct constructor of the superclass:
public class ComputerTrainer extends PokemonTrainer
{
public ComputerTrainer(String name) {
super(name);
...
}
}
see Java Language Specification 8.8.7. Constructor Body for more details
Note: the error message is a bit confusing since there is like a hidden super() call as first statement in the ComputerTrainer constructor
My problem is that, simply I don't know what code to use to get my value from my getX method to my other classses main method.
package hangman;
public class Hangman {
private int triesLimit;
private String word;
public void setTriesLimit(int triesLimit) {
this.triesLimit = triesLimit;
}
public void setWord(String word) {
this.word = word;
}
public int getTriesLimit() {
return this.triesLimit;
}
public String getWord() {
return this.word;
}
#Override
public String toString() {
return ("Enter Secret Word " + this.getWord()
+ ".\nEnter max # of tries (Must be under 7) "
+ this.getTriesLimit());
}
}
Thats from the sub-class and I am trying to store the value of the triesLimit into the main of this classes main method
package hangman;
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
Scanner scn = new Scanner(System.in);
int triesCount = 0;
int correctCount = 0;
hangman.toString();
int triesLimit = hangman.getTriesLimit();
String secretWord = hangman.getWord();
StringBuilder b = new StringBuilder(secretWord.length());
for (int i = 0; i < secretWord.length(); i++) {
b.append("*");
}
char[] secrectStrCharArr = secretWord.toCharArray();
int charCnt = secretWord.length();
for (int x = 0; triesCount < triesLimit; triesCount++) {
while (charCnt >= 0) {
System.out.println("Secrect Word :" + b.toString());
System.out.println("Guess a letter :");
char guessChar = scn.next().toCharArray()[0];
for (int i = 0; i < secrectStrCharArr.length; i++) {
if (guessChar == secrectStrCharArr[i]) {
b.setCharAt(i, guessChar);
correctCount++;
} else if (guessChar != secrectStrCharArr[i]) {
triesCount++;
System.out.println("Incorrect: " + triesCount);hangmanImage(triesCount,correctCount);
}
}
}
}
}
I tried looking it up on here but couldn't find setters and getters used in a sub/superclass
You need to create an instance of the class in the main method to access the variables and method available in that class like so
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
hangman.setTriesLimit(2)
int value = hangman.getTriesLimit();
}
You can look into static keyword to access the value directly but that requires a bit more understanding of OOP's and JAVA.
This should work fine.
Hope it helps :)
EDITED
ToString method is just to convert everything in your model class to String which you have done correctly,but you have implemented incorrectly.... Change your ToString content so
#Override
public String toString() {
return ("The Secret Word you entered: " + this.getWord()
+ ".\n The max # of tries (Must be under 7): "
+ this.getTriesLimit());
}
You have initialized Scanner which does what you want, to ask the user to enter the values but again you haven't implemented it so add this to your main method
Scanner scn = new Scanner(System.in);
hangman.setTriesLimit(scn.nextInt());
hangman.setWord(scn.next());
hangman.toString()//Will work now
Trial and error is your best friend now :)
and Google some of the issues rather than waiting for an answer :)
Like rohit said, this is as simple as understand the basics of OOP, specific the encapsulation.
If you want to get a little deeper into OOP patterns, you could use the Observer pattern. This allows you to change the status of any class instance, even if they're not related by inheritance, aggregation, etc.
You can scale the solution by making List of Observer
Your observable interface
public interface IObservable {
// Set the observer
public void setObserver(IObserver iObserver);
// Notify the observer the current status
public void notifyObserver();
}
Your observer interface
public interface IObserver {
public void update(boolean status);
}
Your observer implementation
public class PlayHangman implements IObserver {
private boolean status = false;
public void printStatus() {
System.out.println("Status: " + (this.status ? "Win" : "Lose"));
}
#Override
public void update(boolean status) {
// The instance status is updated
this.status = status;
// Print the current status
this.printStatus();
}
}
Your observable implementation
public class Hangman implements IObservable{
private String goalWord = "";
private String currentWord = "";
private int triesLimit = 0;
private int tries = 0;
private IObserver iObserver;
public Hangman(String goalWord, int triesLimit) {
this.goalWord = goalWord;
this.triesLimit = triesLimit;
}
public void setCurrentWord(String currentWord) {
this.currentWord = currentWord;
this.notifyObserver();
}
public void addTry() {
this.tries++;
this.notifyObserver();
}
#Override
public void setObserver(IObserver iObserver) {
this.iObserver = iObserver;
}
#Override
public void notifyObserver() {
// True = win
this.iObserver.update(this.tries < this.triesLimit &&
this.goalWord.equals(this.currentWord));
}
}
Your Main class
public class Main{
public static void main(String[] args) {
// PlayHangman (game status)
PlayHangman playHangman = new PlayHangman();
// Hangman initializes with a goalWord and the triesLimit
Hangman hangman = new Hangman("HangmanJava", 5);
// Set the observer
hangman.setObserver(playHangman);
// During the game you just can set the current word and add a try
// You're not setting the status directly, that's the magic of the Observer pattern
hangman.setCurrentWord("Hang");
hangman.addTry();
hangman.setCurrentWord("HangmanJava");
}
}
Hope this helps and enjoy Java
I'm writing a game-like program and it has a class that has to act as an item. Normally I would just keep it as an item but every one has to wait 10 game-days in order to start doing what it's meant to. Is there a way to update the days in all the classes at once? I've tried to use a static method but you can't use instance variables in those so it didn't work. I've thought about possibly making a code that expands every time a new instance is made but I can't find anything i can understand about it. Is there any way to add to a method, make this an item, anything? This is what I have at the moment:
public class Tree
{
private boolean fullGrown;
private int day;
private int APDay; //apples per day
private static int totalApples;
public Tree()
{
fullGrown = false;
day = 0;
APDay = (int) (Math.random()*2) + 4;
}
public void updateDay()
{
day = day + 1;
if (day == 10) fullGrown = true;
if (fullGrown == true) totalApples = totalApples + APDay;
}
public void skipGrowth()
{
fullGrown = true;
}
}
Although this works, you have to update the day for every instance separately. I need a way to update all the instances at the same time. This will also be used by a code and not the actual interface, just in case that's helpful.
Observer and factory pattern looks like a good candidate here.
I hope the code below explain rest to you
public interface DayEventListener {
public void onDay10(DayEvent DayEvent);
}
public class DayEvent {
//... pojo
}
public class AwesomeGame {
private List<DayEventListener> dayEventListenerList = new ArrayList<>();
public void addDayListener(DayEventListener del) {
dayEventListener.add(del);
}
public void fireDay10Event(DayEvent de) {
for(DayEventListener del : dayEventListenerList) {
del.onDay10(de);
}
}
public class Item implements DayEventListener {
//All constructors should be private
public static Item buildItem() {
Item Item = new Item();
awesomeGame.addDayEventListener(Item);
return item;
}
}
so I did some research and while I was working on another project I discovered that i could use a vector to keep track of all my instances, so here is that class:
import java.util.Vector;
public class catcher
{
private static Vector allInstances = new Vector();
private int catchLeft;
private String name;
public catcher(String name)
{
catchLeft = Integer.parseInt(name.substring(name.indexOf("#") + 1, name.length()));
catchLeft--;
this.name = name;
if (catchLeft != 0) allInstances.add(this);
}
public static synchronized Vector getAllInstances()
{
return (Vector) (allInstances.clone());
}
public boolean check(String name, boolean change)
{
boolean foo;
if (this.name.equals(name))
{
if (change == true) catchLeft--;
foo = true;
}
else foo = false;
if (catchLeft <= 0) this.finalize();
return foo;
}
public void finalize()
{
allInstances.removeElement(this);
}
public static void clear()
{
allInstances.clear();
}
}
now that I have a record of all the instances, I used this method in another class to assess all the instances:
import java.util.Iterator;
import java.util.Vector;
public class recipe
{
private boolean checkForList(String name, boolean add)
{
Iterator list = catcher.getAllInstances().iterator();
boolean running = true;
boolean booleanReturn = true;
while (running == true)
{
if (list.hasNext())
{
catcher Foo = (catcher) (list.next());
if (Foo.check(name, false) == true)
{
Foo.check(name, true);
running = false;
booleanReturn = true;
}
}
else
{
if (add == true) new catcher(name);
running = false;
booleanReturn = false;
}
}
return booleanReturn;
}
}
I'm sure that this can be modified to update the classes instead of just accessing them.
I'm trying to make a card game, and have my card class and my deck class sort of ready, it compiles ok, but when I try to run deck's method makeDeckFull, i get the output: invalidnumberinvalidnumber...
when I use the showDeck method I then see this instead of "hearts", 1
Cards#597f13c5 (i do not know what it means, or how to fix it)
Any help would be kindly appreciated: code below.
Deck Class:
import java.util.ArrayList;
public class Deck
{
private ArrayList<Cards> deck;
private int index;
public Deck()
{
deck = new ArrayList<Cards>();
}
public void makeDeckFull()
{
Cards h1 = new Cards("Hearts", 1);
Cards h2 = new Cards("Hearts", 2);
Cards h3 = new Cards("Hearts", 3);
deck.add(h1);
index ++;
deck.add(h2);
index ++;
deck.add(h3);
index ++;
//Rest of these is left out to conserve space
}
public void showDeck()
{
System.out.println(deck);
}
Card class:
public class Cards
{
private String HEARTS = "Hearts";
private String CLUBS = "Clubs";
private String DIAMONDS = "Diamonds";
private String SPADES = "Spades";
public int number;
public String suit;
public Cards()
{
suit = "unknown suit";
number = 0;
}
public Cards(String suit, int number)
{
setSuit(suit);
setNumber(number);
}
public void setCard(String suit, int number2)
{
setSuit(suit);
setNumber(number2);
}
public void setSuit(String newSuit)
{
if(
(newSuit.equalsIgnoreCase(HEARTS)) ||
(newSuit.equalsIgnoreCase(DIAMONDS)) ||
(newSuit.equalsIgnoreCase(CLUBS)) ||
(newSuit.equalsIgnoreCase(SPADES)))
{
suit = newSuit;
}
else
{
newSuit = "invalid";
System.out.print("Invalid");
}
}
public int getNumber()
{
return number;
}
public String getSuit()
{
return suit;
}
public void setNumber(int newNumber)
{
if(newNumber >0 && newNumber <=10)
{
number = newNumber;
}
else
{
number = 0;
System.out.print("invalid number");
}
}
}
1) You need to override toString() in the Cards class. As is, you are printing out the reference of the object(the gibberish) instead of the "data." You should also override the toString() method of Deck to only print out the list.
2) I'm stepping through your code snippet of makeDeckFull(), and it seems to work fine. Are you sure those three inserts are where you are getting the invalid print statements?
I have an assignment from my Java 1 class (I'm a beginner) and the question instructs us to make some code more object-oriented. I've done what I can for the assignment, but one of my files consistently gives me a Cannot Find Symbol Method error even though the files are in the same project. I know the methods are there, so what's going on? The error only occurs in AlienPack, which doesn't seem to recognize the other files, all of which are in the same project (including AlienPack). The getDamage() method that's being called in AlienPack isn't being found (it's in SnakeAlien, OgreAlien, etc).
EDIT: The new error for the getDamage() methods I'm trying to invoke in AlienPack is that the methods still aren't being found. AlienDriver can't find calculateDamage() either.
Here's the code I've got so far:
Alien:
public class Alien {
// instance variables
private String name;
private int health;
// setters
public void setName(String n) {
name = n; }
public void setHealth(int h) {
if(h>0&&h<=100) {
health = h;
} else {
System.out.println("Error! Invalid health value!");
System.exit(0); } }
// getters
public String getName() {
return name; }
public int getHealth() {
return health; }
// constructors
public Alien() {
setName("No name");
setHealth(100); }
public Alien(String n, int h) {
setName(n);
setHealth(h); }
public Alien(Alien anAlien) {
setName(anAlien.getName());
setHealth(anAlien.getHealth()); }
public Alien clone() {
return new Alien(this);
} }
SnakeAlien:
public class SnakeAlien extends Alien { // new file
// instance variables
private int damage;
// setters
public void setDamage(int d) {
if(d>0) {
damage = d;
} else {
System.out.println("Error! Invalid damage value!");
System.exit(0); } }
// getters
public int getDamage() {
return damage; }
// constructors
public SnakeAlien() {
super();
setDamage(0); }
public SnakeAlien(String n, int h, int d) {
super(n, h);
setDamage(d); }
public SnakeAlien(SnakeAlien anAlien) {
super(anAlien);
setDamage(anAlien.getDamage()); }
public SnakeAlien clone() {
return new SnakeAlien(this);
} }
OgreAlien:
public class OgreAlien extends Alien { // new file
// instance variables
private int damage;
// setters
public void setDamage(int d) {
if(d>0) {
damage = d;
} else {
System.out.println("Error! Invalid damage value!");
System.exit(0); } }
// getters
public int getDamage() {
return damage; }
// constructors
public OgreAlien() {
super();
setDamage(0); }
public OgreAlien(String n, int h, int d) {
super(n, h);
setDamage(d); }
public OgreAlien(OgreAlien anAlien) {
super(anAlien);
setDamage(anAlien.getDamage()); }
public OgreAlien clone() {
return new OgreAlien(this);
} }
MarshmallwManAlien:
public class MarshmallowManAlien extends Alien { // new file
// instance variables
private int damage;
// setters
public void setDamage(int d) {
if(d>0) {
damage = d;
} else {
System.out.println("Error! Invalid damage value!");
System.exit(0); } }
// getters
public int getDamage() {
return damage; }
// constructors
public MarshmallowManAlien() {
super();
setDamage(0); }
public MarshmallowManAlien(String n, int h, int d) {
super(n, h);
setDamage(d); }
public MarshmallowManAlien(MarshmallowManAlien anAlien) {
super(anAlien);
setDamage(anAlien.getDamage()); }
public MarshmallowManAlien clone() {
return new MarshmallowManAlien(this);
} }
AlienPack:
public class AlienPack { // new file, this one isn't recognizing the others
// instance variables
private Alien[] pack;
// setters
public void setPack(Alien[] aliens) {
pack = new Alien[aliens.length];
for(int i = 0; i<aliens.length; i++) {
pack[i]=aliens[i].clone(); } }
// getters
public Alien[] getPack() {
Alien[] temp = new Alien[pack.length];
for(int i = 0; i<pack.length; i++) {
temp[i]=pack[i].clone(); }
return temp; }
// constructors
public AlienPack() {
Alien[] nothing = new Alien[1];
nothing[0]=null;
setPack(nothing); }
public AlienPack(Alien[] aliens) {
setPack(aliens);}
// other methods
public int calculateDamage() {
int damage = 0;
for(int i = 0; i<pack.length; i++) {
if((new SnakeAlien()).getClass()==pack[i].getClass()) {
pack[i].getDamage() +=damage;
} else if((new OgreAlien()).getClass()==pack[i].getClass()) {
pack[i].getDamage() +=damage;
} else if((new MarshmallowManAlien()).getClass()==pack[i].getClass()) {
pack[i].getDamage() +=damage;
} else {
System.out.println("Error! Invalid object!");
System.exit(0); } }
return damage; } }
AlienDriver:
public class AlienDriver { // driver class
public static void main(String[] args) {
Alien[] group = new Alien[5];
group[0]= new SnakeAlien("Bobby", 100, 10);
group[1]= new OgreAlien("Timmy", 100, 6);
group[2]= new MarshmallowManAlien("Tommy", 100, 1);
group[3]= new OgreAlien("Ricky", 100, 6);
group[4]= new SnakeAlien("Mike", 100, 10);
System.out.println(group.calculateDamage());
} }
Two problems:
pack[i].getClass().getDamage() ...
should be just
pack[i].getDamage() ...
You seem to be confused about what the getClass() method does. It returns an object which represents the class (i.e. java.lang.Class) of another object. It is used for reflection. To invoke getDamage() you would just invoke it directly on pack[i] as shown above.
However...
You are attempting to invoke the method getDamage() using a reference of type Alien, which is a base class of all the concrete alien types. If you want to do it that way,
getDamage() needs to be declared abstract in the base class so it can be found and dispatched to the correct subclass when invoking it via an Alien reference.
In Alien:
public abstract class Alien {
...
public abstract int getDamage();
An alternative is to cast to the appropriate subclass at each point since you know what it is:
((SnakeAlien)pack[i]).getDamage() +=damage;
However (again) even that is wrong. You can't apply += to an "rvalue". What you need to do here is either:
Also declare setDamage() abstract in Alien and do pack[i].setDamage(pack[i].getDamage()+damage);
If casting, ((SnakeAlien)pack[i]).setDamage( ((SnakeAlien)pack[i].getDamage()) + damage);
My Recommendation:
In class Alien:
public abstract class Alien {
...
private int damage = 0; // Move damage up to the abstract base class
public int addToDamage(int n) { this.damage += n; }
...
}
In your driver, no need to test the class. Invoke the addToDamage() method on the Alien reference.
I think that at least part of your problem is the getClass() method. You are expecting it to return an object but it does not. Just call directly to the array.
pack[I].getDamage()
should work assuming that the correct type of object is stored in pack()