17

Why is it allowed to change the visibility and existence of getters or setters in a property when implementing an interface?

interface IFoo
{
    string Bar { get; }
}

class RealFoo : IFoo
{
    public RealFoo(string bar)
    {
        this.Bar = bar;
    }

    public string Bar { get; private set; }
}

class StubFoo : IFoo
{
    public string Bar { get; set; }
}

...and not legal to do the same when implementing an abstract class?

abstract class AbstractFoo : IFoo
{
    public abstract string Bar { get; }
}

class RealFoo : AbstractFoo
{
    public RealFoo(string bar)
    {
        this.Bar = bar;
    }

    // Cannot override because 'Bar' does not have an overridable set accessor
    public override string Bar { get; private set; }
}
9
  • 2
    In your example, you're adding code to the interface implementation, as there was no setter, but you're changing visibility in the abstract class implementation. So it's not the same. Commented May 19, 2011 at 12:11
  • 1
    @jv42 No visibility is being changed in the implementation because the setter is private. The restriction is arbitrary and foolish ... C# could just as well be specified to allow override to only apply to get or set when they aren't private. Or it could allow public string Bar { override get; private set; } Commented Oct 25, 2014 at 0:35
  • @JimBalter I agree that there could be mechanisms to change accessors visibility. You might want to check what's coming in C# 6, I've seen some interesting new stuff for properties. Commented Oct 26, 2014 at 9:42
  • @jv42 I already know what's coming in C# 6 and it's not there. And the point was that your comment was wrong. Commented Oct 26, 2014 at 16:21
  • @JimBalter Well, we're in disagreement then. Commented Oct 27, 2014 at 7:50

4 Answers 4

12

The interface declares what public properties the class must have (It's just a contract). Which means you need to have those properties, but can add to them.

The abstract class declares the actual structure of those properties. So if you don't have the setter in the abstract base, you can't add to it in the implementation.
When you write the override modifier it looks in the base class for something to override.

Sign up to request clarification or add additional context in comments.

Comments

7

It perhaps becomes clearer if you think of the getters and setters as the methods that they eventually become.

In the case of the interface you are defining this:

interface IFoo
{
    string GetBar();
}

Which can be read as "all classes that implement this interface must include this method." Both of your classes do:

class RealFoo : IFoo
{
    public string GetBar();
    private void SetBar(string value);
}

they also implement SetBar(), but that is immaterial; they have fulfilled the contract defined by the interface and are valid.

The abstract class, on the other hand is this:

abstract class AbstractFoo : IFoo
{
    public abstract string GetBar();
}

Which means that all child classes must provide a method body for GetBar()

The class you made is this:

class RealFoo : AbstractFoo
{
    public override string GetBar();
    public override void SetBar(string value);
}

By putting the override modifier in front of the SetBar method the compiler is expecting to find an abstract or virtual version in the base class. You don't have that so the compilation fails.

4 Comments

This means that properties are really just shortcuts for setters and getters, and assume nothing about good oo-design principles.
So you’re indirectly saying that C# would have to add syntax like public string Bar { override get; set; } and then we’d be less arbitrarily restricted in how we implement abstract properties. That actually makes sense.
@binki It does make sense, which is why these answers don't and the restriction is arbitrary, and poor design. C# doesn't have to "add syntax", it can simply take the syntax the OP provided and treat it intelligently, rather than require us to explicitly provide a backing variable.
You've taken the words out of my mouth @JimBalter. In my mind, both abstract classes and interfaces should define minimum requirements, not maximum requirements, for the API supported by implementing/inheriting classes. Another example of a "C# should treat it intelligently" argument: stackoverflow.com/questions/858080/…
0

An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes.

An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.

Taken from the MSDN http://msdn.microsoft.com/en-us/library/scsyfw1d(v=VS.71).aspx

2 Comments

Okay, this means that adding an abstract base class in the class hierarchy will force you to add an empty/exception-throwing setter implementation in some derived classes. Not the most elegant behavior.
This "answer" does not touch upon the question actually asked.
0

According to the C# specification

An accessor that is used to implement an interface may not have an accessor-modifier. If only one accessor is used to implement an interface, the other accessor may be declared with an accessor-modifier:

public interface I
{
  string Prop { get; }
}
public class C: I
{
  public Prop {
  get { return "April"; }     // Must not have a modifier here
        internal set {...}    // Ok, because I.Prop has no set accessor
  }
}

That means it is OK to have an access modified on a class implementing the interface. However, the abstract class declares an implementation and you cannot change that with a derived class.

3 Comments

abstract properties don’t have implementations. What do you mean by “the abstract class declares an implementation”? That an abstract class arbitrarily limits the implementation while an interface doesn’t arbitrarily limit the implementation?
Yes, abstract classes can have implementation. An abstract class may lack implementation or might be incompletely implemented. An abstract class is only supposed to be used for deriving other classes.
"abstract classes can have implementation" -- @binki said abstract properties don't have implementations. Your response does not address his comment. There's no good reason for C# to not allow something like public string Bar { override get; private set; }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.