So I'm not exactly sure what you end goal is here, but let me take a quick guess at what you might be trying to do:
So you mentioned you have 2 subclasses of BaseBallPlayer
, let's say they are MajorLeaguePlayer
and MinorLeagePlayer
This private Array list teamArrayList
can be used to hold any combinations of your base class (BaseBallPlayer
-- in your case MajorLeaguePlayer
and MinorLeaguePlayer
).
You usually want to leave this teamArrayList private so that it will only be safely modified by your public methods. So for example you might want to have a constructor for PlayerDatabase
that takes an argument of ArrayList<BaseBallPlayer *>
PlayerDatabase(ArrayList<BaseBallPlayer *> players) {
// set the private teamArray list in the constructor
teamArrayList = players;
}
or you might want to sort the teamArray list based off of one of the properties in the base class BaseBallPlayer
// or another one sorting for weight or name
void sortPlayerListByHeight() {
// sort the private team array list
teamArrayList = ... // sort by height
}
Maybe you want to get the number of players in the list, or find the first or last player in the list. In general it's good practice to use public methods to access/modify private data members (i.e. teamArrayList)
int numberOfPlayersInList() {
return teamArrayList.LengthIs();
}
BaseBallPlayer getFirstPlayerInList() {
return teamArrayList.RetrieveItem.... // get the first item in the list
}
Then from another class you could construct some of your subclass objects and construct your player database:
ArrayList<BaseBallPlayer *> playerList = new ArrayList<>();
playerList.add(new MinorLeagePlayer("minorName", 180,70);
playerList.add(new MajorLeaguePlayer("majorName", 200, 72);
PlayerDatabase db = new PlayerDatabase(playerList);
// now you can do some operations on the PlayerDatabase knowing that the list will contain all objects that can use methods from the Base Class (`BaseBallPlayer`)
db.getFirstPlayerInList().print_player(); // method from your base class implemented in your subclasses
int numberOfPlayers = db.numberOfPlayersInList();
// do something with the number of players in the list
This is pseudo code, but hopefully it will help you get the idea.
Edit related to our comments:
ArrayList<BaseBallPlayer *> *playerList = new ArrayList<BaseBallPlayer *>();
MinorLeaguePlayer *aPlayer = new MinorLeaguePlayer();
playerList->InsertItem(aPlayer);
I've included a couple of simple cout statements in the ArrayList constructor, the MinorLeaguePlayer constructor, and the InsertItem method to output some information when they are called (I'm assuming you already have implementations of these methods):
ArrayList constructor: n_element = n;
cout << "Constructing the arrayList, n_element = " << n_element << endl;
MinorLeaguePlayer constructor: cout << "Constructing a minor league player" << endl;
InsertItem method: cout << "Inserting an item into the ArrayList" << endl;
Here's the output after building and running the above code:
Constructing the arrayList, n_element = 99
Constructing a minor league player
Inserting an item into the ArrayList
Edit 2 related to further comments:
Methods which take a reference to the elemType
Example:
// this will basically just going to "hold" the BaseBallPlayer fetched
// from GetNextItem
BaseBallPlayer *bPlayer;
playerList->GetNextItem(bPlayer);
cout << "Weight after fetching from list = " << bPlayer->weight << endl;
The implementation of GetNextItem is going to look something like this:
void ArrayList<elemType>::GetNextItem(elemType& player) {
// implementation to get the next item in the array list
player = //... set the "NextItem" to the BaseBallPlayer reference we passed into this method
}
Edit 3: print_player() polymorphism:
MinorLeaguePlayer *minPlayer = new MinorLeaguePlayer();
MinorLeaguePlayer *min2Player = new MinorLeaguePlayer();
MajorLeaguePlayer *majPlayer = new MajorLeaguePlayer();
MajorLeaguePlayer *maj2Player = new MajorLeaguePlayer();
playerList->InsertItem(minPlayer);
playerList->InsertItem(min2Player);
playerList->InsertItem(majPlayer);
playerList->InsertItem(maj2Player);
BaseBallPlayer *fetchedPlayer;
for (int i = 0; i < 4; i++) {
playerList->GetNextItem(fetchedPlayer);
fetchedPlayer->print_player();
}
Notice that you have to get the reference to the fetchedPlayer prior to calling the print_player() method on it
playerList->GetNextItem(fetchedPlayer);
fetchedPlayer->print_player();
This is because of the way your GetNextItem method is structured to place the reference to the nextItem in the passed in BaseBallPlayer.
Here's another example where the method would return the BaseBallPlayer instead of setting it by reference:
method stub (in ArrayList):
elemType getNextItemReturn();
for loop:
for (int i = 0; i < 4; i++) {
playerList->getNextItemReturn()->print_player();
}
Here's a link to a quick discussion asking which is more efficient:
Which is more efficient: Return a value vs. Pass by reference?
And the output with the example cout statements:
Constructing the arrayList, n_element = 99
Inserting an item into the ArrayList
Inserting an item into the ArrayList
Inserting an item into the ArrayList
Inserting an item into the ArrayList
Printing From MINOR League Player
Player Name: MinorLeagueName Weight = 22
Printing From MINOR League Player
Player Name: MinorLeagueName Weight = 22
Printing From MAJOR League Player
Player Name: MajorLeaguePlayer Weight = 33
Printing From MAJOR League Player
Player Name: MajorLeaguePlayer Weight = 33
The mock implementations of print_player():
void MinorLeaguePlayer::print_player() {
cout << "Printing From MINOR League Player" << endl;
cout << "Player Name: " << name << " Weight = " << weight << endl;
}
void MajorLeaguePlayer::print_player() {
cout << "Printing From MAJOR League Player" << endl;
cout << "Player Name: " << name << " Weight = " << weight << endl;
}