Fraction.h
// // Fraction.h // FractionTest // // Created by lgt on 15/7/2. // Copyright (c) 2015年 lgt. All rights reserved. // #import <Foundation/Foundation.h> @interface Fraction : NSObject -(void) print; -(void) setNumerator: (int) n; -(void) setDenominator: (int) d; -(int) numerator; -(int) denominator; -(double) convertToNum; @end
Fraction.m
// // Fraction.m // FractionTest // // Created by lgt on 15/7/2. // Copyright (c) 2015年 lgt. All rights reserved. // #import "Fraction.h" @implementation Fraction { int numerator; int denominator; } -(void) print { NSLog(@"%i/%i", numerator, denominator); } -(void) setNumerator:(int)n { numerator = n; } -(void) setDenominator:(int)d { denominator = d; } -(int) numerator { return numerator; } -(int) denominator { return denominator; } -(double) convertToNum { if (denominator != 0) { return (double) numerator / denominator; } else { return NAN; } } @end
#import "Fraction.h" int main(int argc, char *argv[]) { @autoreleasepool { Fraction *myFraction = [[Fraction alloc] init]; [myFraction setNumerator:1]; [myFraction setDenominator:3]; NSLog(@"The value of myFraction is:"); [myFraction print]; } }
2015-07-02 18:32:00.514 FractionTest[9121:881411] The value of myFraction is: 2015-07-02 18:32:00.515 FractionTest[9121:881411] 1/3
As of Objective-C 2.0, we can have our setter and getter methods automatically generated for me.
the first step is to use the @property directive in our interface section to identify our properties.These properties are often named the same as our instance variables, although they don't have to be.
@interface Fraction : NSObject @property int numerator, denominator; -(void) print; -(double) convertToNum; @end
#import "Fraction.h" @implementation Fraction @synthesize numerator, denominator; -(void) print { NSLog(@"%i/%i", numerator, denominator); } -(double) convertToNum { if (denominator != 0) { return (double) numerator / denominator; } else { return NAN; } } @end
@synthesize numerator, denominator;
@synthesize x
After we use:
@property int numerator, denominator;
myFraction.numerator = 1;
[myFraction setNumerator:1];
myFraction.numerator
[myFraction numerator]
#import "Fraction.h" int main(int argc, char *argv[]) { @autoreleasepool { Fraction *myFraction = [[Fraction alloc] init]; myFraction.numerator = 1; myFraction.denominator = 3; //[myFraction setNumerator:1]; //[myFraction setDenominator:3]; NSLog(@"The value of myFraction is:%i/%i", myFraction.numerator, myFraction.denominator); } }
we could write the code to make multiple arguments to methods:
-(void) setTo: (int) n over: (int) d;
-(void) setTo:(int)n over:(int)d { numerator = n; denominator = d; }
when we want to invoke a method in the same class, how could we do? we could use self:
@interface ClassA : NSObject -(void) print; -(void) invokePrint; @end @implementation ClassA -(void) print { NSLog(@"hello world"); } -(void) invokePrint { [self print]; } @end int main(int argc, char *argv[]) { @autoreleasepool { ClassA *a = [[ClassA alloc] init]; [a invokePrint]; } }the output is:
2015-07-02 19:08:48.319 FractionTest[9224:889966] hello world
when we write the code:
@interface Fraction : NSObject @end
whenever a new class(other than a new root class) is defined, the class inherits certain things. For example, the(nonprivate) instance variables and the methods from the parent implicitly become part of the new class definition. That means the subclass can access these methods and instance variables, as if they were defined directly within the class definition.
Note that the instance variables that are to be accessed directly by a subclass must be declared in the interface section.Instance variables declared or synthesized in the implementation section are private instance variables and are not directly accessible by subclasses. Instead, you want to use their explicitly defined or synthesized getter and setter methods to access their values.
example 1: the public variable is inherit
@interface ClassA : NSObject { int x; } -(void) initVar; @end @implementation ClassA -(void) initVar { x = 100; } @end @interface ClassB : ClassA -(void) printVar; @end @implementation ClassB -(void) printVar { NSLog(@"x = %i", x); } @end int main(int argc, char *argv[]) { @autoreleasepool { ClassB *b = [[ClassB alloc] init]; [b initVar]; [b printVar]; } }
2015-07-02 20:36:11.951 FractionTest[9306:899284] x = 100
@interface ClassA : NSObject @property int x; @end @implementation ClassA @synthesize x; @end @interface ClassB : ClassA -(void) printVar; @end @implementation ClassB -(void) printVar { //NSLog(@"x = %i", x); NSLog(@"x = %i", [self x]); } @end int main(int argc, char *argv[]) { @autoreleasepool { ClassB *b = [[ClassB alloc] init]; b.x = 100; [b printVar]; } }
NSLog(@"x = %i", x);
now we define XYPoint class:
#import <Foundation/Foundation.h> @interface XYPoint : NSObject @property int x, y; -(void) setX: (int) xVal andY: (int) yVal; @end
@interface Fraction : NSObject @property int numerator, denominator; -(XYPoint *) origin; -(void) print; -(double) convertToNum; -(void) setTo: (int) n over: (int) d; @end
@class XYPoint;
#import "XYPoint.h"
XYPoint.h
#import <Foundation/Foundation.h> @interface XYPoint : NSObject @property int x, y; -(void) setX: (int) xVal andY: (int) yVal; @end
#import "XYPoint.h" @implementation XYPoint @synthesize x, y; -(void) setX:(int)xVal andY:(int)yVal { x = xVal; y = yVal; } @end
#import <Foundation/Foundation.h> @class XYPoint; @interface Rectangle : NSObject @property int width, height; -(XYPoint *) origin; -(void) setOrigin: (XYPoint *) pt; -(void) setWidth: (int) w andHeight: (int) h; -(int) area; -(int) perimeter; @end
#import "Rectangle.h" @implementation Rectangle { XYPoint *origin; } @synthesize width, height; -(void) setWidth:(int)w andHeight:(int)h { width = w; height = h; } -(void) setOrigin:(XYPoint *)pt { origin = pt; } -(int) area { return width * height; } -(int) perimeter { return (width + height) * 2; } -(XYPoint *) origin { return origin; } @end
#import "Rectangle.h" #import "XYPoint.h" int main(int argc, char *argv[]) { @autoreleasepool { Rectangle *myRect = [[Rectangle alloc] init]; XYPoint *myPoint = [[XYPoint alloc] init]; [myPoint setX:100 andY:200]; [myRect setWidth:5 andHeight:8]; myRect.origin = myPoint; NSLog(@"Origin at (%i, %i)", myRect.origin.x, myRect.origin.y); [myPoint setX:50 andY:50]; NSLog(@"Origin at (%i, %i)", myRect.origin.x, myRect.origin.y); } }
2015-07-02 21:46:04.271 FractionTest[9415:909226] Origin at (100, 200) 2015-07-02 21:46:04.272 FractionTest[9415:909226] Origin at (50, 50)
then we look the code:
-(void) setOrigin:(XYPoint *)pt { origin = pt; }
Polymorphism enables programs to be developed so that objects from different classes can define methods that share the same name. Dynamic typing defers the determination of the class that an object belongs to until the program is executing. Dynamic binding defers the determination of the actual method to invoke on an object until program execution time.
just think that we define class ClassA and ClassB, each class define the print method.so when we write the code:
ClassA *a = [[ClassA alloc] init]; ... [a print]
It's simple: The Objective-C runtime knows that a is a ClassA object, so it select the ClassA.print method.
id can be used for storing objects that belong to any class. The real power of this data type is exploited when it's used this way to store different types of objects in a variable during the execution of a program.
the example code:
#import "Rectangle.h" #import "XYPoint.h" int main(int argc, char *argv[]) { @autoreleasepool { id dataValue; Rectangle *myRect = [[Rectangle alloc] init]; XYPoint *myPoint = [[XYPoint alloc] init]; dataValue = myRect; [dataValue print]; dataValue = myPoint; [dataValue print]; } }
Because the type of object stored inside an id variable can be indeterminate at compile time, some tests are deferred until runtime--that is, while the program is executing.
Consider the following sequence of code:
Fraction *f1 = [[Fraction alloc] init]; [f1 setReal: 10.0 andImaginary: 2.5];
/Users/lgt/Desktop/FractionTest/main.m:20:13: No visible @interface for 'Fraction' declares the selector 'setReal:andImaginary:'
id f1 = [[Fraction alloc] init]; [f1 setX: 10.0 andY: 2.5];