Reputation: 1153
Look at the following (pseudo) pattern:
public abstract class Animal {
public abstract AnimalType { get; }
public abstract override string ToString() {
return String.Format("{0}={1}", AnimalType, this.ToString());
^
// does this even work?
}
}
which would force every class that derives from it look like this:
public sealed class Horse : Animal {
// horse specific declaration
private string _name;
private int _age;
// forced
public override AnimalType {
get { return AnimalType.Horse; }
}
// horse specific declaration
public Name {
get { return _name; }
public Horse(string name, string age) {
_name = name;
_age = age;
}
// forced
public override string ToString() {
return String.Format("{0}({1}", _name, _age);
}
}
which would produce the following output:
Horse =MyHorseName(3);
Tiger =SomeOtherAttributesBecauseTigerIsDifferent
Problem is: When I want to force ToString() in the derived class, I can't have any functionality in the base class. I want the derived class to provide it's own string representation of itself, but still want to have a string representation that tells me, in this case, what type of animal it is.
Upvotes: 0
Views: 2108
Reputation: 1111
I dont know maybe push the variables used in the ToString code up the base class with some default values, but have the child classes change them. So the ToString() code in base class wont need to be overriden but will provide custom outputs as the base class variables keep changing to whatever the child wants them to be. for example consider this:
abstract class cbase
{
internal string _var1 = "def1", _var2 = "def2";
public override string ToString()
{
return string.Format("{0} - {1}", _var1, _var2);
}
}
class cchild1 : cbase
{
public cchild1()
{
_var1 = "umm";
_var2 = "ok";
}
}
class cchild2 : cbase
{
}
so for the above code:
new cchild1().ToString()
will output
umm - OK
while
new cchild2().ToString()
will output:
def1 - def2
so in this way, you dont have to override ToString in each child class but still the output format stays consistent in all inherited classes as you have defined in the base class. But you also have the liberty to override the ToString if there is a need.
Upvotes: 0
Reputation: 23218
I think your best bet is to declare and call a separate protected abstract string GetAttributes()
method. In addition, you can use sealed
to prevent subclasses from overriding the ToString()
implementation:
public abstract class Animal {
public abstract AnimalType { get; }
public sealed override string ToString() {
return String.Format("{0}={1}", AnimalType, this.GetAttributes());
}
protected abstract string GetAttributes();
}
public sealed class Horse {
protected override string GetAttributes() {
return String.Format("{0}({1}", _name, _age);
}
}
If Horse
attempted to override ToString
at this point, it would receive a compile error. Meanwhile, it's forced to implement GetAttributes
.
Upvotes: 5