C#类继承

C#类继承,c#,class,inheritance,base,C#,Class,Inheritance,Base,你好。我有以下课程: public class Ship { public enum ValidShips { Minesweeper, Cruiser, Destroyer, Submarine, AircraftCarrier } public enum ShipOrientation { North, East, Sout

你好。我有以下课程:

public class Ship
{
    public enum ValidShips
    {
        Minesweeper,
        Cruiser,
        Destroyer,
        Submarine,
        AircraftCarrier
    }

    public enum ShipOrientation
    {
        North,
        East,
        South,
        West
    }

    public enum ShipStatus
    {
        Floating,
        Destroyed
    }

    public ValidShips shipType { get; set; }

    public ShipUnit[] shipUnit { get; set; }

    public ShipOrientation shipOrientation { get; set; }

    public ShipStatus shipStatus { get; set; }

    public Ship(ValidShips ShipType, int unitLength)
    {
        shipStatus = ShipStatus.Floating;

        shipType = ShipType;

        shipUnit = new ShipUnit[unitLength];

        for (int i = 0; i < unitLength; i++)
        {
            shipUnit[i] = new ShipUnit();
        }
    }
}
这是有道理的

我想知道的是如何删除基类的某些功能

例如:

    public ShipUnit[] shipUnit { get; set; } // from base class
我希望是:

    public ShipUnit[][] shipUnit { get; set; } // in the derived class
我的问题是如何实现完全隐藏基类shipUnit的代码

否则,我将在派生类中得到两个shipUnit实现

谢谢你抽出时间

ShipPlacementArray只处理一艘船。但是数组反映了飞船可以放置的方向。

您可以使用“new”操作符。 如


您不能使基类的成员在派生类中消失。在某些情况下,您可以通过在派生类中的隐藏成员上使用
new
关键字来屏蔽或隐藏基类成员,但用户将始终能够将您的对象强制转换回基类
(base)实例\u派生的
,并访问基类的成员

例如,您可以在派生类中执行以下操作:

public new ShipUnit[][] shipUnit { get; set; }
但我可以做到:

((Ship)ShipPlacementArray_instance).shipUnit
这将参考原始发货单位。因此,您可以“隐藏”成员,但不能禁用其功能或可访问性

我想知道的是如何删除基类的某些功能

你没有。这不是继承的问题。继承的要点是继承基类功能——所有功能——并添加/更改内容。它代表“是一种”关系,例如,“一辆车就是一辆车。”

我的问题是如何实现完全隐藏基类shipUnit的代码

听起来您希望
shippplacementarray
成为多个
Ship
对象的包装器或容器。这似乎不是应该使用继承的情况


问自己一个问题:“ShipPlacementArray是否是一种
Ship
?”

您可以使用
new
关键字,如下所示:

public new ShipUnit[][] shipUnit { get; set; }
使用C#的new修饰符,可以从基类成员隐藏继承的成员。
查看页面以供参考。

根据我的经验,每次我想从继承类的类中删除属性时,我的类设计都有缺陷。解决此问题的一种方法是创建一个没有ShipUnit属性的新基类,然后继承该基类两次,一次用于具体的Ship类型,一次用于具体的ShipPlacementArray类型。在这两个子类中,您都可以根据需要实现ShipUnit。

我不完全理解您想用继承来建模什么,但我很确定这是一个错误的工具。我想这就是您所需要的。

除了其他优秀的答案之外,顺便说一句,您可能会发现封装是一个更好的选择。通常我一开始认为我想从类继承,后来发现我真的想封装它。您只需在私有字段中声明原始类的一个新实例就可以做到这一点。然后创建公共属性和函数,这些属性和函数只需像下面这样调用原始类,就可以很好地控制公开的内容。这也是避开继承的缺点的一种方法,例如增加了复杂性和无法执行多重继承(有充分的理由):


我不知道这是一个人为的例子,还是一个实际的问题。但是,我想说的是,这种情况下的继承是不可取的。您有Ship和ShipPlacementArray。最后的“数组”使它听起来更像它的数组数据类型。所以把它拿走,你就有了船位

对我来说,这听起来像是某个位置,所以可能它应该是Ship类的成员?

“支持对象组合而不是类继承”-如果您正在从基类中寻找新的行为,那么似乎您无论如何都不想继承,因为它们是不同的类型。
Ship和ShipPlacementArray可能应该继承一个公共接口,但肯定不能从公共基类继承。在任何需要使用的地方,您都可以使用界面-但在需要ShipUnit矩阵的地方,您可以显式使用ShipPlacementArray类型。

您可以在基类的声明中使用new关键字或添加virtual,并在派生类中重写它。

ShipPlacementArray不是ship,但它与ship类共享大量数据/相似性。这就是为什么我考虑从ship类继承。在这种情况下,您可以创建一个实现公共功能的类,并从中派生
ship
ShipPlacementArray
。但是如果你真的在创造一个战舰游戏(从你的代码中可以看出),我想不出两个游戏有什么值得共同之处。托马斯:我理解你说的第一部分,但后面我不确定我是否理解。ShipPlacementArray是一个容器,用于在将船舶分配到网格上的某个位置时提供船舶放置位置。它是一个容器的船舶,而不是一艘船。您在
ShipPlacementArray
中还需要的
Ship
的功能是什么?(有些属性碰巧有相同的名称,但不算,因为它们有不同的类型!)托马斯:它是船的容器。它存储了一艘船可以放置在网格上的位置。哇,看起来好像有人通过了,否决了每个人的答案。是的,因为我是一个初学者,我还不能一次就完全想出来。我想你的信息解决了我的问题。把数据分成有用的单位就行了。我在一定程度上做到了这一点,但你的输入为我清除了设计的下一步。谢谢。@ikurtz-继承应该始终遵循“是一种”关系。你能说“一艘ShipPlacementArray就是一艘飞船”吗?这是有道理的(就像“一个圆就是一个形状”一样)?如果没有,那就回到绘图板上来:)我投了反对票,因为new是隐藏基类im的一种方式
((Ship)ShipPlacementArray_instance).shipUnit
public new ShipUnit[][] shipUnit { get; set; }
class SomeNew
{
  private SomeOld someOld = new SomeOld();//could have done this in constructor instead

  public DoSomething()
  {
    someOld.DoSomething();
  }
}