Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

What are setters and getters?

Discussion in 'Scripting' started by macifone, Oct 26, 2009.

  1. macifone

    macifone

    Joined:
    May 24, 2009
    Posts:
    49
    What are setters and getters and what do they do? (Preferably for Objective-C)
     
  2. mrmop

    mrmop

    Joined:
    Oct 13, 2009
    Posts:
    23
  3. Timmer

    Timmer

    Joined:
    Jul 28, 2008
    Posts:
    330
    Hello,

    Unity doesn't support Objective-C so you may not get good language specific answers from us. However, getters and setters are not unique to that language and indeed are supported in .NET (mono).

    Basically, they are a way of encapsulating, or hiding, member variables from outside access and are at the heart of good object-oriented programming.

    You should generally never have a member variable accessible to the outside:
    Code (csharp):
    1. // bad oop
    2. class MyClass {
    3.    public name;
    4. }
    5. // access
    6. me = new MyClass;
    7. me.name = "Whatever I want";
    What you do instead is write a getter if you want the member visible and a setter if you want it writable:
    Code (csharp):
    1. //better oop
    2. class MyClass {
    3.    private name;
    4.    public string SetName(value) { // writable
    5.       name = value;
    6.    }
    7.    public string GetName() { // readable
    8.       return name;
    9.    }
    10. }
    11. // access
    12. myclass.name = "whatever" // error
    13. myclass.SetName("whatever") // ok
    Languages like many .NET-based ones also have built-in getter and setter support to make this even easier and more seemless:

    Code (csharp):
    1. // cleaner OOP
    2. class MyClass {
    3.    private name;
    4.    public Name {
    5.       get { return name; } // getter
    6.       set { name = value; } // setter
    7.    }
    8. };
    9. // access
    10. myclass.Name = "whatever" // works
    This hides the fact that you're using a setter/getter which many people feels more natural as the caller doesn't need to know if the variable is public or if it's a setter.

    Finally you may ask: WHY?

    The answer is that it allows you to make internal changes to the class without disrupting outside access. What if you started with a public variable 'name' and allowed people to access it directly but later you want to add validation so only names with no numbers can be set? You'd have to go and change all the code from "myclass.name = xyz" to "myclass.SetName(xyz);" or whatever. It's easier (and better) to just start with setters/getters. Also, what if you eventually don't even use a variable anymore but store it somewhere else?

    The concept is that you should aks an object to do something or ask it to give you some information without caring *how* it does it. Allowing direct access to its internals violates this concept.

    Unfortunately, Unity teaches bad practices since the editor needs to see public variables (tsk tsk). ;)

    Hope that helps!
     
  4. tonyd

    tonyd

    Joined:
    Jun 2, 2009
    Posts:
    1,224
    I disagree with this.

    For small developers doing relatively small projects, setters and getters add an unwarranted amount of complexity to your code. I personally wouldn't use them unless I really needed them.

    If you only have one programmer, he's going to know not to do stuff like:

    Character.name = 12;
    Weapon.number = "foobar";
     
  5. macifone

    macifone

    Joined:
    May 24, 2009
    Posts:
    49
     
  6. MadMax

    MadMax

    Joined:
    Aug 5, 2009
    Posts:
    203
    I think your missing the point. Its less complex in the long run. Maybe you have a point if you just do scripting and all your stuff inherits from monobehaviour

    c# Properties are nice like the one below

    public double Hours
    {
    get { return seconds / 3600; }
    set { seconds = value * 3600; }
    }

    however getters and setters allow you to SendMessage();
     
  7. Timmer

    Timmer

    Joined:
    Jul 28, 2008
    Posts:
    330
    Obviously, if you're the only coder you may do as you wish. But there's no reason to not hide members. In fact, in some languages (Ruby, Eiffel, etc) it is impossible to have public members (or at least writable members) and must be accessed via methods.

    As mentioned above, in .NET and Ruby, Eiffel, etc they can disguise the fact that they are methods so you can still type "object.name = value". Also, .NET allows you to say (at least in BOO but I think C# offers similar):
    Code (csharp):
    1. class MyClass:
    2.    [Property(Name)] # creates a getter + setter
    3.    private name as string
    4.    [Getter(Age)] # creates a getter only
    5.    priavet age as int
    Making it even easier.

    Well designed code is just as important on a one-person project as a many-person project. :)
     
  8. Per

    Per

    Joined:
    Jun 25, 2009
    Posts:
    460
    Getter/Setter systems are just good policy for clean readable code. They also become vital once you start dealing with threading, it really helps reduce the potential for error.

    For ultimate speed you can use direct access, you basically reduce branching (stack access) by doing so, but it can reduce the readability, debugging ease and extensibility down the line, so use direct access with care and understanding of class/application needs.

    Objective C more or less forces you to use them. Personally I dislike that, it's as bad as not supporting pointers because with bad coding habits and inexperience they can cause a lot of crashes, you may as well remove threading then too for the same reasons.

    This stuff is down to you as a developer, there are times when it's advantageous to use getter/setters, and other times when direct access makes more sense. Both are legitimate and valuable tools, and with more experience you'll be able to work out when and where is best to do either.
     
  9. kevinr

    kevinr

    Joined:
    Jul 24, 2008
    Posts:
    263
    That's not the issue. Since getter/setters wouldn't solve that issue either.

    Encapsulation gives you various advantages, most of which have to do with design, rather than issues arising from multiple programs. But, good design and standards does help when you start having multiple programmers.

    For instance.. lets say in your RPG you let the player choose the name of the character.

    so in your character class you have a variable for name.

    Code (csharp):
    1.  
    2. string name;
    3.  
    4. public void name
    5. {
    6.     set {  
    7.               name = value;
    8.               if (name == null || name.Equals(''))
    9.                   name = "Dark Master" ;
    10.           }
    11. }
    12.  
    It's a good standard of putting code like this. Or when you decide later on, you need to add some sort of validation or some other instruction of the data, it's built right into the class itself. If you have various objects that might pass data to name, you wouldn't want to have to repeat that code every instance accessing it. Then if you need to change things around, you'd have to find that code in every spot.

    The other major benefit is with inheritance. You may want to change how an inheriting class deals with what is being sent to a class member.

    But basically, it just good just good for the fact that it leaves you room to add code in the future, since you never know.

    And yes. It does keep other programmers in line (and yourself). You wouldn't want someone to just accesses 'speed' directly and do something like speed-=50; and then you wind up with -25. It could produce an undesired result if you are never expecting it to go bellow 0. Instead in the setter you can make sure it doesn't go below 0.
     
  10. immortius

    immortius

    Joined:
    Aug 7, 2009
    Posts:
    41
    Defensive programming is the name of the game, and it is easier to validate variable setting at a single point rather than everywhere it can happen.
     
  11. tonyd

    tonyd

    Joined:
    Jun 2, 2009
    Posts:
    1,224
    And that folks, is MY point.

    I'm not saying not to use setters/getters. I'm saying to use them when you need to, when it makes sense to do so.

    Don't simply do it because a teacher or an author (who have likely been programming for less years than many of us here) says it's the 'standard' or 'good form'.

    What 'good form' is varies widely from one language to another. In python, code readability and brevity is good form, and using getters/setters when not needed is frowned upon. Variables should be public unless you REALLY need them to be private. In fact, Python doesn't have TRULY private variables, as they can still be accessed directly, it simply becomes a little more difficult to do so.

    In the end, write code that makes sense to you, that you can maintain... because once your code is compiled, no one else is going to see it!

    Of course, if you're aiming to work at Epic or Microsoft one day, you damn well better learn what they consider "good form" and start practicing it now. But I personally have no interest in that.
     
  12. TWest

    TWest

    Joined:
    May 26, 2009
    Posts:
    131
    Personally if I am designing something I want to be able to apply it to more than one thing I find getters and setters allow me to make a more modular reusable code. At the most basic its just a couple more lines of code.
     
  13. Nick-Wiggill

    Nick-Wiggill

    Joined:
    Jan 31, 2010
    Posts:
    46
    I think you'll find the reason that getters and setters are such a popular way to do things, is due to the Gang of Four's well-known suggestion to "Program to an interface, not an implementation." Unfortunately novices frequently know about the practice of making redundant getters and setters, but not the reason behind it, thus making it a little pointless.

    The reason for this approach is that programming to an interface can improve development times, if the concepts behind it are clear. The core concept is this: Whether it's for a banking system or a video game, classes are best designed from the outside in, i.e. first we ask, "How do client classes want to access this new class; what service(s) does it need to provide them?", and after defining that service interface, we decide how to build the internal functionality of that class to serve that interface and thus satisfy client classes' requirements.

    When you design/develop to interfaces, what you are doing is confirming that you really know what your class is about before you get started. Without that step, you could be running yourself in circles for a while. Internally to the class, it doesn't matter how shoddily you implement those services/methods (at least at first!), just so long as the class provides, through it's method interface, what the client classes are asking for. This is prototyping. Optimisation and cleanup are best left for later, to quote Knuth, "Premature optimisation is the root of all evil."

    Basically, it's a way of doing the least amount of work to accomplish working functionality in the shortest time, and is in line with the principles of Agile software development and Extreme Programming.

    Now any novices can go and read about designing to an interface, or drop redundant getters and setters if they're not going to use them properly and just use public variables instead.