繁体   English   中英

C#:帮助设计嵌套类的结构

[英]C#: Help to design a structure of nested classes

我需要一个描述行星系统的类系统。

我的第一堂课是原子空间体:

public class SpaceBody
{
    public string Name;
    public float Mass;
   // and so on
}

第二个是空间物体系统,它也是SpaceBody:

public class SpaceBodySystem<ChildType>: SpaceBody where ChildType: SpaceBody, new()
{
    // ...
    public List<ChildType> Children;
    // ...
}

接下来,我有一颗星星:

public class Star: SpaceBodySystem<SpaceBody>
{
    public float Intencity;
    // ...
}

最后,整个恒星系统是这样的(它可以有多个恒星):

public class StarSystem: SpaceBodySystem<Star>
{
    public bool OccupiedByAliens;
    // ...
}

问题是 :星星应该有行星(SpaceBodySystem),这些行星又可能有自己的卫星,而那些卫星也可能有自己的卫星,依此类推...嵌套深度是无限的。

用我当前的课程系统是不可能的。 我必须写这样的东西,但是这个丑陋的解决方案具有有限的层次结构级别。

public class StarSystem: SpaceBodySystem<SpaceBodySystem<SpaceBodySystem<SpaceBody>>>
{
    public float Intencity;
    // ...
}

我要求社区给我一些建议,以改善这种结构。 我考虑了其他方案(接口,组合+委派),但未能获得可接受的解决方案。

非常感谢您的帮助。

如果您需要一个系统中有多个太阳的可能性,也许您还希望两个行星共享一个月球的可能性。

在这种情况下,也许您应该拥有一个子系统,该子系统具有一系列主体和一系列卫星。 在太阳系中,您可以将恒星用作主体,将行星用作卫星。 在星系中,也许您可​​以定义一些抽象的中心点/航路点为主体,而所有的太阳系都是卫星。

因此,对于我们的太阳系,您拥有子系统'SolarSystem',其中包含太阳主体和卫星行星,它们每个都是子系统。 子系统地球有一个主体地球和一个卫星月亮。

拥有一个带有MainBody Earth的Subsystem Earth听起来可能有点多余,但是也许可以通过使用接口来解决这个问题,因此可以通过实现ISubSystem和IMainBody的单个类来实现一个简单的子系统(具有一个主体)。

或者,您可以简化实现过程,并使Earth(system)成为一个单独的子系统,该子系统具有一个具有一个主体的数组,该主体是Earth(planet),另一个具有一个卫星的阵列,即SubSystem Moon(system),其中包含主体Moon而且没有卫星。

我认为有一个班级会建立一个行星系统:

public class SpaceBody
{
    public string Name;
    public float Mass;
    public float Distance;
    public bool clockwise;
    //...
    public SpaceBody RevolvesAround;
    List<SpaceBody> Satellites;

}

如果您的系统基类可以具有子对象,而这些子对象本身是该基类的实例或派生自该基类,则您不需要像这样嵌套。 让我举个例子吧:

public class SpaceBodySystem<ChildType>: SpaceBody where ChildType: SpaceBody, new()
{
    public List<ChildType> Children;
}

因此, SpaceBodySystem具有属于SpaceBody类型的SpaceBody ,它本身就是一个SpaceBody

public class StarSystem : SpaceBodySystem<Star>
{
}

此类可以表示一颗恒星或两颗恒星的双星对,或任何其他形式。

public class PlanetarySystem : SpaceBodySystem<Moon>
{
    public Planet CentralPlanet;
}

这可以代表具有任意数量卫星的Planet ,其中Planet继承自SpaceBody

public class SolarSystem : SpaceBodySystem<PlanetarySystem>
{
    public StarSystem CoreStar;
}

该类现在可以表示具有某些恒星配置的太阳系,而所有子代都是可能带有卫星的行星。

简而言之,您无需保留嵌套SpaceBodySystem<SpaceBodySystem<SpaceBodySystem<SpaceBody>>>因为SpaceBodySystem继承自SpaceBody ,因此,如果您只有SpaceBodySystem<SpaceBody> ,则该内部SpaceBody 可能是一个SpaceBodySystem ,而后者可能会进一步孩子们,但您不必知道这一点 这就是多态的美。

另外要说的是,我想从数据文件加载我的系统。 假设我有此输入数据(在附件中)。 我有一个虚拟方法,该方法读取并创建一个SapceBody对象。

class SpaceBody...
{
    ...
    public virtual void CreateGameObject()
    {
        instance = new GameObject();
    }
    ...
}

class SpaceBodySystem...
{
    ...
    public override void CreateGameObject()
    {
        base.GameObject();
        foreach(ChildType child in Children)
        {
            child.CreateGameObject();
        }
    }
    ...
}


class Star: SpaceBodySytem<SpaceBody>
{
    ...
    public override void CreateGameObject()
    {
        base.GameObject();
        doExtraWorkForTheStar();
    }
    ...
}

StarSystem.CreateObject();
 // for attached file, will load and create one star (Sun) and nine planets.

因此,如果我使用anaximander提出的声明,则系统不会看到孩子的孩子。 例如,地球是SpaceBody(但应该是SpaceBodySytem),在这种情况下不会创建月亮。

GolezTrol的想法很好。

solarsystem.json

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM