views:

119

answers:

5

I'm a new programmer, so please forgive any dumbness of this question but can anyone please tell me how the folowing code is encapsulating private data-

public class SomeClass
{
    private int age;

    public int Age
    {
        get { return age; }
        set { age = value; }
    }

    public SomeClass(int age)
    {
        this.age = age;
    }
}

I mean, with no restriction logic or filtering logic in the properties, how is the above code different from the folowing one -

public class SomeClass
{
    public int age;

    public SomeClass(int age)
    {
        this.age = age;
    }
}

Is the first code providing any encapsulation at all?

+9  A: 

It's providing one piece of encapsulation: it's saying, "there's an Age property you can get and set, but I'm not going to tell you how I'm implementing it."

That's not very strong encapsulation, but it does keep the implementation details separate from the public API. Without changing the public API at all, you could start to store the age somewhere else - in two short fields, in a service somewhere, as part of a long field or whatever. You could put logging in the property to see how often it's used. You could add an event which gets fired when the age changes (that's an API change, but won't break existing callers).

EDIT: One thing to note: even though this does nothing now, the change to make it do something later is both source and binary compatible. Changing a field to become a property is not backward compatible, either in source or binary forms. In most cases it will be source-compatible, but not binary-compatible. In some cases source will no longer build. In more evil (and contrived, admittedly) both versions will build, but with different effects.

Also note that as of C# 3, you can declare a trivial property as easily as a field:

public int Age { get; set; }

I have an article about all of this which provides more details.

Jon Skeet
...but is it by any means "protecting" my private data? i thought protecting private data was an important purpose that encapsulation serves :(
Nero
Encapsulation gives you the ability to protect your private data. It's like saying "How come nothing is happening when I hit these rocks with this hammer? I thought hammers were for building things." It's just a tool. It's not going to force you to use it sensibly.
recursive
@Nero: It can be about data... it can be about implementation details. Both are part of encapsulation.
Jon Skeet
Encapsulation is more about hiding implementation details from callers. Having the ability to treat a function like a black box instead of having to understand how it works to return a value. Protecting private data is important but encapsulation does that indirectly.
Beth
It's providing one piece of encapsulation: it's saying, "there's an Age property you can get and set, but I'm not going to tell you how I'm implementing it." - i think thats the only thing going on here in the first code sample.
Nero
A: 

In your first example, SomeClass.Age is a property. The field "backing" the property is private. In your second example, SomeClass.age is a public field. While in many cases there may be no difference, choosing a property over a field gives you the ability to change the implementation without changing the API, or "shape" of the class. Maybe you want to do something (persist, or notify) whenever the property changes -- that would be impossible to do with a field.

Mark
You could turn the field into a property pretty easily ;-)
Victor Nicollet
There are differences. Properties can not be passed as `ref`. Fields can not be data bound.
recursive
+2  A: 

This is a bit of a vacuous example. As you've correctly noted, the property doesn't seem to do anything.

But it could. For example, SomeClass could put restrictions on how the Age property is modified (by say not changing the age to a bad value like -2 or 823). Also, SomeClass need not represent age as an int internally. Age could be the result of a computation (by say subtracting today's date from a person's date of birth) or it could be stored within SomeClass as another data type (say a byte, long or a double).

joshdick
Nero
@Nero: I don't know why you say "not expert" - in some cases a public writable, trivial property is exactly the right thing to have. It's still better than a public field.
Jon Skeet
@Nero: Yes, the semantic difference between a property and a public field is minimal, but that's not what matters. The point of good software engineering isn't just to write code that works; it's to write code that is understandable and extensible.Thus, what "could be" matters just as much as what "is."
joshdick
+1  A: 

I mean, with no restriction logic or filtering logic in the properties, how is the above one different from the folowing one

Its not the fact that you have or have not implemented the validation logic in the property, encapsulation here means that nobody can directly access/modify your private data. The only access available is to go through the property.

Using the bottom code, anyone can genereate exceptions and cause all kinds of havoc because they can do anything they want to your data.

Using the top code as its written allows this same havoc, but at any time in the future you can implement restriction logic in the Property and not have to modify an API for users of this class.

Jess
+1  A: 

It's encapsulating, or wrapping, changes to the private variable age. Private variable Age can't be modified by external callers directly, only through the public methods given. It's setting up an interface so future changes to age won't break callers. The benefit is to external callers in the future, which is why it's hard to see now.

Beth