简体   繁体   English

C#类继承

[英]C# Class Inheritance

greetings. 问候。 i have the following class: 我有以下课程:

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();
        }
    }
}

i would like to inherit this class like so: 我想像这样继承此类:

public class ShipPlacementArray : Ship
{

}

this makes sense. 这是有道理的。

what i would like to know is how do i remove certain functionality of the base class? 我想知道的是如何删除基类的某些功能?

for example: 例如:

    public ShipUnit[] shipUnit { get; set; } // from base class

i would like it to be: 我希望它是:

    public ShipUnit[][] shipUnit { get; set; } // in the derived class

my question is how do i implement the code that hides the base class shipUnit completely? 我的问题是如何实现完全隐藏基类shipUnit的代码?

otherwise i will end up with two shipUnit implementation in the derived class. 否则,我将在派生类中最终获得两个shipUnit实现。

thank you for your time. 感谢您的时间。

ShipPlacementArray deals with only one ship. ShipPlacementArray仅处理一艘船。 but the array reflects the directions the ship can be placed at. 但是数组反映了可以放置船的方向。

what i would like to know is how do i remove certain functionality of the base class? 我想知道的是如何删除基类的某些功能?

You don't. 你不知道 This is not the point of inheritance. 这不是继承的重点。 The point of inheritance is to inherit the base class functionality -- all of it -- and adding/changing stuff. 继承的重点是继承基类功能- 所有这些功能-并添加/更改内容。 It's for "is-a" relations, eg, "a car is a vehicle." 用于“是”关系,例如,“汽车就是车辆”。

my question is how do i implement the code that hides the base class shipUnit completely? 我的问题是如何实现完全隐藏基类shipUnit的代码?

It sounds like you want ShipPlacementArray to be a wrapper, or container, of multiple Ship objects. 听起来您想让ShipPlacementArray成为多个Ship对象的包装或容器。 This does not seem like a case where inheritance should be used. 这似乎不应该使用继承的情况。

Ask yourself the question: "is a ShipPlacementArray a kind of Ship ?" 问自己一个问题:“ ShipPlacementArray是一种Ship吗?”

In my experience, every time I've wanted to remove a property from a class in an inherited class, my class design was flawed. 根据我的经验,每次我想从继承的类的类中删除一个属性时,我的类设计都是有缺陷的。 One way to solve this problem would be to create a new base class without the ShipUnit property and then inherit that base class two times, once for your concrete Ship type and once for your concrete ShipPlacementArray type. 解决此问题的一种方法是创建一个没有ShipUnit属性的新基类,然后两次继承该基类,一次是针对具体的Ship类型,一次是针对具体的ShipPlacementArray类型。 In both subclasses you could implement ShipUnit as you need to. 在这两个子类中,您都可以根据需要实现ShipUnit。

You cannot make members of a base class disappear in a derived class. 您不能使基类的成员在派生类中消失。 In certain instances, you can mask or hide the base members by using the new keyword on your hiding member in the derived class, but the user will always be able to cast your object back to the base class (base)instance_of_derived and access the base class's members. 在某些情况下,您可以使用派生类中隐藏成员上的new关键字来屏蔽隐藏基成员,但是用户始终可以将您的对象强制转换回基类(base)instance_of_derived并访问基班级的成员。

So, for example, you can do in your derived class: 因此,例如,您可以在派生类中执行以下操作:

public new ShipUnit[][] shipUnit { get; set; }

But then I can do: 但是我可以做:

((Ship)ShipPlacementArray_instance).shipUnit

And this will reference the original shipUnit. 这将引用原始的shipUnit。 Thus, you can "hide" the member but you cannot disable its functionality or accessibility. 因此,您可以“隐藏”成员,但不能禁用其功能或可访问性。

With C#'s new modifier you can hide an inherited member from a base class member. 使用C#的修饰符,您可以从基类成员中隐藏继承的成员。 Check out this page for reference. 查看页面以供参考。

In additoin to the other excellent answers, as an aside I'd say you may find encapsulation to be a better option. 除了其他出色的答案之外,我想说的是,封装可能是更好的选择。 Often I used to at first think I wanted to inherit from a class, and later found that I really wanted to encapsulate it. 通常,我一开始常常以为我想从一个类继承,后来发现我真的想封装它。 You do this by simply declaring a new instance of the original class in a private field. 您只需在私有字段中声明原始类的新实例即可。 You then create public properties and function that simply call the original class like the below, giving you a fine grain of control over what gets exposed. 然后,您可以创建公共属性和函数,这些公共属性和函数只需调用原始类,如下所示,从而使您可以很好地控制公开的内容。 This also is a way to side step the disadvantages of inheritance such as added complexity and inability to perform multiple inheritence(for good reason): 这也是避免继承缺点的一种方法,例如增加了复杂性和无法执行多重继承(有充分的理由):

class SomeNew
{
  private SomeOld someOld = new SomeOld();//could have done this in constructor instead

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

I don't know if this is just a contrived example, or an actual problem. 我不知道这只是一个人为的例子,还是一个实际的问题。 But, I would say that the inheritance in this case isn't desired. 但是,我想说这种情况下的继承是不希望的。 You have Ship and ShipPlacementArray. 您有Ship和ShipPlacementArray。 The "Array" at the end makes it sound more like its, well, an array data type. 最后的“数组”听起来更像是数组数据类型。 So taking that away, you have ShipPlacement. 因此,将其带走,就可以得到ShipPlacement。

That sounds to me like its a location somewhere, so maybe it should be a member of the Ship class? 在我看来,这听起来像是某个地点,所以也许它应该是Ship类的成员?

"Favor object composition over class inheritance" - If you are looking for new behavior from the base class, then it doesn't seem like you'd want to inherit anyway because they are different types. “从类继承继承好对象的方法”-如果您要从基类中寻找新的行为,那么无论如何似乎都不想继承,因为它们是不同的类型。 Perhaps Ship and ShipPlacementArray should inherit a common interface, but certainly not from a common base class. 也许Ship和ShipPlacementArray应该继承一个公共接口,但是肯定不是从一个公共基类继承的。 Anywhere you'd need to use either you could use the interface - but where you needed your ShipUnit matrix, you'd use the ShipPlacementArray type explicitly. 无论您需要使用哪一个接口,都可以使用它-但在需要ShipUnit矩阵的地方,可以显式使用ShipPlacementArray类型。

you can use the "new" operator. 您可以使用“新”运算符。 as in

public new ShipUnit[][] shipUnit { get; set; } // in the derived class

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

public new ShipUnit[][] shipUnit { get; set; }

I don't fully understand what you want to model with the inheritance but I am quite sure it is the wrong tool. 我不完全了解您要使用继承建模的内容,但是我确信这是错误的工具。 I assume aggregation or composition are what you need. 我认为聚合或合成是您所需要的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM