Reputation: 3014
Is there a way i can have derived classes override the default value of the base class? In the example below i would need the Hammer.Name to return "Hammer".
public class ItemBase
{
public string Name = "Base";
}
public class Hammer: ItemBase
{
new public string Name = "Hammer";
}
public class Test
{
ItemBase MyThing = new Hammer();
// Prints "Base"
Console.WriteLine(ItemBase.Name);
}
Upvotes: 1
Views: 2458
Reputation: 10818
Trying to figure out what exactly is needed while skating around the .NET version restrictions has been a headache but I have a solution. According to your comments you can use a constructor.
In that case this is really easy to do with properties (which are the preferred way to handle your situation) instead of public fields:
public class ItemBase
{
public ItemBase()
{
//When instantiating ItemBase the value of Name is "Base"
Name = "Base";
}
public string Name { get; set; }
}
public class Hammer : ItemBase
{
public Hammer()
{
//When instantiating Hammer the value of Name is "Hammer"
Name = "Hammer";
}
}
And to test just run this:
public class Program
{
public static void Main()
{
ItemBase itemBase = new Hammer();
Console.WriteLine(itemBase.Name);
itemBase.Name = "Foo";
Console.WriteLine(itemBase.Name);
}
}
Outputs:
Hammer
Foo
This should check off all the boxes. You now use properties (making your code better), each class has a default value, and the properties can be changed after instantiation.
Upvotes: 0
Reputation: 120498
You might consider using virtual properties instead of exposing public fields (which is considered bad practice).
As such, you can (with C# 6.0):
void Main()
{
ItemBase myThing = new Hammer();
// Doesn't print "Base"
Console.WriteLine(myThing.Name);
}
public class ItemBase
{
public virtual string Name { get; } = "Base";
}
public class Hammer : ItemBase
{
public override string Name { get; } = "Hammer";
}
or (if you're using older version of C#)...
public class ItemBase
{
public virtual string Name { get { return "Base"; } }
}
public class Hammer : ItemBase
{
public override string Name { get { return "Hammer"; } }
}
Upvotes: 8
Reputation: 62276
You don't need different fields, you need different initializations of the same field.
class Base {
protected string name = "";
public Base() { name = "X"};
}
class Derived : Base {
public Derived() { name = "Y"}; //same {name } field of a Base class
}
Upvotes: 6
Reputation: 32780
You are not defining a new default value in the derived type, you are declaring a completely new field that hides the field with the same name in the base class.
Because fields can't be virtual, the returned field is the one declared in the type through which you are invoking it.
Solution? Don't redeclare a new field, simply assign a new value to the existing field in the constructor of the derived type:
public class Hammer
{
public Hammer() {
Name = "Hammer"; }
}
Upvotes: 1