【发布时间】:2011-09-08 13:08:57
【问题描述】:
我正在尝试使用多态性让派生类使用派生属性而不是基属性进行操作。我不确定如何用更清晰的语言表达,所以这里有一个输出示例:
// setup output to demonstrate the scenario
static void Main(string[] args)
{
var foo = new Foo();
var foobase = foo as FooBase;
Console.WriteLine("Foo is null? {0}", foo == null);
Console.WriteLine("Foo.Bar is null? {0}", foo.Bar == null);
Console.WriteLine("FooBase is null? {0}", foobase == null);
Console.WriteLine("FooBase.Bar is null? {0}", foobase.Bar == null);
Console.ReadLine();
}
// base and derived. These represent my problem.
class BarBase { }
class Bar : BarBase { }
// Base implementation using base properties
class FooBase
{
public virtual BarBase Bar { get; set; }
public FooBase() { }
}
// Derived implementation using "new" to operate with the
// derived the property
class Foo : FooBase
{
public new Bar Bar { get; set; }
public Foo() : base()
{
// populate our modified property with the derived class
Bar = new Bar();
//base.Bar = Bar; // I don't want to do this, but how can I avoid it?
}
}
输出:
Foo 为空?错误的 Foo.Bar 为空?错误的 FooBase 为空?错误的 FooBase.Bar 为空?真的问题是“FooBase.Bar”为 NULL。我知道 new 修饰符隐藏了基本实现,这就是为什么我知道我可以通过添加(注释掉的)行使其工作:
base.Bar = Bar; // I don't want to do this, but how can I avoid it?
有没有更好的方法?我错过了什么?
提前致谢!
编辑(2011 年 6 月 7 日)
为我的问题添加更具体的示例。基本上,有游戏和相机的抽象实现(这里非常基本......)。抽象游戏使用抽象相机进行基本工作。派生游戏使用其派生相机进行专业工作。最后,我需要派生和抽象相机在它们自己的范围内工作。
我已经给出了两个不同的 Camera 实现和两个 Game 实现来(希望)展示我正在寻找的灵活性。请注意,Game1 使用“hack”来强制基本相机具有值 - Game2 不会这样做。 Game1 有我想要的行为,但没有我想要的实现。
class GameAndCameraExample
{
static void Main(string[] args)
{
new Game1().Play();
Console.WriteLine();
new Game2().Play();
Console.ReadLine();
}
// abstract camera
abstract class CameraBase
{
public void SpecialCameraBaseMethod()
{
Console.WriteLine("SpecialCameraBaseMethod");
}
}
// camera implementation
class ChaseCamera : CameraBase
{
public void SpecialChaseCameraMethod()
{
Console.WriteLine("SpecialChaseCameraMethod");
}
}
// a different camera implementation
class FlightCamera : CameraBase
{
public void SpecialFlightCameraMethod()
{
Console.WriteLine("SpecialFlightCameraMethod");
}
}
// abstract game
abstract class GameBase
{
public virtual CameraBase Camera { get; set; }
public GameBase() { }
public virtual void Play()
{
Console.WriteLine("GameBase.Camera is null? {0}", Camera == null);
if(Camera != null) // it will be null for Game2 :-(
Camera.SpecialCameraBaseMethod();
}
}
// awesome game using chase cameras
class Game1 : GameBase
{
public new ChaseCamera Camera { get; set; }
public Game1() : base()
{
Camera = new ChaseCamera();
base.Camera = Camera; // HACK: How can I avoid this?
}
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialChaseCameraMethod();
base.Play();
}
}
// even more awesome game using flight cameras
class Game2 : GameBase
{
public new FlightCamera Camera { get; set; }
public Game2()
: base()
{
Camera = new FlightCamera();
}
public override void Play()
{
Console.WriteLine("Game.Camera is null? {0}", Camera == null);
Camera.SpecialFlightCameraMethod();
base.Play();
}
}
}
输出:
Game.Camera 为空?错误的 特殊追逐相机法 GameBase.Camera 为空?错误的 特殊CameraBaseMethod Game.Camera 为空?错误的 特殊飞行相机法 GameBase.Camera 为空?真的继承是否是最好的方法?
【问题讨论】:
-
添加了一个新示例以更好地反映我的实际问题
标签: c# .net polymorphism derived-class