- Home /
The question is answered, right answer was accepted
Return a parent object to different derived objects from a function
resolved this thanks guys!
Answer by Glurth · Dec 30, 2014 at 10:07 PM
But I don't know how I can make it so that the function "AddCost" returns the correct CraftItem for different child class objects of the CraftItem class?
If the AddCost function is called by a Gun, the CraftItem returned WILL BE a Gun (and a CraftItem). In order to access the members that are in the Gun class, but not also in CraftItem, you will need to "explicitly cast" it e.g
Gun g=(Gun)someCraftItem;
g.shoot();
That is why I specified: "If the AddCost function is called by a Gun". Extending this... If the AddCost function is called by an Ammo, the return value WILL BE an Ammo (and a CraftItem).
Perhaps I misunderstand your question.
hmm lets see if I can clarify using your own code:
from the end of your addCost function
return this;
Which means, it will return whatever child-type of CraftItem the calling object is.
So for
new Gun$$anonymous$$4A4().AddCost(....)
When this AddCost function is called, the calling object is a newly created Gun$$anonymous$$4A4, so the return value will be a CraftItem of class Gun$$anonymous$$4A4.
And for the ammo,
new Ammo(Ammo.AmmoTypes.Pistol).AddCost(...)
When this addCost function is called by the newly create Ammo object, the return value will be a CraftItem of class Ammo.
So...
new Gun$$anonymous$$4A4().AddCost(ResourceItem.wood, 5).AddCost ()
Since the return type from the first AddCost call is a Gun$$anonymous$$4A4 class, then a Gun$$anonymous$$4A4 object (the same instance of the gun we just created, in fact) is also calling the second AddCost function, so the return type from the second call will ALSO be a Gun$$anonymous$$4A4.
Another way to put it is: you can always treat a Gun like a CraftItem, but you cannot treat just ANY CraftItem like a Gun, only those that were actually created with new Gun(). (Technical wording can be more precise: Whenever you reference "this" in a class (e.g parent), it will be of whatever class-type(e.g child) is specified in the "new" statement used to create the calling instance.)
How does this differ from what you would like, or is this what you actually wanted?
Thanks for the help, and I know what you mean, its just it gives that error when I AddCost because it's not been casted. But I can't cast it to any specific CraftItem because then the other CraftItems won't work, if I am correct? I appreciate the help man :)
But I can't cast it to any specific CraftItem because then the other CraftItems won't work, if I am correct?
Yes AND No (sorry). While you must indeed be careful not to cast an ammo:craftItem into a Gun:craftItem type, it is perfectly safe to cast a craftItem that was created as a gun:craftItem, explicitly into a gun. In fact you $$anonymous$$UST do this if you want to access members that are unique to a gun (like say ... gun.shoot()).
Now if you are keeping a list of CraftItem, of various subclasss, you need to $$anonymous$$A$$anonymous$$E SURE the subclass of a particular list element is a gun, before you explicitly cast it into a gun.
Usually this is not necessary though, with the use of OVERRIDES (I think this is the part of the inheritance scheme you are missing). When you override a function, you are creating the same exact function definition (name, return type, parameter count & types) you have in the parent class, but in the child class the body of the function is different. When you call that overriden function on an instance of the parent class, it will automatically, call ins$$anonymous$$d, the correct child class version of that function. Once you are inside these overriden functions, explicit casting is no longer neccessry, and you can access other members of the child-class, normally.
here is an example of override in child classes.
Class CraftItem{
string Foo(){return "parent"};
}
Class Gun:CraftItem
{
override string Foo(){Shoot(); return "gun";}
void Shoot();
}
Class Ammo:CraftItem
{
override string Foo(){checkClip(); return base.Foo()+"ammo";}
bool checkClip();
}
So, you wouldn't need to do ANY casting, if you wanted to call Foo() on a whole list of craftitems. Each one would call the appropriate subclass version, so all the guns in the list would also shoot(), and all the ammos would also checkClip(). (I threw in the Base.Foo() so you could how to access the craftItem version of Foo(), from within the childclass Ammo)
EDIT: here is a sample usage of the above
...
...
CraftItem[] itemArray=new CraftItem[2];
itemArray[0]= new Gun(); //when we instantiate we define which child class of CraftItem
itemArray[1]= new Ammo(); // no casting is needed in this "dircetion"
itemArray[0].Foo(); //this will shoot, and return the word "gun"
itemArray[1].Foo(); //this will checkClip, and return the word "parentammo"
//if shoot were a public function...
((Gun)itemArray[0]).shoot() //this is an excplicit cast from CraftItem to Gun. It will work in this case.
((Gun)itemArray[1]).shoot() //this will probabaly generate a runtime error, because the craftItem is NOT a gun.
...
...
I love to help, but only so much we can do here. Though I think we have just about covered your OP, I suggest you find some REAL lessons on c# inheritance, rather than my piecemeal ramblings here.
Answer by Kiwasi · Dec 31, 2014 at 12:53 AM
You need a generic function.
http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx
Follow this Question
Related Questions
Counting active objects in a list 3 Answers
onmousedown on object teleport 1 Answer
What are GameTiles? 1 Answer
How to change scenes without reloading them. 2 Answers
Dynamically Adding Objects 1 Answer