Data Encapsulation Help (newbie)

Moderator
Posts: 704
Joined: 2002.04
Post: #16
(Caveat lector: it is approximately half-past four in the morning – I may be writing nonsense ZZZ)

I'm not sure what it is you're asking; if you're referring to eg.

Code:
-(void) setNumerator: (int) n
{
    numerator = n;
}

[...]

[myFraction setNumerator: 1];

"numerator" is an instance variable.

"-(void)setNumerator:(int)" is a method (an instance method if you want to be pedantic - there also exist class methods.)

"numerator" represents an integer value.

"-(void)setNumerator:(int)" represents ≥0 instructions – yes, a method with no instructions in it is legal – which don't necessarily have to relate to "numerator" at all.

The statement "numerator = 21;" assigns the value 21 to the instance variable "numerator".

The statement "[myInstance setNumerator:21];" sends the message "setNumerator:21" to the instance "myInstance", causing the instructions in "-(void)setNumerator:(int)" to be executed.

I'm not sure how much knowledge of C you have, but you may be aware that you can access the members of a struct in the following fashion:

Code:
struct t_ExampleStruct
{
    int m_i;
};

[…]

struct t_ExampleStruct es;
es.m_i = 21; // <- This will work :)

Unlike the members of a struct, instance variables are not accessible outside of the instances to which they belong – you can't directly assign a value to (or read the value of) an instance variable – you must go through the intermediate step of using a method (setter or getter.)

Code:
@interface ExampleClass : NSObject
{
    int m_i;
}
-(void)setI:(int)p;
@end

@implementation ExampleClass
-(void)setI:(int)p
{
    m_i = p;
}
@end

[...]

ExampleClass *ec = [[ExampleClass alloc]init];
ec.m_i = 21; // <- This won't work :( [1]
[ec setI:21]; // <- This will work :)

[1] Because I'm a pedant, I'll mention that this can be made to work – however, behind the scenes it is still sending a message to the "-(void)setI:(int)" method of "ec", it is still not assigning a value to the instance variable directly – it is just a little syntactic sugar to make life easier.

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #17
(Apr 5, 2013 06:01 PM)easy_e Wrote:  What is the difference between the accessors "[myFraction setNumerator/Denominator = __]" and the "numerator/denominator = __"? (Btw, the setNumerator/Denominator is obviously a method that applies the number to the ivar - I assume just like the latter does, but I still do not know which one of the ways is better?

I suppose your question could be answered in the following fashion:

"[myFraction setNumerator/Denominator = __]" is possible both inside and outside the class – it is sending a message to an instance (eg. [myFraction setNumerator:21];" outside, "[self setNumerator:21];" inside.)

"numerator/denominator = __" is possible only inside the class – it is an assignment statement.

Inside a class, whether it is better to directly assign a value to an instance variable – "numerator = 21;" – or to use a method which assigns a value to an instance variable – "[self setNumerator:21];" – depends on whether eg. "-(void)setNumerator:(int)" performs some sort of error checking.

Outside a class, as you can't directly assign a value to an instance value, there can be no discussion of what is better – you have to use a setter.

Okay, I somehow forgot that the following is possible:

Code:
@interface ExampleClass : NSObject
{
    @public
    int m_i;
}
@end

@implementation ExampleClass
@end

[...]

ExampleClass *ec = [[ExampleClass alloc]init];
ec->m_i = 21;

I'm an idiot, and I'm going to go to bed before I write any more nonsense Cry

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Member
Posts: 60
Joined: 2013.03
Post: #18
Erm......... Uh.......... Now I'm confused again.

I'm just gonna pretend I understood all of that and tell myself that I can move on to the next chapter..... Rasp

Thanks though. You might or might not be writing nonsense (I have no idea) but either way I don't get it. But I understand the answer to the question I originally had, so it's fine! haha

Being more specific:

1. I have no C knowledge
2. I'm not an idiot (just putting that out there) I just don't understand conecpts whenever the examples are so terribly impractical (referring to the book I am using) Annoyed
3. All I still need to figure out (for now) is what the specific difference is (because I can't really understand what you originally said Sealfin.... haha) between [myFraction setNumerator: __] and numerator = __. Because they do the same thing.

What I THINK The answer is:

[myFraction setNumerator: __] applies that method to 'myFraction' (the object, Fraction is the class) and thus applies the it to the 'numerator', the ivar that I have set. And that means, that although it takes a few steps, it simply applies the integer to the numerator.

numerator = __ simply does one step to accomplish the same thing, apply the integer to the numerator.

I THINK ^ those are the answers to my own questions.

Again, I'm not an idiot as I seem to be right now, I just don't understand why my book does not explain this!

Also: AnotherJake pretty much answered my question above, just not exactly outright, and you seem to want to answer it too, so I'm asking again Rasp
Quote this message in a reply
Member
Posts: 34
Joined: 2010.01
Post: #19
easy_e Wrote:All I still need to figure out (for now) is what the specific difference is (because I can't really understand what you originally said Sealfin.... haha) between [myFraction setNumerator: __] and numerator = __. Because they do the same thing.

What I THINK The answer is:

[myFraction setNumerator: __] applies that method to 'myFraction' (the object, Fraction is the class) and thus applies the it to the 'numerator', the ivar that I have set. And that means, that although it takes a few steps, it simply applies the integer to the numerator.

numerator = __ simply does one step to accomplish the same thing, apply the integer to the numerator.

I THINK ^ those are the answers to my own questions.

Right. setNumerator: is just a method (a type of function) that modifies your instance variable (a piece of data). Or rather, setNumerator: is simply a method that sets the instance's numerator.

From the outside (say in main.m), there's no need to know how setNumerator: works. The ivar doesn't even have to be named "numerator", it could be named "stupidNumerator" and it still wouldn't matter to outside world - because you're still using the method setNumerator:

You wrap instance variables with accessor methods as a form of abstraction, and flexibility. You should try to only access an instance variable directly in the accessor methods, and use the accessor methods everywhere else, within the class (via self) or outside. (Here I disagree with AnotherJake a bit).

Say you wanted to change setDenominator: so that if the passed argument is 0, it will set the denominator to 1. You can easily do this like AnotherJake showed. Here we changed setDenominator: from "set the instance's denominator" to "set the instance's denominator, but if requested denominator is zero, we will set it to one." If you were just accessing the instance variable directly everywhere (denominator = ...), it would be painful to make this change.

I remember reading Kochan's book as my first source of learning programming too. Brings back good old days.
Quote this message in a reply
Member
Posts: 60
Joined: 2013.03
Post: #20
(Apr 6, 2013 11:02 AM)Zorg Wrote:  
easy_e Wrote:All I still need to figure out (for now) is what the specific difference is (because I can't really understand what you originally said Sealfin.... haha) between [myFraction setNumerator: __] and numerator = __. Because they do the same thing.

What I THINK The answer is:

[myFraction setNumerator: __] applies that method to 'myFraction' (the object, Fraction is the class) and thus applies the it to the 'numerator', the ivar that I have set. And that means, that although it takes a few steps, it simply applies the integer to the numerator.

numerator = __ simply does one step to accomplish the same thing, apply the integer to the numerator.

I THINK ^ those are the answers to my own questions.

Right. setNumerator: is just a method (a type of function) that modifies your instance variable (a piece of data). Or rather, setNumerator: is simply a method that sets the instance's numerator.

From the outside (say in main.m), there's no need to know how setNumerator: works. The ivar doesn't even have to be named "numerator", it could be named "stupidNumerator" and it still wouldn't matter to outside world - because you're still using the method setNumerator:

You wrap instance variables with accessor methods as a form of abstraction, and flexibility. You should try to only access an instance variable directly in the accessor methods, and use the accessor methods everywhere else, within the class (via self) or outside. (Here I disagree with AnotherJake a bit).

Say you wanted to change setDenominator: so that if the passed argument is 0, it will set the denominator to 1. You can easily do this like AnotherJake showed. Here we changed setDenominator: from "set the instance's denominator" to "set the instance's denominator, but if requested denominator is zero, we will set it to one." If you were just accessing the instance variable directly everywhere (denominator = ...), it would be painful to make this change.

I remember reading Kochan's book as my first source of learning programming too. Brings back good old days.

So the 'right' means I'm right? They are both accessors? If so, cool. I get it. Thanks for the clarification! Grin
Quote this message in a reply
Member
Posts: 34
Joined: 2010.01
Post: #21
Accessors (getters and setters) are methods that encapsulate access to instance variables.

You were confused about the difference between accessors, and instance variables.
Quote this message in a reply
Member
Posts: 60
Joined: 2013.03
Post: #22
(Apr 6, 2013 01:07 PM)Zorg Wrote:  Accessors (getters and setters) are methods that encapsulate access to instance variables.

You were confused about the difference between accessors, and instance variables.

I was? Ok... lol

(I'm confused with the difference between "[myFraction setNumerator: __]" and "numerator = __". Those are accessors and instance variables? Which? )

Again - I'm not stupid, it's just the book is not explaining.... Wacko
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #23
(Apr 6, 2013 01:45 PM)easy_e Wrote:  (I'm confused with the difference between "[myFraction setNumerator: __]" and "numerator = __". Those are accessors and instance variables? Which? )

"-(void)setNumerator:(int)" is an accessor (and a setter.)

"numerator" is an instance variable.

Additionally:

"[myFraction setNumerator: __]" is a statement sending the message "setNumerator: __" to the instance "myFraction".

"numerator = __" is an assignment statement.

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #24
[myFraction setNumerator: __] is a method call.

setNumerator is a method.

numerator is an instance variable.

In this case we can call setNumerator an accessor for numerator.

numerator = __ is how numerator is actually assigned a value within the setNumerator method (or anywhere else within the Fraction class). Remember what I said earlier, there is only one way to set a variable and that is with an assignment operator, such as "=". That is the ONLY way to assign a value to a variable.

Calling setNumerator is an *indirect* way of setting numerator because the assignment happens within setNumerator.
Quote this message in a reply
Member
Posts: 60
Joined: 2013.03
Post: #25
(Apr 6, 2013 02:26 PM)AnotherJake Wrote:  [myFraction setNumerator: __] is a method call.

setNumerator is a method.

numerator is an instance variable.

In this case we can call setNumerator an accessor for numerator.

numerator = __ is how numerator is actually assigned a value within the setNumerator method (or anywhere else within the Fraction class). Remember what I said earlier, there is only one way to set a variable and that is with an assignment operator, such as "=". That is the ONLY way to assign a value to a variable.

Calling setNumerator is an *indirect* way of setting numerator because the assignment happens within setNumerator.

Alright. Perfect. That is just what I needed. Thanks for the ultra-clarification!
Quote this message in a reply
Post Reply