- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我尝试学习双重调度和访问者模式,但下面的代码显然是错误的。我一定是遗漏了一些明显的东西,但我不知道如何修复它。谁能照亮我?我不知道如何在访问者中放置具体实例,是否应该在具体访问者类中创建一个构造函数?
interface Collidable
{
void Accept(IVisitor other);
}
class Asteroid : Collidable
{
public void Accept(IVisitor other)
{
Console.Write("[Asteroid] ");
other.visitAsteroid(this);
}
}
class Spaceship : Collidable
{
public void Accept(IVisitor other)
{
Console.Write("[Spaceship] ");
other.visitSpaceship(this);
}
}
interface IVisitor
{
void visitAsteroid(Asteroid a);
void visitSpaceship(Spaceship s);
}
class CollisionWithAsteroidVisitor : IVisitor
{
public void visitAsteroid(Asteroid a)
{
Console.WriteLine("Collided with asteroid");
}
public void visitSpaceship(Spaceship s)
{
Console.WriteLine("Collided with asteroid");
}
}
class CollisionWithSpaceShipVisitor : IVisitor
{
public void visitAsteroid(Asteroid a)
{
Console.WriteLine("Collided with spaceship");
}
public void visitSpaceship(Spaceship s)
{
Console.WriteLine("Collided with spaceship");
}
}
static void Main(string[] args)
{
Asteroid a1 = new Asteroid();
Asteroid a2 = new Asteroid();
Spaceship s1 = new Spaceship();
Spaceship s2 = new Spaceship();
s1.Accept(new CollisionWithAsteroidVisitor()); // this must be wrong
s1.Accept(new CollisionWithSpaceShipVisitor()); // this must be wrong
}
最佳答案
据我了解,您希望实现不同的对象可以相互碰撞,并且当发生此类碰撞时,参与者将知道他们碰撞到了其他类型的对象。
要在不使用反射(或如您所说的 RTTI,尽管它是 C++ 术语)的情况下实现此目的,使用访问者模式是一种很好的方法。您做错了什么,在这种情况下,两个对象都将充当接受者和访问者,具体取决于哪个对象与哪个对象发生碰撞。我们正在碰撞的对象将成为接受者(“接受碰撞对象”),而正在碰撞另一个对象的对象将成为访问者(“访问/碰撞到接受者对象)。
当碰撞物体是另一个物体时,接受者-访问者的角色可能会颠倒(移动的小行星碰撞到宇宙飞船与移动的宇宙飞船碰撞到静止的小行星)。从这个例子中你可以看到,一个对象可以根据情况充当接受者或访问者。这必须反射(reflect)在类层次结构中,因此两个对象都必须实现 ICollidable 和 IVisitor 接口(interface)。
我重写了您发布的代码,因此 Asteroid 和 Spaceship 类都实现了这两个接口(interface)。不再需要额外的访问者类,因为我们的对象本身成为了访问者:
interface ICollidable
{
void Accept(IVisitor other);
}
interface IVisitor
{
void VisitAsteroid(Asteroid a);
void VisitSpaceship(Spaceship s);
}
class Asteroid : ICollidable, IVisitor
{
public void Accept(IVisitor other)
{
Console.Write("[Asteroid] ");
other.VisitAsteroid(this);
}
public void VisitAsteroid(Asteroid a)
{
Console.WriteLine("Collided with asteroid");
}
public void VisitSpaceship(Spaceship s)
{
Console.WriteLine("Collided with asteroid");
}
}
class Spaceship : ICollidable, IVisitor
{
public void Accept(IVisitor other)
{
Console.Write("[Spaceship] ");
other.VisitSpaceship(this);
}
public void VisitAsteroid(Asteroid a)
{
Console.WriteLine("Collided with spaceship");
}
public void VisitSpaceship(Spaceship s)
{
Console.WriteLine("Collided with spaceship");
}
}
class Main
{
public static void Main(string[] args)
{
Asteroid a1 = new Asteroid();
Asteroid a2 = new Asteroid();
Spaceship s1 = new Spaceship();
Spaceship s2 = new Spaceship();
s1.Accept(a1);
s1.Accept(as);
a1.Accept(s1);
a2.Accept(a2);
}
}
如果您运行该程序,您将在控制台中获得以下输出:
[Spaceship] Collided with asteroid
[Spaceship] Collided with spaceship
[Asteroid] Collided with spaceship
[Asteroid] Collided with asteroid
我希望它让您明白如何在这种情况下使用访问者模式。
关于c# - 访客模式的实现。小行星/宇宙飞船碰撞问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8869767/
我目前正在编写 Asteroids,以获取计算机科学类(class)的额外学分,遵循提供了一些入门代码的非常宽松的指南。我有一艘船,我可以使用按键来改变它的位置。起始代码提供了一种根据点位置绘制船舶的
我尝试学习双重调度和访问者模式,但下面的代码显然是错误的。我一定是遗漏了一些明显的东西,但我不知道如何修复它。谁能照亮我?我不知道如何在访问者中放置具体实例,是否应该在具体访问者类中创建一个构造函数?
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我是一名优秀的程序员,十分优秀!