This is an example, I'm just curious as to how it would be achieved.
I want to enable only subclasses of Animal
to be able to set the number of legs that they have, but I still want them to be able to set their own colour. Therefore, I want to restrict classes further down the hierarchy from then altering this Legs
property.
public abstract class Animal
{
public string Colour { get; protected set; }
public int Legs { get; protected set; }
public abstract string Speak();
}
public class Dog : Animal
{
public Dog()
{
Legs = 4;
}
public override string Speak()
{
return "Woof";
}
}
public sealed class Springer : Dog
{
public Springer()
{
Colour = "Liver and White";
}
}
public sealed class Chihuahua : Dog
{
public Chihuahua()
{
Colour = "White";
}
public override string Speak()
{
return "*annoying* YAP!";
}
}
For example, I want to eliminate this kind of subclass:
public sealed class Dalmatian : Dog
{
public Dalmatian()
{
Legs = 20;
Colour = "Black and White";
}
}
How would this be achieved?
I'm aware that I could stop overriding in a subclass by sealing the implementation of a function in the parent class. I tried this with the Legs
property but I couldn't get it to work.
Thanks
In part, this goes against OO principles. Your superclass Animal makes available a contract which includes the set/get for Legs. You then want a subclass to be able to restrict that interface to disallow set Legs. Since subclassing provides an "is-a" relationship, restricting the interface goes against this, which would mean that subclasses would not be true subtypes, since the set Legs methods is not present.
I would remove the setter for the Legs property from Animal, since that is an implementation detail. Instead simply have an abstract getter. Subclasses can then decide how best to implement this, either by returning a hard-coded value or by using a field to store the value.
Rather than having the Legs a field of the abstract class, you should make it a property only (remove the setter), and make it abstract.
In Animal
public abstract int Legs { get; }
In Dog
public override sealed int Legs { get { return 4; } }
In Java, you'd make the getters and setters final methods, so they couldn't be overridden. In C#, I believe the keyword you want is "sealed"; you'd seal the method, but not the entire subclass.
You'd make the variable itself private, so subclasses would have to use a getter/setter to access the variable.
class Quadruped : Animal
{
public int Legs { get {return 4;} }
}
class Dog : Quadruped
{
...
}
?
I guess then you'd never want to classify an octopus as a quadruped.
I think that if you have this sort of problem, you need to re-arrange the hierarchy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With