作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
好的,最近我开始关注类,继承,接口(interface)以及它们之间如何交互。在此期间,我在各种论坛/博客/视频上发现了对继承的普遍不屑一顾,并且青睐作曲。好吧,酷一些新东西要学习。通过使用this wiki page上的示例,我着手尝试并更好地理解它……到目前为止,我的成就似乎只会使自己更加困惑。
我的代码,然后我将解释我认为是错误的。
MainClass.cs
class MainClass
{
static void Main(string[] args)
{
var player = new Player();
var enemy = new Enemy();
var entity = new Entity();
for(int i = 0; i < GameObject.GameObjects.Count; i++)
{
GameObject.GameObjects[i].Type();
GameObject.GameObjects[i].Draw();
GameObject.GameObjects[i].Move();
GameObject.GameObjects[i].Collision();
GameObject.GameObjects[i].Ai();
Console.WriteLine();
}
Console.ReadKey();
}
}
interface IVisible
{
void Draw();
}
class Visible : IVisible
{
public void Draw()
{
this.Print("I am visible!");
}
}
class Invisible : IVisible
{
public void Draw()
{
this.Print("I am invisible!");
}
}
interface IVelocity
{
void Move();
}
class Moving : IVelocity
{
public void Move()
{
this.Print("I am moving!");
}
}
class Stopped : IVelocity
{
public void Move()
{
this.Print("I am stopped!");
}
}
interface ICollidable
{
void Collide();
}
class Solid: ICollidable
{
public void Collide()
{
this.Print("I am solid!");
}
}
class NotSolid: ICollidable
{
public void Collide()
{
this.Print("I am not solid!");
}
}
interface IAi
{
void Ai();
}
class Aggressive : IAi
{
public void Ai()
{
this.Print("I am aggressive!");
}
}
class Passive : IAi
{
public void Ai()
{
this.Print("I am passive!");
}
}
class GameObject
{
private readonly IVisible _vis;
private readonly IVelocity _vel;
private readonly ICollidable _col;
private readonly IAi _ai;
public static List<GameObject> GameObjects = new List<GameObject>();
public GameObject(IVisible visible, IVelocity velocity)
{
_vis = visible;
_vel = velocity;
GameObjects.Add(this);
}
public GameObject(IVisible visible, IVelocity velocity, ICollidable collision)
{
_vis = visible;
_vel = velocity;
_col = collision;
GameObjects.Add(this);
}
public GameObject(IVisible visible, IVelocity velocity, ICollidable collision, IAi ai)
{
_vis = visible;
_vel = velocity;
_col = collision;
_ai = ai;
GameObjects.Add(this);
}
public void Draw()
{
if(_vis != null)
_vis.Draw();
}
public void Move()
{
if(_vel != null)
_vel.Move();
}
public void Collision()
{
if(_col != null)
_col.Collide();
}
internal void Ai()
{
if(_ai != null)
_ai.Ai();
}
}
class Player : GameObject
{
public Player() : base (new Visible(), new Stopped(), new Solid()) { }
}
class Enemy : GameObject
{
public Enemy() : base(new Visible(), new Stopped(), new Solid(), new Aggressive()) { }
}
class Entity : GameObject
{
public Entity() : base(new Visible(), new Stopped()) { }
}
public static class Utilities
{
public static void Type(this object o)
{
Console.WriteLine(o);
}
public static void Print(this object o, string s)
{
Console.WriteLine(s);
}
}
最佳答案
作品?首先让我们看看继承是否是正确的工具。这些接口(interface)是行为或特征。实现多种行为的最简单方法是简单地从这些接口(interface)继承。例如(简化代码):
sealed class Enemy : IMoveable, ICollidable {
public void Move() { }
public void Collide() { }
}
Netrual
和
Friend
类将需要重写
Enemy
的相同逻辑)。
abstract class PhysicalObject : IMoveable, ICollidable {
public virtual void Move() { }
public virtual void Collide() { }
}
abstract class SentientEntity : PhysicalObject, IAi
{
public virtual void Ai() { }
}
sealed class Enemy : SentientEntity {
}
sealed class Player : SentientEntity {
}
sealed class Friend : SentientEntity {
}
sealed class Enemy : IMoveable, ICollidable {
public void Move() => _moveable.Move();
private readonly IMoveable _moveable = new Moveable();
}
Moveable
实现的
IMoveable
实现中的代码。
abstract class PhysicalObject : IMoveable, ICollidable {
protected PhysicalObject() {
_moveable = CreateMoveableBehavior();
_collidable = CreateCollidableBehavior();
}
public void Move() => _moveable.Move();
public void Collide() => _collidable.Collide();
protected virtual IMoveable CreateMoveableBehavior()
=> new Moveable();
protected virtual ICollidable CreateCollidableBehavior()
=> new Collidable();
private readonly IMoveable _moveable;
private readonly ICollidable _collidable;
}
sealed class Ghost : PhysicalObject {
protected override CreateCollidableBehavior()
=> new ColliderWithProbability(0.1);
}
abstract ComposedPhysicalObject : ICollidable {
public void Collide() {
Parts.ForEach(part => part.Collide());
}
public List<ICollidable> Parts { get } = new List<ICollidable>()
}
ICollidable
,然后它强制所有部件都具有这种行为。可能不正确:
interface IGameObject { }
interface ICollidable : IGameObject { }
abstract ComposedPhysicalObject : ICollidable {
public void Collide() {
foreach (var part in Parts.OfType<ICollidable>())
part.Collide();
}
public List<IGameObject> Parts { get } = new List<IGameObject>()
}
null
的原因,顺便说一下,它可能会简化为
fieldName?.MethodName()
)。您要在运行时解决在编译时众所周知的问题,并且(几乎)总是首选编译时检查。
abstract class GameObject {
public virtual void Move() { }
public virtual void Collide() { }
}
sealed class Player : GameObject {
public override void Move()
=> _collisionLogic.Move();
private readonly CollisionLogic _collisionLogic = new CollisionLogic(this);
}
关于C#合成-我不确信我完全了解如何实现此目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44668852/
我是一名优秀的程序员,十分优秀!