Inheritance and accessing a class

Hi there.

I'm making a small 3D game in XNA/C# and I'm having a bit of trouble with inheritance.
I have several classes that inherit from each other, but now I need to be able to access all of them from 1 function.

I'll try to explain as clearly as possible.

I have a virtual class, BasicModel and 2 classes that inherit from it, StaticModel and AnimationModel.

I also have a virtual class called GameObject and 2 classes that inherit from it, StaticObject and AnimationObject.

StaticObject has a StaticModel object in it and AnimationObject has an AnimationModel object in it.
Both Object classes have a method called GetModel, which returns the StaticModel and AnimationModel respectively. Because I need to be able to get that model class without knowing what type it is, I added a GetModel method in the GameObject class that returns a BasicModel.


Now I want to check if 2 objects collide with each other with a method in another class which looks like this:
CollisionCheck(GameObject object1, GameObject object2)
{
   object1.GetModel().Check(object2.GetModel());
}
These GameObjects can be either a StaticObject or an AnimationObject.
Now the problem is, GetModel always returns the BasicModel object from the GameObject class. I can't use override on the GetModel methods of StaticObject and AnimationObject because the return type is not the same.

Simply put, when I call object1.GetModel(), I need it to return either a StaticModel or an AnimationModel depending on wether it is a StaticObject or an AnimatedObject.


I pasted some code below.
How can I get GetModel to return the correct value?

Thanks in advance.





// MODELS
//-----------
 
public class BasicModel
public class StaticModel : BasicModel
public class AnimationModel : BasicModel
 
 
// GAMEOBJECT
//------------------
 
    public class GameObject
    {
        protected BasicModel MyModel;
 
        public virtual BasicModel GetModel
        {
            get { return MyModel; }
        }
    }
 
 
// STATICOBJECT
//-------------------
 
    public class StaticGameObject : GameObject
    {
        protected new StaticModel MyModel;
 
        public StaticModel GetModel
        {
            get { return MyModel; }
        }
    }
 
 
// ANIMATIONOBJECT
//-------------------------
 
    public class AnimatedGameObject : GameObject
    {
        protected new AnimationModel MyModel;
 
        public AnimationModel GetModel
        {
            get { return MyModel; }
        }
    }
 
 
// COLLISION
//--------------
 
   public class CollisionManager
    {
        public float? CursorBoundingSphereCheck(Cursor cursor, GameObject object1)
        {
            float? check = null;
 
// This line gives an error, object1.GetModel is null, because it uses the GetModel method from the GameObject class even if object1 is a StaticObject or AnimatedObject.
                check = object1.GetModel.BoundingSphere.Intersects(cursor.CalculateCursorRay(Engine.CameraManager.ActiveCamera.Projection,
                                                                              Engine.CameraManager.ActiveCamera.View));
 
                if (check != null)
                    object1.GetModel.Collides = true;
            
            return check;
        }
    }

Open in new window

LVL 2
SnapplesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AruspexCommented:
2 suggestions i can think of that would help your situation is:

1) Implement Interfaces and have your methods return interface type ensuring that interfaces implement inheritance also.
2) Use a generic method hence return whatever type is required.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tcullerCommented:
This is where polymorphism gets interesting. The thing is, your method actually is returning the appropriate type; however, the reference just "thinks" its a different type. Because of Polymorphism, the correct method is always called. For example, take a look at the following:

public class SamplePolymorphism
{
     public override String ToString()
     { return "Hey I'm not returning System.Object!"; }
}

Then try calling the following:

public static void Main()
{
     Object sample = new SamplePolymorphism() as Object;
     Object obj = new Object();
     Console.WriteLine("Sample: {0}\n\nObject: {1}", sample.ToString(), obj.ToString());
}

Notice that both references are Objects; however, their ToString methods return entirely different values! This is the result of what's called "Virtual Table", or v-table for short. Basically, every class has a 'small' table that dynamically links overrides to virtual methods. The details are out of the scope of this question.

Anyways, use the "as" operator to force the compiler to by-pass type-checking, as long as you know what you're doing. Even if you pass an AnimatedGameObject as a GameObject, the appropriate methods are still called on the passed object. Its true type is unaffected. However, if you need to access methods that are exclusive to that type, use the as operator. You can store the result and then use it, like this:

AnimatedGameObject animObj = myObj as AnimatedGameObject;
// Use methods

Or, you can just do this:
(myObj as AnimatedGameObject).NameOfMethod();

The disadvantage of the second part is that you need to do that every time you access an exclusive member.

Hope I helped,
Nate
0
SnapplesAuthor Commented:
Aruspex:
Sorry, i've never used generic classes before. I looked it up but all I can find are PrintArray examples that print ints or doubles, it's not all that clear to me.


tculler:
I gave your method a try, (see code snippet), and it works that way but the problem is, in that method I don't know if I have to use "as StaticGameObject" or "as AnimatedObject".

I gave this a try as my method in AnimatedObject:
        public override BasicModel GetModel
        {
            get { return MyModel as AnimationModel; }
        }
but that doesn't work either.
        public float? CursorBoundingSphereCheck(Cursor cursor, GameObject object1)
        {
            float? check = null;
 
 
                check = (object1 as AnimatedGameObject).GetModel.BoundingSphere.Intersects(cursor.CalculateCursorRay(Engine.CameraManager.ActiveCamera.Projection,
                                                                                    Engine.CameraManager.ActiveCamera.View));
 
                if (check != null)
                    (object1 as AnimatedGameObject).GetModel.Collides = true;
            
            return check;
        }

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.