【问题标题】:Object of a class within itself自身内部的类的对象
【发布时间】:2011-05-12 13:07:39
【问题描述】:

嘿,我在想我是否可以创建一个类的实例......

我的问题是我正在为行星及其卫星创建 3D 球体,我将其数据保存在 Object.我将参数传递给我的行星类的构造函数,用于“大小”“轨道半径”“纹理”“转速”等。我必须为 Moon's of Planets 制作另一个类,它与 moon 类完全相同。

我在想我是否可以在自身内部创建类对象。为自己的对象列表\数组传递一个参数来创建和喜欢地球,我将传递“1”来创建一个月亮,因为月亮将具有相同的构造函数,我将传递“0”来表示没有月亮。创建。

类似的东西

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
}
  • 这怎么可能?

  • 或者什么是此类问题的最佳实践\方法?

p.s 我正在使用 C# 和 Microsoft X.N.A 框架

【问题讨论】:

  • 为什么不试试呢?这就像你写的那样工作。 (当然,while 循环可以更简单。)

标签: c# oop xna


【解决方案1】:

是的,为什么不呢?但是您可能想要创建一个CelestialBody 类型的基类,您的PlanetMoon 类都将从中继承。而且您不必将PlanetMoons 传递给构造函数,但您可以使Planet 看起来像这样:

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

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

然后像这样添加Moons:

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

例如抽象出一些信息,因为 Moon 不是 Planet

【讨论】:

  • 乔希的方法与我想说的一样。这两个类将具有共同的属性。我不确定我是否会使用接口——我会选择 Planet 和 Satellite 都继承自基类 CelestrialBody 的路线。然后,Planet 将拥有自己的其他属性(List、Aphelion、Perihelion),而 Satellite 将拥有自己的属性(perigee、apogee)。
  • 我最初也将它作为基类 - 这可能就是我将如何实现它。
  • 无论如何,它简化了答案。
  • @Amitd - 当然,这可能是您添加的内容。但是假设数据模型比这里显示的要大,那么AddMoon 帮助器变成了 100 多个包装器方法,而实际上它与myPlanet.Moons.Add(...) 没有什么不同(嗯,它是 一个字符)。
【解决方案2】:

更面向对象的方法可以将任何特定于月球的代码分离到自己的类中。随着代码变大,这可能有助于使您的代码更有条理。我知道月亮并不是真正的行星,但谁在乎呢?

然而,这样做的一个缺点是您现在限制了您的继承选项,因此这是您必须考虑的设计决策。

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");
    }
}

【讨论】:

    【解决方案3】:

    当然。您只是再次重用该课程。请记住,该类的某些属性可能不再适用(没有卫星之类的东西,是吗?)

    您可能想要添加一个传递布尔值 isChild 的构造函数。这样嵌套的孩子就可以知道它确实是一个孩子。

    【讨论】:

    • 卫星实际上可以有卫星。
    【解决方案4】:

    您已经掌握的内容似乎非常准确。一种可能的改进是创建一个名为Moon 的新类并让它继承自Planet。这样,您可以为 Moon 添加其他属性/功能,例如存储对拥有的 Planet 的引用。

    【讨论】:

      【解决方案5】:

      当然,这是有效的代码。

      不过,这种类型的设计可能会因其他原因而受到质疑。为什么 Planet 类会知道如何创建其他 Planet 实例等。如果创建行星的逻辑在 imo 类之外,那就更清楚了。

      【讨论】:

        【解决方案6】:

        虽然您的代码没问题,但对于我的口味来说,它看起来有点太接近无限循环了。如果您曾经将 0 更改为 1,那么 BANG!使其更健壮的一种方法是创建一个额外的构造函数并将它们链接起来。这样就没有递归了。

        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;
        }
        

        【讨论】:

          猜你喜欢
          • 2012-08-21
          • 2018-11-12
          • 2014-01-30
          • 2018-02-06
          • 2019-11-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多