- Home /
Using child class variables while in a parent class array.
Hello, I am having trouble with my inventory/item usage system (C#)
I have a base class Item, and a child class Weapon(more child classes in the future) that inherits from Item, and an Inventory array of type Item that can hold those items. Now if i create a new Weapon() (because it inherits from Item it can still be put to Item straight away even if its Weapon)and put it in the Inventory array everything is fine, i can access the variables in Item class, but not Weapon, and now I don't know what to do, because if I want to find out what Attack or something, that weapon has, I cant. Because I put it into an Item array, I cannot see its class Weapon variables unless I assign it to a Weapon variable while casting it as Weapon (since I'm assigning an Item class from the array to that new Weapon variable)
And I'm sure there has to be some better way, or I'm totally going the wrong way here, or I'm missing something here, some guidance and help and/or examples would be much appreciated.
What I want to achieve is: Have an Item class array that I can put all its child classes (weapon, armor, ammo, etc.) but be able to see and use the different child variables. I hope these code examples might make it any clearer.
public class Item { // Base Class
private string _name; // Variable
// Default/custom constructors and setters/getters somewhere here
}
public class Weapon : Item{ // Child class inherits from Item
private int _attack; // Variable
// Default/custom constructors and setters/getters somewhere here
}
private static Item[] _Inventory1 = new Item[50]; // The Item class inventory array
Inventory1[0] = new Weapon(); // puts a weapon class in the first slot of the array
Inventory[0].Name = "lalalal"; <--- Works fine
Inventory [0].Attack = 50; <--- does not because Attack is Weapon class variable and not Item...
Answer by Azrapse · Nov 06, 2013 at 01:25 PM
You gave yourself the solution. If you totally want to access the members of the derived class, you have to cast the reference to a variable of that type first.
Of course, before doing so, you must be totally sure that the item is indeed a weapon before casting it to the Weapon type.
If in the future you will have several kinds of items, and each must be dealt with in a different way, you will end with a long switch
or chained if...else
structure that kind of defeats the point of inheritance (why not just have a single Item class, with a field that is int itemType
?)
I don't know your code or what you are attempting to achieve in the bigger picture. But maybe what you need is to make use of polymorphism. I will give you a simple example:
Let's say that you want each item to describe itself, for some kind of tooltip. Normal items should only return their name, but weapons should also return their attack rating.
You could, of course, have a long chained if (item is Type1) else if (item is Type2)
... structure, or a switch
. But it would be much better if you add a virtual
method in the Item
class, that the children classes can redefine.
public class Item
{
private string _name; // Variable
public virtual string Describe()
{
return _name;
}
}
Then, in the Weapon
class you would have:
public class Weapon : Item
{
private int _attack; // Variable
public override string Describe()
{
return _name + " [Atk:" + _attack + "]";
}
}
Then you could just call the Describe
method on any item. Normal items will use the Describe
method defined in the Item
class, but weapons will use the Describe
method in the Weapon
class. (This is similar to what the .ToString()
method can do).
If you just want to be able to initialize your weapons with the extra parameters needed, consider adding all needed paramenters to the Weapon constructor, instead. Then you can add the weapon like
Inventory1[0] = new Weapon("lalalal", 50);
If you don't want to use constructors with parameters, and still want to initialize the Weapon without casting it first to a Weapon variable, use the object initializer:
Inventory1[0] = new Weapon{_name="lalalal", _attack=50};
but it will only work with public fields and properties. Not your case.
Ah yes the Virtual method, forgot about that. Thank you, you helped a lot, I think I see a way forward using it. If anyone else has any other ideas/suggestion I'll look into them too.
Thanks again Azrapse.
Your answer
Follow this Question
Related Questions
Inheriting from classes from other files (Javascript) 1 Answer
Class extends Object but does not inherit variables 1 Answer
Abstract class question 1 Answer
Defining and inheriting from a Javascript Class 0 Answers
Can't inherit from namespace 0 Answers