Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding fields or properties in subclasses

People also ask

Can you override fields?

From this definition, member fields can not be overridden like methods. When a subclass defines a field with the same name, the subclass just declares a new field. The field in the superclass is hidden. It is NOT overridden, so it can not be accessed polymorphically.

Can we override fields in Java?

Fields can't be overridden; they're not accessed polymorphically in the first place - you're just declaring a new field in each case. It compiles because in each case the compile-time type of the expression is enough to determine which field called number you mean.

Can properties be overridden?

You cannot "override" fields, because only methods can have overrides (and they are not allowed to be static or private for that). This trick lets A 's subclasses "push" a new value into the context of their superclass, getting the effect similar to "overriding" without an actual override.

Can you override a property in C#?

In C#, class methods, indexers, properties and events can all be overridden. Non-virtual or static methods cannot be overridden. The overridden base method must be virtual, abstract, or override. In addition to the modifiers that are used for method overriding, C# allows the hiding of an inherited property or method.


Of the three solutions only Option 1 is polymorphic.

Fields by themselves cannot be overridden. Which is exactly why Option 2 returns the new keyword warning.

The solution to the warning is not to append the “new” keyword, but to implement Option 1.

If you need your field to be polymorphic you need to wrap it in a Property.

Option 3 is OK if you don’t need polymorphic behavior. You should remember though, that when at runtime the property MyInt is accessed, the derived class has no control on the value returned. The base class by itself is capable of returning this value.

This is how a truly polymorphic implementation of your property might look, allowing the derived classes to be in control.

abstract class Parent
{
    abstract public int MyInt { get; }
}

class Father : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "X" and return a value */ }
    }
}

class Mother : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "Y" and return a value */ }
    }
}

Option 2 is a non-starter - you can't override fields, you can only hide them.

Personally, I'd go for option 1 every time. I try to keep fields private at all times. That's if you really need to be able to override the property at all, of course. Another option is to have a read-only property in the base class which is set from a constructor parameter:

abstract class Mother
{
    private readonly int myInt;
    public int MyInt { get { return myInt; } }

    protected Mother(int myInt)
    {
        this.myInt = myInt;
    }
}

class Daughter : Mother
{
    public Daughter() : base(1)
    {
    }
}

That's probably the most appropriate approach if the value doesn't change over the lifetime of the instance.


You could do this

class x
{
    private int _myInt;
    public virtual int myInt { get { return _myInt; } set { _myInt = value; } }
}

class y : x
{
    private int _myYInt;
    public override int myInt { get { return _myYInt; } set { _myYInt = value; } }
}

virtual lets you get a property a body that does something and still lets sub-classes override it.


option 2 is a bad idea. It will result in something called shadowing; Basically you have two different "MyInt" members, one in the mother, and the other in the daughter. The problem with this, is that methods that are implemented in the mother will reference the mother's "MyInt" while methods implemented in the daughter will reference the daughter's "MyInt". this can cause some serious readability issues, and confusion later down the line.

Personally, I think the best option is 3; because it provides a clear centralized value, and can be referenced internally by children without the hassle of defining their own fields -- which is the problem with option 1.


You could define something like this:

abstract class Father
{
    //Do you need it public?
    protected readonly int MyInt;
}

class Son : Father
{
    public Son()
    {
        MyInt = 1;
    }
}

By setting the value as readonly, it ensures that the value for that class remains unchanged for the lifetime of the object.

I suppose the next question is: why do you need it?