views:

258

answers:

11

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?

otherwise i will end up with two shipUnit implementation in the derived class.

thank you for your time.

ShipPlacementArray deals with only one ship. but the array reflects the directions the ship can be placed at.

A: 

you can use the "new" operator. as in

public new ShipUnit[][] shipUnit { get; set; } // in the derived class
aggietech
I down voted because new is a way to hide the base class implementation and start a new inheritance hierarchy but this solution does not really solve the presented problem - it fixes at best some symptoms.
Daniel Brückner
+2  A: 

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.

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. Thus, you can "hide" the member but you cannot disable its functionality or accessibility.

David Pfeffer
+15  A: 

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, e.g., "a car is a vehicle."

my question is how do i implement the code that hides the base class shipUnit completely?

It sounds like you want ShipPlacementArray to be a wrapper, or container, of multiple Ship objects. This does not seem like a case where inheritance should be used.

Ask yourself the question: "is a ShipPlacementArray a kind of Ship?"

Thomas
ShipPlacementArray is not a ship but it shares a great deal of data/similarities with ship class. thats why i am thinking of inheriting from ship class.
iEisenhower
In that case, you *could* create a class that implements the common functionality, and derive both `Ship` and `ShipPlacementArray` from that. But if you're really creating a Battleship game (as it seems from your code), I can't think of anything worthwhile that the two have in common.
Thomas
Thomas: i understood the first part of what you said but the later im not sure if i understand. ShipPlacementArray is a container for avaliable ship placement location when assigning the ship on to a location on the grid.
iEisenhower
Exactly. It is a *container of ships*, not a *ship*. What is the functionality of `Ship` that you also need in `ShipPlacementArray`? (Some properties that happen to have the same names doesn't count, because they have different types!)
Thomas
Thomas: It is a container of a ship.it stores the positions where a ship can be placed on the grid.
iEisenhower
A: 

You can use the new keyword, like this:

public new ShipUnit[][] shipUnit { get; set; }
Max Toro
I down voted because new is a way to hide the base class implementation and start a new inheritance hierarchy but this solution does not really solve the presented problem - it fixes at best some symptoms.
Daniel Brückner
@Daniel Brückner The question is "my question is how do i implement the code that hides the base class shipUnit completely?", not "how do I fix this design?".
Max Toro
Yes and no. It answers the question the opener asked but it does not give him the information he (really) needs.
Daniel Brückner
@Daniel Brückner Still, downvoting a correct answer was completely unnecessary.
Max Toro
+2  A: 

With C#'s new modifier you can hide an inherited member from a base class member. Check out this page for reference.

Pompair
+6  A: 

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. In both subclasses you could implement ShipUnit as you need to.

Jeremy Wiebe
yes as im a beginner i cant think out completely in one go yet.i think your information solves the issue im having. just devide the data into useful units. which im doing to an extent but your input cleared the next step in design for me. thanks.
iEisenhower
@ikurtz - Inheritance should always follows an "is a" relationship. Can you say "a ShipPlacementArray is a Ship" and it make sense (in the way "a circle is a shape" does)? If not then it's back to the drawing board :)
Paolo
A: 

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.

Daniel Brückner
+1  A: 

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();
  }
}
AaronLS
+1  A: 

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. The "Array" at the end makes it sound more like its, well, an array data type. So taking that away, you have ShipPlacement.

That sounds to me like its a location somewhere, so maybe it should be a member of the Ship class?

Bryce Fischer
+1  A: 

"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. 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.

WalterVonBruegemon
+2  A: 

you can use the new keyword or add virtual on the declaration on the base class and override it on the derived class.

Jojo Sardez