Reputation: 20022
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
Upvotes: 7
Views: 4328
Reputation: 7546
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");
}
}
Upvotes: 2
Reputation: 27831
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 Moon
s 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 Moon
s like this:
myPlanet.Moons.Add(new Moon(...));
E.g. abstract-away some of the information since a Moon
is not a Planet
.
Upvotes: 7
Reputation: 7546
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;
}
Upvotes: 0
Reputation: 133188
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.
Upvotes: 0
Reputation: 37516
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
.
Upvotes: 0
Reputation: 13377
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.
Upvotes: 0