- Home /
Derived Class Fields
When I pass a derived class object in as a base class object I can't seem to access the derived class fields. An example may help:
class BaseClass {
// base class fields
string name;
public virtual void SomeMethod(BaseClass obj) { }
}
class DerivedClass : BaseClass {
// Derived class specific fields
float number = 0;
// constructor
public DerivedClass(float num) {
number = num;
}
public override void SomeMethod(BaseClass obj) {
DerivedClass c = obj as DerivedClass;
print(c.number.ToString()); // prints "0", the default value
}
}
class Program {
BaseClass c = new DerivedClass(10);
SomeMethod(c);
}
If I use:
print(obj.GetType());
In "SomeMethod" in "DerivedClass" it does print the correct type (DerivedClass) but the cast causes the object to lose all it's initialized values. How do I access the values of a DerivedClass object after it has been pass in as a BaseClass object?
EDIT: To clarify. The different classes are not in the same place so I can't just call "SomeMethod", I do need an these instances.
Also, the reason I need use such inheritance is I do not know ahead of time what object the player is aiming at at the time. The player casts a ray and then calls on the objects type by it's parent type "BaseClass". It is then up to the subtype class (returned by GetComponent()) to determine how to handle the exact specifics of how to treat the object that was passed in as an argument. The problem is is that the parameter is of BaseClass type but I need the derived class fields that it contains.
Hope this helps explain my confusing situation. Thanks for all replies.
Answer by Doireth · Sep 27, 2012 at 06:02 PM
Solved: The inheritance structure was fine and the object types were functioning correctly. The problem was the objects I was passing were been instantiated (like I wanted) but a piece of legacy code was overriding those objects returning them to their default values.
Thanks for those who replied.
It would be good form to accept Bunny's answer, as he/she/it did post a variant of your code that worked.
@kmeboe A fair point and one I considered (credit where credit is due). The reason I didn't was to draw attention to what solved the exact problem I was having. Also, while Bunny's answer could have been valid it wasn't in this particular case. His/her answer was based on my poor explanation of my problem which resulted in it been (inadvertently) irrelevant. I'm not been ungrateful for his time.
Answer by Bunny83 · Sep 27, 2012 at 04:54 PM
Your usage of SomeMethod doesn't make much sense. It's a member function of your class. You call it in a different class without an instance. Also you can't just "write code" in a class. You can't call a function like you did in your Program class. Method calls can only be made inside of another method.
I guess you want something like that:
class BaseClass
{
private string name;
public virtual void SomeMethod() { }
}
class DerivedClass : BaseClass
{
// Derived class specific fields
private float number = 0;
// constructor
public DerivedClass(float num)
{
number = num;
}
public override void SomeMethod()
{
print(number.ToString());
}
}
// [some where else]
void SomeOtherMethod()
{
BaseClass c = new DerivedClass(10);
c.SomeMethod(); //--> prints "10"
}
btw this is actually nothing Unity specific. May i ask where you need such an inheritance? Keep in mind that Unity can't serialize derived classes that are stored in a base-class pointer because Unity serialized on the variable type, not the actual type.
An exception is the MonoBehaviour class. Since each MonoBehaviour is serialized on it's own you can assign a derived class to a base class variable as long as baseclass is derived from MonoBehaviour.
Beat me to it! +1.
I'd also like to add: the OP should be a little careful with patterns like calling a virtual method on a type, and then passing in that same type. There are specific examples of this that are valid (e.g. copy constructors, etc), but just make sure you know what you're doing so that you don't get confused between "this" and the argument.
Answer by MarkFinn · Sep 27, 2012 at 04:55 PM
The full answer to this would be an entire crash course in Object Orientated Coding. However, I believe there are limitations to the length these answers can be, so lets see if we can't simplify a bit.
When you cast to a base (or parent) class, all references to the object through that name are treated exactly as if it were genuinely that parent class, so by default the additional fields/methods in the derived class are not available. Casting to parent classes is best done only when you no longer need the additional functionality of the child class.
However, there are of course always special situations where "best done" no longer applies.
These are generally related to storage, arrays of related but not identical object types, comparison of apples and pears (not quite apples, but they're both fruit, so that's fine, right?) and so on.
When you hit this point, it's always best to pause a moment and meditate on the eternal koan : "do I really want to do this?".
Can you cast it back to a child class and get the values that way? Sometimes yes, but this is a nasty hack as you then have to keep track of whether or not each item is actually of the correct child class (And if you're doing that, well, why aren't you storing them as the child class in the first place?)
This is where virtual classes come into play.
Again, a bit longer than we want to get into here, and covered a million times over, a lot better than I can here on a million c# howto pages. Just Google "c# virtual howto".
Good luck on the quest for O.O. stylings and structures.