在运行时是否可以接受未知类型?

问题描述 投票:0回答:1

我正在尝试解决一个简单的OOP问题。当我必须创建少量武器并且每个武器都有一个主要动作并且可以通过单击鼠标执行该主要动作时。 a弹枪射击的例子,而Katana摇摆枪的例子。下面是我的课程。

public interface IShootable
{
    void TakeShot();
}
public interface ISwingable
{
    void Swing ();
}

public class ShotGun : IShootable
{
    public void TakeShot()
    {
    }
}
public class Kanata : ISwingable
{
    public void Swing ()
    {
    }
}   

[每种武器为其主要动作都实现了不同的界面。 (我不确定是否可以创建一个抽象类,从中可以继承这些具体类。似乎不能替代两种不同类型的武器。)

我想要实现的是在运行时,当用户选择其中一种武器时,用户只要单击鼠标即可获得正确的操作。对于shot弹枪,它是TakeShot(),对于武士刀,它是Swing()

我必须采取的措施。或者,我应该以其他方式重构类。

c# oop design-patterns solid-principles
1个回答
0
投票

两个类都可以通过IWeapon / Attack方法实现第三个接口-Use

public interface IWeapon {
    void Attack();
}

public class ShotGun : IShootable
{
    void IWeapon.Attack() {
        TakeShot();
    }

    public void TakeShot()
    {
    }
}
public class Kanata : ISwingable
{
    public void Swing ()
    {
    }

    void IWeapon.Attack() {
        Swing();
    }
}  

请注意,我在此处具有explicitly implemented IWeapon接口。您不必显式地执行此操作,而仍然可以按“常规方式”进行操作。但我更喜欢这种方式。这样,当您有一个Katana对象时,只有Swing是可见的,而没有Attack。我只是觉得同时显示两种方法令人困惑。

还请注意,IWeaponISwingableIShootable无关,因为可摆动的物体(网球拍)和可射击的物体(水枪)不一定是武器。


0
投票

您可能想做一些更通用的事情:

public interface IWeaponPrimaryAction
{
    void PerformPrimaryAction();
}
public interface IWeaponAction
{
    void PrimaryAction();
}

public class Shoot :IWeaponAction
{
    public void PrimaryAction()
    {
        //Fire in the hole
    }
}   
public class Swing :IWeaponAction
{
    public void PrimaryAction()
    {
        //Into pieces
    }
}
public class ShotGun : IWeaponPrimaryAction
{
    private IWeaponAction _action = new Shoot();
    public void PerformPrimaryAction()
    {
        _action.PrimaryAction();
    }
}
public class Kanata : IWeaponPrimaryAction
{
    private IWeaponAction _action = new Swing();
    public void PerformPrimaryAction()
    {
        _action.PrimaryAction();
    }
}

比注入动作要好:

public class ShotGun : IWeaponPrimaryAction
{
    private IWeaponAction _action;
    public ShotGun(IWeaponAction action)
    {
        _action = action;
    }
    public void PerformPrimaryAction()
    {
        _action.PrimaryAction();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.