Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not use class fields directly? [duplicate]

So I know classes and structures are structures of data. Class fields are by default private and structure ones - public. Like public: / int a; for C++ and public int a; for C#

But other ways of access these fields are by making them private and use functions/methods. Like SetValue(int value){a = value;} and GetValue() { return a; } or I've even heard of the new cool {set; get;} in C#.

But why? Many people have told me 'other people could access your variables this way, so make them private'. I don't get it, what difference does it make making them public and just use them obj.a = 3; or making them private and doing obj.SetValue(3);? Could someone (even briefly) explain what the differences are and how can s.o. get to those fields when they're public?

like image 340
Bonnev Avatar asked Dec 26 '22 17:12

Bonnev


2 Answers

There exist many reasons why you would want to use properties (getters and setters) instead of public fields (instance variables made public). Some of them are:

  • You can allow read-only access to external classes (by providing a getter, but not a setter)
  • You can calculate the value when it is accessed.
  • You can change how the value is accessed/calculated without breaking existing code.
  • You can change the internal representation without breaking existing code.
  • You can override properties in subclasses, which is not possible with fields.
  • Etc.

Also, there aren't really that many downsides to using properties. So the pros outweigh the cons.

like image 77
MAV Avatar answered Dec 28 '22 07:12

MAV


The answer differs for different languages.

In C++ it is a good idea to make attributes private and provide getter and setter methods because C++ provides const correctness - and setters cannot be called on a const object.

In C# which does not offer const correctness it may seem pointless to do other than simply offer all attributes up as public, as the moment there is a setter it can be called at any time anyway.

But what if, for example, the property is a container (List, for example). It might then be that you only want people to be able to manipulate the list but not set the list pointer to a new value - so you would define the property like this:

class Contrived
{
    private List<Things> m_List = new List<Things>();

    public List<Things> LIST{ get {return m_List;} }
};

Or maybe you only want people to be able to examine the list, but not add or remove things from it:

class Contrived
{
    private List<Things> m_List = new List<Things>();

    public IEnumerable<Things> LIST{ get {return m_List;} }
};

In that way we are staggering towards faking const correctness by use of interfaces, although IMO it's not as good as just having a const correct language. ;-) Indeed, in the last example we provide a list that cannot be modified but who's contents can be, so we could implement the property like this (assuming Things implements IUnmoddableThing):

class Contrived
{
    private List<Things> m_List = new List<Things>();

    public IEnumerable<IUnmoddableThing> LIST{ 
    get 
    {
        List<IUnmoddableThing> temp = new List<IUnmoddableThing>();
        ... copy m_List into temp ...
        return temp;
    } }
};

Clearly allowing us much more control than simply making the member attribute public. And that's before we get into a property hiding the fact that we actually, maybe ... oh, connect to a remote database, via a socket, carried by a bespoke military radio...

Once you realise that a setter can be denied use at compile time (in a const correct language) and that a getter/setter or get/set (depending on language) can do more than simply assign or return, they can be very powerful.

like image 36
Grimm The Opiner Avatar answered Dec 28 '22 05:12

Grimm The Opiner