c#继承多态类型
本文关键字:类型 多态 继承 | 更新日期: 2023-09-27 18:17:43
从一个叫做武器的基本类开始,我打算它是多态的,如下所示:
public class Weapon
{
// Some code..
}
public class MachineGun : Weapon
{
// Extend the base code..
}
这些类定义了基本功能,但是它们不包含绘制武器的任何代码。这个绘图只需要添加到客户端应用程序中,服务器只需使用MachineGun类而不需要可视化。
public class DrawableWeapon : Weapon
{
// Adding draw calls and properties
}
public class DrawableMachineGun : DrawableWeapon
{
// The problem:
// You have no access to the properties of the original MachineGun here
}
// or..
public class DrawableMachineGun : MachineGun
{
// Same problem, only now you miss properties of the DrawableWeapon
}
问题是失去MachineGun()类或DrawableWeapon()类的功能,因为c#没有多重继承。
将Weapon类定义为接口也没有成功,你不能在接口中定义方法,这正是我需要减少代码的。
我发现的唯一(部分)解决方案是方法:在一个单独的静态类中定义它们,在一个可绘制的类中调用每个方法,也调用这个静态方法。这仍然遗漏了所有的属性,并导致长时间的方法调用。
要很好地实现这一点,最好的选择是什么?在这种情况下是否有更好的编程模式可以使用?
是。你可以使用Decorator模式:
public class Weapon
{
public virtual void Shot()
{
// Some code...
}
}
public class MachineGun : Weapon
{
public override void Shot()
{
// Extend base code...
}
}
public class DrawableWeapon : Weapon
{
Weapon mWeapon;
public override void Shot()
{
mWeapon.Shot();
}
// Adding draw calls and properties
}
您可以使用装饰器模式来扩展您的类,而不需要继承。对于这类多态问题,最好记住优先选择对象组合而不是继承原则。
interface Weapon : Weapon {
void Fire();
}
class MachineGun : Weapon {
public override void Fire() {
for (int i = 0; i < 5; i++) {
// Do something
}
}
}
class HandGun : Weapon {
public override void Fire() {
// Do something
}
}
abstract class WeaponDecorator : Weapon {
protected Weapon weapon;
public WeaponDecorator(Weapon weapon) {
this.weapon = weapon;
}
// Implement methods by calling this.weapon's method
public virtual void Fire() {
weapon.Fire();
}
}
class DrawableWeapon : WeaponDecorator {
public DrawableWeapon (Weapon weapon) : base(weapon) {
}
public override void Fire() {
PlayShakingEffect();
base.Fire();
}
private void PlayShakingEffect() {
}
}
有了这段代码,我们可以使任何类型的Weapon
绘制。注意所有武器仍然是Weapon
的实例。
Weapon machineGun = new MachineGun();
Weapon handGun = new HandGun();
Weapon drawableMachineGun = new DrawableWeapon(new MachineGun());
Weapon drawableHandGun = new DrawableWeapon(new HandGun());
也许另一种看待这个问题的方式是创建不同类的组合,而不是使用经典的OO继承。这强调使用接口而不是类层次结构,其中通用代码不是继承而是使用。例子;
interface IDrawer
{
void Draw();
}
class WeaponDrawer : IDrawer // class carries out the drawing of a weapon
class Weapon : IDrawer
{
private IDrawer : weaponDrawer = new WeaponDrawer();
// Delegate the draw method to a completely different class.
public void Draw()
{
this.weaponDrawer.Draw();
}
}
这遵循了SOLID原则,将武器的定义与绘制武器的功能分开。(你当然可以使用IOC容器而不是"= new WeaponDrawer()")。您最终得到的是一组单一用途的类,而不是复杂的继承层次结构—它看起来像更多的代码,但您可能会发现设计更清晰,更易于维护。
另一种方法,使用方法注入允许多个抽屉实现,同时您可以在需要的地方添加IDrawable。
interface IDrawable {
Draw(WeaponDrawer)
}
class DrawableWeapon : Weapon, IDrawable {
Draw(WeaponDrawer wd){
wd.Draw(this);
}
}
class WeaponDrawer {
Draw(Weapon weapon){
//drawing logic here
}
}
你可以使用泛型和装饰器模式来实现DrawableWeapon
public class DrawableWeapon<T> : Weapon where T : Weapon
{
T _weapon;
public void Shot()
{
_weapon.Shot();
}
}
通过这种方式,你可以为每个武器实现一个不同的DrawableWeapon类。