Code

Coding, Programming & Algorithms, Tips, Tweaks & Hacks
Search

Property getters & setters

In traditional OOP, if we wanted to get or set an object's private member, we would need to write a public method to do the job.
The reason behind making a member data private and then accessing it through a public method is to avoid the implementing-user to access it directly.
There can be many reasons for prohibiting direct access to member data to the implementing-code.
For example, you may want a radius of a Circle to be within the range of 10 - 500.

C++: Traditional OOP
class Circle
 {
        private:
          int radius;

        public:
          Circle(int radius = 15)
           {
                  setRadius(radius);
           }

          void setRadius(int radius)
           {
                  if (radius < 10 || radius > 500)
                   {
                          this->radius = -1;
                          cout << "Radius must be within the range of 10 - 500" << endl;
                   }
                  else
                   this->radius = radius;
           }

          int getRadius()
           {
                  return this->radius;
           }
 }

void main()
 {
        Circle c = Circle();
        c.setRadius(25);
        cout << c.getRadius();
 }
C++

In languages like PHP & Python & PERL which have a weak type system, a further check of the data type may be necessary.
But for Python unfortunately even traditional getter & setter methods cannot be implemted because Python doesn't have a public or private. Everything is public by default - though a member can be made private by prefixing two underscores to it. But this is only for convention, it doesn't really serve its true purpose.

PHP 5 and C# .NET have a getter and setter method feature, making it look like we're accessing the data member directly.

PHP
<?php
class Circle
 {
        private $radius; # integer

        # Constructor
        public function __construct($radius = 15)
         {
                self::__set('radius', $radius);
         }

        # Setter
        public function __set($name, $value)
         {
                switch ($name)
                 {
                        case 'radius':

                          if (!is_numeric($value)) # is_int() for strong type checking
                           throw new Exception('Radius must be of a numeric type');

                          if ($value < 10 || $value > 500)
                           throw new Exception('Radius must be within the range of 10 - 500');

                          $this->radius = $value;

                        break;

                        default:
                          throw new Exception("Attempt to set a non-existing property: $name");
                        break;
                 }
         }

        # Getter
        public function __get($name)
         {
                if (in_array($name, array('radius')))
                 return $this->$name;

                switch ($name)
                 {
                        default:
                          throw new Exception("Attempt to get a non-existing property: $name");
                        break;
                 }
         }

 }

$c = new Circle();
$c->radius = 25;
echo $c->radius;
>
PHP 5.x
C#
using System;

public class Circle
 {
        private int __radius = 5;

        public Circle()
         {
         }

        public Circle(int radius)
         {
                this.radius = radius; // This will call the property defined below
         }

        public int radius // Property getter/setter name cannot be the same as the member variable name
         {
                get
                 {
                        return __radius;
                 }

                set
                 {
                        if (value < 10 || value > 500)
                         throw new Exception("Radius must be within the range of 10 - 500");

                        __radius = value;
                 }
         }
 }

public class main
 {
        public static void Main(string[] args)
         {
                Circle c = new Circle(); // Circle c = new Circle(5); will throw an Exception
                c.radius = 25;
                Console.WriteLine(c.radius);
         }
 }
.NET 2.0

C# .NET 3.0 has introduced Automatic Properties where you don't need to specify code for the getter & setter - the compiler takes generates the method body.

JavaScript does seem to have a getter and setter method which I came across just now when searching for the official source to Java 7's new features' documentation, but :

  • only within an object initializer - not inside a function so it doesn't seem to be of much use as we can't create instances
  • doesn't hide the member from being accessed directly
  • doesn't work in IE.

JavaScript
var someObj =
 {
        a : 7,
        get b()
         {
                return this.a * 3;
         },
        set c(x)
         {
                this.a = x / 2;
         }
 }

someObj.foo1 = function()
 {
        //
 }

alert(someObj.a); // 7
alert(someObj.b); // 21
someObj.c = 5; alert(someObj.a); // 2.5
someObj.foo1();
JavaScript 1.5

The Getter & Setter feature does not seem to be a much "wanted" feature in the Java community.
Still, this has been proposed by RĂ©mi Forax for JDK 7.

Java: Proposal
public class Circle
 {
        private int __radius = 5;

        public Circle()
         {
         }

        public Circle(int radius)
         {
                this.radius = radius; // This will call the property defined below
         }

        public property int radius // Property getter/setter name cannot be the same as the member variable name
         {
                get
                 {
                        return __radius;
                 }

                set (int radius)
                 {
                        if (radius < 10 || radius > 500)
                         throw new Exception("Radius must be within the range of 10 - 500");

                        __radius = radius;
                        // firePropertyChange(radius);
                 }
         }

        public static void main(String[] args)
         {
                Circle c = new Circle(2); // Circle c = new Circle(5); will throw an Exception
                c.radius = 25;
                System.out.println(c.radius);
         }
 }
JDK 7
Vanakkam !

0 comments: