PDA

View Full Version : Getters and Setters, is this an example of where I should use them?


Nickbee
10-14-2010, 01:55 PM
I’m just starting to get my head around OOP. In my last few projects I wrote some custom classes where I saw fit. In this example I wrote a class to provide a non-repeating Array.

ArrayShuffle Class:
// com > ArrayShuffle.as
package com{

//imports
import flash.display.Sprite;

//declare ArrayShuffle class
public class ArrayShuffle extends Sprite
{
//vars
//var to hold argument from the constructor
public var _arrayLength:uint;
//temp array to initialy hold the numbers in sequential order
public var _tempArray:Array = new Array();
//array to be populated with the numbers in random order
public var _shuffledArray:Array = new Array();

//constructor method ArrayShuffle
//argument passes the amount of numbers in the final shuffled Array
public function ArrayShuffle(arrayLength:uint)
{
//pass the argument to the class var
_arrayLength = arrayLength;

//set up loop to populate the _tempArray with sequential numbers based on the _arrayLenght var
for (var i:int=0 ; i<_arrayLength ; i++){
//populate the _tempArray with the current value of i
_tempArray.push(i);
}//closes for loop

//set up loop to randomly populate the _shuffledArray
while (_tempArray.length > 0)
{
//declare r which is a random number based on current the length of _tempArray
var r:int = Math.floor(Math.random()*_tempArray.length);
//populate the _suffledArray with the value of _tempArray at the index of r
_shuffledArray.push(_tempArray[r]);
//remove to value of _tempArray at the index of r since it is no longer needed
//this assures that the _shuffledArray will contain non-repeating random numbers
_tempArray.splice(r,1)
}//closes while loop

}//closes ArraySuffle constuctor method
}//closes public class ArraySuffle
}//closes package

Document Class:
//Document Class Test
package {
//flash imports
import flash.display.Sprite;

//custom class imports
import com.ArrayShuffle

//declare Test class
public class Test extends Sprite
{
//vars
//_testArray to populate non-repeating numbers from the ArrayShuffle Class
var _testArray:Array = new Array();

//Test constructor method
public function Test()
{
//new instance of the ArrayShuffle Class
//argument of 10 passed - the amount of non-repeating numbers to create
var _arrayShuffle:ArrayShuffle = new ArrayShuffle(10);

//transfer non-repeating numbers from _arrayShuffle instance to class var
_testArray = _arrayShuffle._shuffledArray;

//trace _testArray
trace(_testArray); //1,5,6,2,8,9,3,4,7,0

}//closes Test constructor method
}//closes Test class
}//closes package

My question… What is the best way to access the Array made by the ArrayShuffle Class? I just used public vars and transferred the data to local vars. But I think this might be a good place to use a getter?

Thanks for any insight…

tadster
10-14-2010, 10:38 PM
no, not in this case, it's fine the way it is

TomMalufe
10-15-2010, 01:40 PM
I use getter setters quite regularly. I think it's good to be able to overwrite them in a child class making all public properties more flexible.

For example, if I want something to happen whenever say... character.health is changed. I can write that code in the setter function. That way I don't have to constantly check the value, or remember to do that thing (maybe just dispatch an event) whenever I change it elsewhere.

did you know that you can override the x and y getter setters on a DisplayObject? It's kind of cool if (for example) you wanted to give a little depth look in the upper y direction, then you can override the y setter and change the scale of the object based on the y position.

SOMETIMES I use getters to make a value read-only by not giving it a setter.
But, in your case above it won't really matter and you can just use your public vars since complex vars like Arrays are passed by reference anyways so giving any access to it is going to give complete access to it (unless you only return a copy).

I kind of wonder why your ArrayShuffle class extends Sprite though... is it a DisplayObject that you might add to stage at some point?

drkstr
10-18-2010, 03:57 AM
As a rule of thumb, always use getters/setters for public properties. If you're using Flash Builder or Flash Develop, you can auto generate these from a private property. Don't extend Sprite if you are not putting the class on the display list. Don't prefix public vars with an underscore. That is meant to denote private vars.

tadster
10-19-2010, 12:58 AM
As a rule of thumb, always use getters/setters for public properties


I have to disagree, as a rule of thumb, only use getters and setters if they will actually do more than just get or set some private value.

You can think of getters and setters as the main things you will use when creating code for someone else to use/see/incorporate, they are what you use when you are creating your own language of sorts.

In general, for performance reasons, you want to call the least amount of functions possible, and getters and setters are functions.

drkstr
10-19-2010, 04:59 AM
Well OOP isn't really meant for performance. I guess it comes down to personal taste, and the scale of the project. If you want to follow strict OOP design, then getters/setters are the way to go.

tadster
10-19-2010, 11:52 PM
I see OOP as a performance enhancer when used for that purpose.
There's no difference, in OOP, or otherwise between a public variable and a getter/setter that just switches a private variable.
Edit:

case in point,

this code is useless:

private var _someBoolean:Boolean = false;
public function get someBoolean():Boolean {
return _someBoolean;
}
public function set someBoolean(toThis:Boolean):void {
_someBoolean = toThis;
}

private function loop() {

if (_someBoolean == true) {
//... do stuff
}

}


The following code increases performance, yet remains object oriented:

public var booleanSwitch:int = 0;

public function get someBoolean():Boolean {
return Boolean(booleanSwitch == 1);
}

private function loop() {
if (booleanSwitch == 1) {
//do stuff...
}
}

drkstr
10-20-2010, 03:24 AM
Both of your examples defeat the purpose of getters/setters. I agree, that's not how they should be used at all. You should always reference your public getters/setters, even in your internal class (a few exceptions of course).

The purpose of getters/setters are to abstract your internal data state, and to provide a central point of access to data updates. Most of the time, your public properties aren't there for the sole purpose of holding data. When set, there is probably something somewhere in your class (or another class) that needs to know when that data changes. That is their purpose in life.

Maybe it's because I'm used to a more data-driven style of programming, rather than a "micro-processing" style, but I would simply die without being able to use getters/setters.

tadster
10-20-2010, 10:26 PM
Most of the time, your public properties aren't there for the sole purpose of holding data. When set, there is probably something somewhere in your class (or another class) that needs to know when that data changes.

That is a good description of when getters/setters can/should be used.

In the long run, we pretty much agree after all. :)

wvxvw
10-21-2010, 06:32 AM
tadster: You don't need to declare Booleans as false, they have default values. The calculated value of expression of type X == Y is of type Boolean, you don't need to cast it.

Regarding the subject: get/set functions allow for easier debugging in development, however, I've seen another interesting approach:
CONFIG::debug {
public function get foo():Object { /* implementation */ }
public function set foo(value:Object):void { /* implementation */ }
}
CONFIG::release {
public var foo:Object;
}
Of course, as mentioned before, if designing a general purpose library, you won't do it like this (or maybe, just like in CPP, distribute debug + release library versions...)

ASWC
10-21-2010, 02:08 PM
but I would simply die without being able to use getters/setters.Same here! ;)

tadster
10-23-2010, 01:13 AM
You don't need to declare Booleans as false, they have default values. The calculated value of expression of type X == Y is of type Boolean, you don't need to cast it.



Really? I thought for sure that the default value for all Booleans was maybe.
And doesn't the casting make it look more pretty?

:p

wvxvw
10-23-2010, 10:49 AM
Booleans aren't nullable (thanks god) in AS3 :)
At the last place I worked, the project I inherited was maintained by two girls, who were some sort of acquaintance / family of the company owner. On the first reading of the code I was fascinated by something I haven't seen before:
if ((!(foo)) && (bar == null)) { ... }
When I eventually saw the girl who wrote that, I asked whether she writes in Lisp, or why does she like parens so much. She told me that way it looked prettier to her. I had no further arguments.

tadster
10-23-2010, 04:10 PM
Wvxvw... I was just joking with you... but I guess there really are those who use erroneous code for the sake of being "pretty" :D

bowljoman
10-23-2010, 05:30 PM
Booleans aren't nullable (thanks god) in AS3 :)

Try again.


var obj:Object={bolVal:new Boolean()};
trace( obj.bolVal === false )

obj.bolVal=1;
trace(obj.bolVal === true )

obj.bolVal=true;
trace(obj.bolVal === true )

obj.bolVal=null;

trace(obj.bolVal == true )
trace(obj.bolVal === null )

delete obj['bolVal'];
trace( obj.bolVal )

ASWC
10-23-2010, 05:34 PM
Try again.

Really? Going the untyped way to prove nothing? Then null this:
var bool:Boolean;

bowljoman
10-23-2010, 05:38 PM
:)

bowljoman
10-23-2010, 05:49 PM
public dynamic class quant extends Sprite
{
public function quant()
{
this.b=new Boolean();
this.b=null;
}
}
:p

bowljoman
10-23-2010, 05:56 PM
I know Im not nulling the boolean, Im nulling the temporary pointer to the boolean.

ASWC
10-23-2010, 06:09 PM
just open a new thread called "I can put everything in untyped variable" and that will do it. ;) As for proving anything about boolean, I don't think that does it!

bowljoman
10-23-2010, 06:16 PM
yeah, just a little early morning fun and the old 'never say never' creed. All I played with is nulling a temp var, which could be a boolean, which is still null indeed.

ASWC
10-23-2010, 06:23 PM
Just to try to close that boolean chapter. Boolean have only two values, false and true. Everything you pass to a boolean will eventually be evaluated to false and true. Passing null is evaluated to false (you'll get a warning for that). null is a value. When you set a variable to null you pass to that variable a new value: null. All your custom class for example can by default accept a value of null. So var myvariable:MyCLass = null; is a valid value assignment.