Can a class array contain subclass items?
I have one class named "Vessel". I have other 2 classes named "Ferry" & "Cargo" that extend the class "Vessel".
I need to make a 4th class that has the attribute "schedule", which is an array containing every ship. Each ship must be either of type "Ferry" or "Cargo".
So is this correct?
Ferry schedule[] = new Ferry[];
Could the above array contain objects of type "Ferry" and "Cargo" ? If not, how can I accomplish this?
Example:
class Vessel {
String name;
int length;
int year;
Vessel(String n, int l, int y) {
name = n;
length = l;
year = y;
}
}
class Ferry extends Vessel {
int passengerCount;
int carCount;
}
class Cargo extends Vessel {
int load;
}
class Port {
String portName;
Ferry schedule[] = new Ferry[];
}
This is standard polymorphism and inheritance. It works the same in Unity C# as every other C#. There are lots of non-Unity examples that are pretty thorough, and written by $$anonymous$$chers and so on, or at least have years or corrections and edits and replies.
'extends' is also kind of oddball syntax. $$anonymous$$ost people just use a colon. I'm wondering if your source for this is a little wonky, and maybe telling you to use inheritance when something else would be better in this case.
Answer by Glurth · Sep 05, 2017 at 06:08 PM
Vessel schedule[] = new Vessel[2];
This line declares and instantiates an array of Vessels. (We don't know what KIND of vessel each element in the array is... yet).
to add a ferry to element 0 of the array:
schedule[0] = new Ferry();
to add a cargo to element 1 of the array:
schedule[1] = new Cargo();
This is legal because both Cargo and Ferry ARE (derived from) Vessels.
Edit: Keep in mind the array variable, considers these to be Vessels, so elements in the array can only reference members of the Vessel class.
schedule[0].length = 23; // is legal
but
schedule[0].passengercount=100; // this is NOT legal
To get around this you CAN "cast" the array element to the appropriate vessel type:
((ferry)schedule[0])..passengercount=100; // this IS legal, but ONLY if the schedule[0] was ACTUALLY instantiated (new) as a ferry.
If the array element was actually instated as a new cargo(), this command will generate a run-time "type-mismatch" error. You can use GetType(), if you must, to check, but this is considered bad form.
Note: Unity serialization does NOT support inheritance. (this is only relevant if you want to SAVE the vessel array to disk). If it's just a runtime array, don't worry about this.
Thanks for your answer! I have one question though:
If I need to, let's say, get the attribute information (passengerCount, carCount) from a "Ferrie" on the array using a method, what should i do? Can't I use "schedule[x].GetData()" ?
( GetData() being a method inside class "ferry", returning passenger and car Count )
You can only get passengerCount
, carCount
from an element in the Vessel array, if the element was instantiated as a ferry e.g. schedule[x]= new Ferry();
You can check if the element was instantiated as a Ferry using the reflection Type class: eg. if(schedule[x].GetType() == typeof(Ferry) )
Then you can safely CAST the Vessel to a Ferry
Ferry aFerry= (Ferry)schedule[x];
But this generally considered bad design for inheritance ( though sometimes unavoidable). A "more inheritance based" approach would be to have your Vessel class define a virtual function like
virtual public bool CheckCapacity(Dock dockInfo){}
Your ferry class will "override" this function such that it checks against passengers
and cars
on the dock and in the ship. While you cargo class will check against load
on the dock and in the ship.
Now; when you look through all your vessels, you simply call CheckCapacity, and the appropriate function is called.
So, I wrote this:
public class Port {
Vessel schedule[] = new Vessel[3];
schedule[0] = new Ferry();
....
....
}
And I get this error for the second command. Any idea why?
"]" expected
invalid method decleration, return type required
The full script if it helps:
public class Port {
Vessel schedule[] = new Vessel[3];
schedule[0] = new Ferry();
/**
*
* @param args
*/
public static void main(String[] args) {
}
int getPassengers(Ferry f) {
return f.passengerCount;
}
int getCars(Cargo c) {
return c.load;
}
}
class Vessel {
String name;
int length;
int year;
Vessel(String n, int l, int y) {
name = n;
length = l;
year = y;
}
}
class Ferry extends Vessel {
int passengerCount;
int carCount;
public Ferry(String n, int l, int y, int pc, int cc) {
super(n, l, y);
passengerCount = pc;
carCount = cc;
}
}
schedule[0] = new Ferry();
this line of code needs to be inside a function, so the program knows WHEN to execute it. If you want to simply initialize your schedule array, with a default data, this correct syntax would be (edit/updated it, to use your constructors):
Vessel schedule[] = new Vessel[3]{
new Ferry("south harbor ferry",100,20),
new Cargo("The Filthy Gull",500),
new Ferry("north harbor ferry",80,30) };
also.. unity does not use or call:
public static void main(String[] args)
Perhaps you meant to define a "constructor"?
Oh wait.."extends".. is this java? Can't help with that syntax.
But isn't the original error where you declare an array of Vessel using C++-style syntax?
For future reference, as @Owen-Reynolds mentioned, you're declaring the array incorrectly.
You do Vessel schedule[] = new Vessel[3];
while the correct C# way is Vessel[] schedule = new Vessel[3];