7
votes

hey i am thinking if i could make instance of a class with in itself...

My problem is that i ma creating 3D Spheres for planets & their moons whose data i am keeping in Object. I pass parameters to the constructor of my planet class for "Size" "Orbital Radius" "Texture" "Revolution Speed" etcetra. I Have to make another class for Moon's of Planets which is an exact duplicate of moon class.

I was thinking if i could make the class object within itself. Pass a parameter for list\array of Objects of itself to create and like for earth i will pass "1" to create one moon and as the moon will have the same constructor i will pass "0" for no moons of moon. to create.

Something like this

class Planet
{
    Model     u_sphere;
    Texture2D u_texture;
    //Other data members

    List<Planet> Moons = new List<Planet>(); 

    Planet()
    {
    //Default Constructor
    }

    //Overloaded\Custom Constructor
    Planet(Model m, Texture2D t, int moon_count)
    {
       u_sphere  = m;
       u_texture = t;

       while(moon_count > 0)
       {
           Model     moon_sphere = LoadMesh("moon.x");
           Texture2D u_texture   = LoadTexture("moon.bmp"); 
           Planet    temp        = new Planet(moon_sphere,moon_texture,0);
           Moons.Add(temp);
           moon_count--;
       }
    }
    //Others Getters & Setters
}
  • Is it some how possible?

  • or What is the best-practice\approach to this kind of problem?

p.s I am using C# & Microsoft X.N.A Framework

6
Why not try it? This works just like you’ve written. (Of course, the while loop can be made simpler.)Konrad Rudolph

6 Answers

7
votes

Yes, why not? But you may want to make an base-class of type CelestialBody from which both your Planet and Moon classes will inhert. And you don't have to pass a Planet's Moons into the constructor, but you can just make Planet look like this:

public class Moon : CelestialBody
{
    //Moon-only properties here.
}

public class Planet : CelestialBody
{
    //Planet-only properties here.
    public List<Moon> Moons { get; set; }
}

And then add Moons like this:

myPlanet.Moons.Add(new Moon(...));

E.g. abstract-away some of the information since a Moon is not a Planet.

2
votes

A more object-orientated approach could be separate any moon specific code into its own class. This might help keep your code more organised as it gets larger. I know a moon is not really a planet, but who cares?

A downside to this however is that you are now limiting your iheritance options, so it is a design decision you would have to think about.

class Planet 
{     
    Model     u_sphere;
    Texture2D u_texture;
    List<Planet> Moons = new List<Planet>();

    Planet(){}

    Planet(Model m, Texture2D t, int moon_count)     
    {
        u_sphere  = m;
        u_texture = t;

        while(moon_count > 0)        
        {
            Planet    temp        = new Moon();
            Moons.Add(temp);
            moon_count--;
        }     
    }
} 


class Moon : Planet
{   
    Moon()
    {
        u_sphere  = LoadMesh("moon.x");
        u_texture = LoadTexture("moon.bmp");
    }
}
0
votes

Sure. You're just reusing the class again. Keep in mind, that some properties of the class may no longer apply (there's no such thing as moons of moons, is there?)

You may want to add a constructor that passes a boolean, isChild. That way the nested child can be aware that it is indeed a child.

0
votes

What you've got already seems pretty accurate. One possible improvement would be to make a new class called Moon and have it inherit from Planet. That way, you could add additional properties/functionality for Moon, such as storing a reference to the owning Planet.

0
votes

Of course, this is valid code.

This type of design might be questionable for other reasons though. Why would a Planet class know how to create other Planet instances etc. It's much clearer if the logic creating planets are outside the class imo.

0
votes

While your code is ok, it just looks like it is a little bit too close to an infanite loop for my taste. If ever you changed that 0 to a 1 then BANG! One way to make this more robust would be to create an extra constructor and chain them. This way there is no recursion.

Planet(Model m, Texture2D t, int moon_count) : this(m, t)
{
    while(moon_count > 0)
    {
        Model     moon_sphere = LoadMesh("moon.x");
        Texture2D u_texture   = LoadTexture("moon.bmp");
        Planet    temp        = new Planet(moon_sphere, moon_texture);
        Moons.Add(temp);
        moon_count--;
    }
}

Planet(Model m, Texture2D t)
{
    u_sphere  = m;
    u_texture = t;
}