[英]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的想法很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.