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.
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?"
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.
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.
With C#'s new modifier you can hide an inherited member from a base class member.
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. 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?
"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.
you can use the "new" operator.
as in
public new ShipUnit[][] shipUnit { get; set; } // in the derived class
You can use the new keyword, like this:
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.
you can use the new keyword or add virtual on the declaration on the base class and override it on the derived class.
Related
I'm not really sure what looks better or when do I really use in abstract classes and properties, or when to use non abstract properties. I'll try to make a simple example. Let's say I have this:
abstract class Human
{
public GenderType Gender { get; set; }
public string Name { get; set; }
public Date Born { get; set; }
public bool IsNerd { get; set; }
abstract public void Speak();
abstract public void Sleep();
abstract public void AnoyingPeopleOnStackOverflow();
//... so on
}
class Peter : Human
{
//Peter is special, he got a second name
//But thats all, everything else is the same as like on other humans
public string SecondName { get; set; }
//...override abstract stuff
}
Is this alright? As I understood, I don't have to use an abstract property if I dont want to override it. And in this situation it would be ok, just the methods like Speak, Sleep and so on should be abstract.
Now, if this is ok, when would or should I use an abstract property?
Use an abstract property when you have no default implementation and when derived classes must implement it.
Use a virtual property when you have an implementation in the base class but want to allow overriding.
Use the override keyword to override a member. Mark the member as sealed override if it should not be overridden again.
Don't mark the property as abstract or virtual if you don't want it to be overridden.
Use the new keyword to hide a non-abstract, non-virtual member (this is rarely a good idea).
How to: Define Abstract Properties
I find that abstract properties often occur in a design which implies that they will have type-specific logic and/or side effects. You are basically saying, "here is a data point that all subclasses must have, but I don't know how to implement it". However, properties which contain a large amount of logic and/or cause side effects may not be desirable. This is an important consideration, though there is no fixed right/wrong way to do it.
See:
Should Properties have Side Effects
CA1024: Use properties where appropriate
Personally, I find that I use abstract methods frequently but abstract properties rarely.
I know what I want them to do, I don't care how they do it: Interface.
I know what I want them to do, I don't care how they do some of it, but I've firm ideas on how they'll (or at least most of them) do other bits: Abstract class.
I know what I want them to do, and how most of them will do it: Concrete class with virtual members.
You can have other cases such as e.g. an abstract class with no abstract members (you can't have an instance of one, but what functionality it offers, it offers completely), but they're rarer and normally come about because a particular hierarchy offers itself cleanly and blatantly to a given problem.
(Incidentally, I wouldn't think of a Peter as a type of Human, but of each peter as an instance of human who happens to be called Peter. It's not really fair to pick on example code in this way, but when you're thinking about this sort of issue it's more pertinent than usual).
Abstract members are simply virtual members that you have to override. You use this for something that has to be implemented, but can't be implemented in the base class.
If you want to make a virtual property, and want that it has to be overridden in the class that inherits your class, then you would make it an abstract property.
If you for example have an animal class, its ability to breathe would not be possible to detemine just from the information that it's an animal, but it's something that is pretty crucial:
public abstract class Animal {
public abstract bool CanBreathe { get; }
}
For a fish and a dog the implementation would be different:
public class Dog : Animal {
public override bool CanBreathe { get { return !IsUnderWater; } }
}
public class Fish : Animal {
public override bool CanBreathe { get { return IsUnderWater; } }
}
Use abstract when all sub-classes have to implement the method/property. If there's no need for each and every sub-class to implement it, then don't use it.
As for your example, if SecondName is not required for each person, then there's no need to make an abstract property in the base class. If on the other hand, every person does need a second name, then make it an abstract property.
Example of correct usage of an abstract property:
public class Car
{
public abstract string Manufacturer { get; }
}
public class Odyssey : Car
{
public override string Manufacturer
{
get
{
return "Honda";
}
}
}
public class Camry : Car
{
public override string Manufacturer
{
get
{
return "Toyota";
}
}
}
Making Maker abstract is correct because every car has a manufacturer and needs to be able to tell the user who that maker is.
An abstract property would be used where you want the class to always expose the property, but where you can't pin down the implemetation of that property - leaving it up to/forcing the inheriting class to do so.
There's an example here, where the abstract class is named Shape, and it exposes an abstract Area property. You can't implement the Area property in the base class, as the formula for area will change for each type of shape. All shapes have an area (of some sort), so all shapes should expose the property.
Your implementation itself looks just fine. Was trying to think of a sensible example of an abstract property for a Human, but couldn't think of anything reasonable.
I would like to define an enum inside of a class. The class will have a public property of the enum type. I would like classes outside this class to be able to reference this class' enum property, but I don't want other classes to be able to create their own instances of this enum. Is this even possible? Consider this example:
public class MyClassWithEnum
{
public Season MySeason { get; set; }
public enum Season { Winter, Spring, Summer, Fall }
}
public class OutsideClass
{
public void OutsideClassMethod()
{
MyClassWithEnum enumClass = new MyClassWithEnum();
enumClass.MySeason = MyClassWithEnum.Season.Spring; // This should be okay
MyClassWithEnum.Season localSeason = MyClassWithEnum.Season.Winter; // This should NOT be okay
}
}
It seems to me I am left to choose between defining the enum as public and letting any other class create instances of it, or making it private and not being able to set it from outside the class.
You do not instantiate Enums as if it where classes, therefore you cannot prevent someone to use it. With a class you could have a private ctor for example... That's obviously not possible with Enums.
So yes, your assumption is correct, either make it internal or private, or make it public... ;)
Btw, I cannot think about any good scenario where you want to hide the Enum while having a public property using the Enum, even if it where possible to do this.
So say I have a class
public abstract class Mammal { ... }
public class Wolf : Mammal
{
// concrete methods and
}
But I don't want to do something like:
List<Wolf> myWolfPack = new List<Wolf>();
I sort of want to say:
WolfPack myWolfPack = new WolfPack();
Which means I basically need to write a WolfPack class:
****public class WolfPack : IList<Wolf>
{
// properties, methods that implements IList
// WolfPack-specific methods
}****
The reason I want to do this is because I wolf packs have specific properties (e.g. a leader, an omega).
WolfPack-specific methods
Wolf Leader { get;set; }
Wolf Omega { get;set; }
So here are my newbie questions:
What is this called? Is there a name for wanting to add methods to a collection/list/existing concrete object? If I'm just using a private List inside my WolfPack class, should I instead just say: public class WolfPack : List
? Seems weird to do this with a concrete class, no? Are there any downsides to this?
Sorry if my words are weird.
I suggest you use composition instead of inheritance. Something like this:
public class WolfPack
{
public IReadOnlyList<Wolf> Members { get; private set; }
public Wolf Leader { get; private set; }
public Wolf Omega { get; private set; }
}
Any operations specific to a WolfPack collection of Wolf should be methods on the WolfPack class. This does not require any modification to the .NET collection class used internally.
Encapsulation is probably what you're looking for. However, to answer
Is there a name for wanting to add methods to a collection/list/existing concrete object?
directly, you probably want extension methods.
I would argue that WolfPack may seem, at first glance, to be an IList<Wolf>, but are you sure that a WolfPack must expose every member that IList<> will require? Chances are, it won't. You probably want to use a List<Wolf> inside your WolfPack implementation as a private field.
You don't have to inherit from the collection class. There are reasons why inheritance is considered problematic - Prefer composition over inheritance?
Instead, your could pack class can be composed of items:
public class WolfPack {
// composed of items
private List<Wolf> _wolves = new List<Wolf>();
// lets you add items
public void Add( Wolf wolf ) {
this._wolves.Add( wolf );
}
public IEnumerable<Wolf>() {
return this._wolves;
}
public Wolf Omega { get; set; }
...
This way you hide the way pack is composed of items and, in future, you could even completely change the implementation (to use another type of list or to change the way wolves are added to the pack for example) with/without changing the interface. On the other hand, inheriting from List would determine the class interface and would not let you change/remove specific methods/properties.
There is a class that I want to create as abstract but I can't because that class's base class is ActiveReports and as soon as I make it abstract the sub-reports are no longer designable. (Interestingly the base class itself IS designable but not it's children).
I know that I cannot declare class members as abstract without first declaring the class as abstract.
In this case what is the NEXT BEST way to do this. At this point I made the members virtual and added comments to each one. Where it made sense I also declared a member as protected rather than public. But is there some other best way that would REQUIRE that these members be overridden at compile-time rather than run-time?
If you were in this situation how would you do it?
EDIT
Let me explain further. I can create a class (lets call it MyReportsBase) that inherits from ActiveReports. (I do that using add new and choose the ActiveReports type) Then ActiveReports provides a property of the report object in MyReportsBase (in design time properties) called MasterClass. Once I set that property to true then I can then create new reports and inherit from MyReportsBase instead of directly from ActiveReports. (The way you do that is by create add new ActiveReports but then edit the code in the code-behind to inherit from MyReportsBase instead of ActiveReports).
That is all well and good and it all works perfectly well. However, my requirement is that MyUpwardBase would HAVE to be inherited (declared abstract with a few abstract members). And I CAN go in the code-behind and set the abstract modifier on the base class. And even then I can design MyReportsBase. However, at that point, all of the reports that I inherited from MyReportsBase are no longer designable. Attempting to open the derived reports in the designer throws an error about how the designer cannot open the base class because it is declared as abstract.
All of this is to just clarify the question. Right now the Interface suggestion is making the most sense to me.
EDIT 2
An Interface doesn't really do it for me either for this reason. The base classes "abtract-but-aren't-abstract" members HAVE To be present in my base classes because I have virtual and public members that depend on them. And in my case, because I cannot declare the class as abstract, I have to have an implementation for those members.
As soon as I provide an implementation for those members then all of my inheriting classes ALSO have the implementation and the Interface doesn't complain at compile time. I thought by removing the virtual modifier from those members that the compiler would require them but it did not behave that way.
I am beginning to think that my solution (document the members well) is the best solution.
Why are the base classes of a abstract class that also has a baseclass not designable?
public class Base
{
public int SomeInt { get; set; }
}
public abstract class BaseChild : Base
{
public abstract string Value { get; set; }
}
public class ChildChild : BaseChild
{
public override string Value { get; set; }
}
Works. Or did I misunderstood?
var child = new ChildChild { SomeInt = 3, Value = "asd" };
you dont want to use interface ?
class A: ActiveReport
{
// some public methods to share between all childs
}
interface IReport
{
// some required method
}
Class B: A, IReport
{
}
Class C: A, IReport
{
}
.
.
.
I have 2 class's
Class 1.
public class BaseContentPage : System.Web.UI.Page
{
}
Class 2.
public class BaseUserControl : System.Web.UI.UserControl
{
}
And now i want them to be aware of this class.
public class BaseCommon
{
public string Variable1 { get; set; }
public string Variable2 { get; set; }
public string Variable3 { get; set; }
}
How I'm currently doing it is by making the variables of the BaseCommon class static like so
public static string Variable1 { get; set; }
public static string Variable2 { get; set; }
public static string Variable3 { get; set; }
How else can i do this?
Use composition.
Give BaseContentPage and BaseUserControl a private field (which can be exposed as a property if needed) of type BaseCommon (don't make it static).
They can either create BaseCommon or have an instance passed in through the constructor (Dependency Injection).
First off, I don't think you want the BaseCommon properties to be static. The properties are then global across the application so changing them from one instance will change them for all instances.
What you're talking about is multiple inheritence and it isn't supported by c#. You'd be better off changing BaseCommon to be an interface and having BaseContentPage and BaseUserControl implement that interface.
If they are static, does that mean that this third class is a global resource? You could look at Singleton or IoC containers or pass the instance to the other classes when constructed.
You need to give more concrete examples of what this common "base" data that you are adding to two different parts of your object inheritance tree are.
Conceivably, say each instance really just has similar data (an example I'm thinking of is internationalization, say, which is used to customize both a page and a usercontrol according to phrase IDs, etc which are specific in context), then what you can do is have a class I18nSettings which implements II18nSettings. Then in each class, encapsulate an I18nSettings instance and implement II18nSettings and pass them through. Alternatively, you can expose the internal I18nSettings instance. I've even just defined an interface and had each class implement it - it was not worth having a separate class at all.
There are other options to do this kind of thing - it depends on whether the concrete classes you are inheriting from implement a lot more useful things than the things you are adding. It might make more sense to inherit from your concrete class and implement other interfaces so that the class can be used in other places.