630 likes | 863 Views
MORE on classes in …. Objective-C. OOP terminology in Objective-C. Class: defines the grouping of data and code type of entity Object or Instance: a specific instantiation of a class with its own state (class variables values) Method:
E N D
MORE on classes in ….. Objective-C
OOP terminology in Objective-C • Class: • defines the grouping of data and code • type of entity • Object or Instance: • a specific instantiation of a class with its own state (class variables values) • Method: • a “function/operator” that an object knows how to perform • Instance Variable: • this is what we call class variable in other OOP languages
Objective-C as an OOP lang • Strict superset of C • Mix C with ObjC • Or even C++ with ObjC (usually referred to as ObjC++) • A very simple language, but some new syntax • Single inheritance, classes inherit from one and only one superclass • Protocols define behavior that cross classes • Dynamic runtime • Loosely typed, if you’d like
More on Objective-C Syntax: What’s most confusing about Objective-C? • Most class names start with NS: NSString, NSObject • Parameter lists are not comma delimited and method names are interrupted by parameter names and types. • There are too many brackets and colons. :[ • Memory Management. • All these @ symbols confuse me. • Both C and Objective-C methods are allowed? Weird.
Objective-C Class Methods Instances/Objects respond to instance methods • - (id)init; • - (float)height; • - (void)walk; Classes respond to class methods • + (id)alloc; • + (id)person; • + (Person *)sharedPerson; [object walk] [ClassName person]
Intro to Objective-C Syntax: Method Signatures In Java or C: voiddoNothing() { // nothing } intaddThree(intx) { return x + 3; } intmultiplyThreeParameters(intx,inty,intz) { return x * y * z; } // note methods with multiple parameters are given in a parameter list // that is delimited by commas. Key return type method name parameter type parameter name
Intro to Objective-C Syntax: Method Signatures In Objective-C - (void) doNothing{ // nothing } - (int) addThree:(int) x { return x + 3; } - (int) multiplyThis:(int) xByThis:(int) yAndThis:(int) z { return x * y * z; } Key return type method name parameter type parameter name NOTE: methods of Objective-C classes with multiple parameters have a to delimit the end of the parameter name and the continuation of the method name. Actually method name is multiplyThis:ByThis:AndThis
Stop---that was weird---method name is change of the 3 - (int) multiplyThis:(int) xByThis:(int) yAndThis:(int) z { return x * y * z; } Method name is multiplyThis:ByThis:AndThis
Intro to Objective-C Syntax: Accessing methods of objects In Java:object.method(param1, param2); In C++:object->method(param1, param2); In C:(no objects) method(param1, param2); In Objective-C:[object method:param1method:param2]; Only a space between no comma
Intro to Objective-C Syntax: Accessing methods of objects In Objective-C:[object method:param1method:param2]; Example: If you have a string: NSString *msg= @"ALL YOUR BASES BELONG TO US"; And you want to split the sentence into an array of words: NSArray*words = [msgcomponentsSeparatedByString:@" "]; // The @ is required for all string literals, and encodes the string using UTF8
Intro to Objective-C Syntax: Instantiation / Memory Allocation In Java: Objecto = new Object(); // Java takes care of garbage collection. In this statement, memory // is automatically allocated for the new object. Memory is also // automatically released when the object is no longer in use. In C: Object*o = (Object *) malloc(sizeof(Object)); free (o); In C++: Object*o = new Object; delete (o);
Intro to Objective-C Syntax: Instantiation In Objective-C: Object*obj= [[Objectalloc] init];
Ways of creating objects • Asking other objects to create objects for you • NSString’s - (NSString *)stringByAppendingString:(NSString *)otherString; • NSString’s & NSArray’s - (id)mutableCopy; • NSArray’s - (NSString *)componentsJoinedByString:(NSString *)separator; • Not all objects handed out by other objects are newly created • NSArray’s - (id)lastObject; • NSArray’s - (id)objectAtIndex:(int)index; • Unless the method has the word “copy” in it, if the object already exists, you get a pointer to it. • If the object does not already exist (like the 3 examples above), then you’re creating. • Using class methods to create objects • NSString’s + (id)stringWithFormat:(NSString *)format, ... • UIButton’s + (id)buttonWithType:(UIButtonType)buttonType; • NSMutableArray’s + (id)arrayWithCapacity:(int)count; • NSArray’s + (id)arrayWithObject:(id)anObject;
Ways of creating objects –cont. • Allocating and initializing an object from scratch • Doing this is a two step process: allocation, then initialization. • Both steps must happen one right after the other (nested one inside the other, in fact). • Examples: • NSMutableArray *stack = [[NSMutableArray alloc] init]; • CalculatorBrain *brain = [[CalculatorBrain alloc] init]; • About Allocating • Heap allocation for a new object is done by the NSObject class method + (id)alloc • It allocates enough space for all the instance variables (e.g., the ones created by @synthesize). • About Initializing • Classes can have multiple, different initializers (with arguments) in addition to plain init. • If a class can’t be fully initialized by plain init, it is supposed to raise an exception in init. • NSObject’s only initializer is init.
Ways of creating objects –cont. • More complicated init methods • If an initialization method has arguments, it should still start with the four letters init • Example: - (id)initWithFrame:(CGRect)aRect; // initializer for UIView • UIView *myView = [[UIView alloc] initWithFrame:thePerfectFrame]; • Examples of multiple initializers with different arguments • From NSString: • - (id)initWithCharacters:(const unichar *)characters length:(int)length; • - (id)initWithFormat:(NSString *)format, ...; • - (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding; • Classes must designate an initializer for subclassers • This is the initializer that subclasses must use to initialize themselves in their designated initializer. • Static typing of initializers • For subclassing reasons, init methods should be typed to return id (not statically typed) • Callers should statically type though, e.g., MyObject *obj = [[MyObject alloc] init];
Creating you own init • Creating your own initialization method • Super initializer can return nil if it failed to initialize. • Example ---.m file @implementation MyObject - (id)init { self = [super init]; // call our super’s designated initializer if (self) { // initialize our subclass here } return self; } @end
Intro to Objective-C Syntax:Classes • In Java, students can define and implement a class in a single .java file. • In C++, students define a class and methods in a .h header file and implement the methods in a .c file. • In Objective-C, students define a class and its methods in a .h header file and implement the methods in a .m file. Circle.h Circle.m include
Intro to Objective-C Syntax:Classes Circle.h @interface Circle : NSObject{ // instance variables doubleradius = 1.0; } // Class methods +(double) getPi; // Instance methods -(double) getArea; -(void) setRadius:(double) r; @end Key class name superclass return type method name parameter type parameter name Optional parameter name
Circle.m #import "Circle.h" @implementation Circle +(double) getPi { return 3.14159265; } -(double) getArea { double pi = [Circle getPi]; return pi * radius * radius; } -(void) setRadius:(double) r { radius = r; } @end
Main.m #import "Circle.h" // Non Objective-C function; program origin int main() { @autoreleasepool { Circle *mycirc = [[Circle alloc] init]; [mycirc setRadius:3.0]; double area = [mycirc getArea]; double pi = [Circle getPi]; return 0; } }
Classes --- remember • Have both definition file and implementation file : classname.h and classname.m
Prototyping methods • When declaring or implementing functions for a class, they must begin with a + or - • + indicates a “class method” that can only be used by the class itself. In other words, they’re for private functions ---like static functions in other languages. • - indicates “instance methods” to be used by the client program (public functions) –invoked on objects/instance of class
Class Declaration (Interface) #import <Cocoa/Cocoa.h> @interface Node : NSObject { Node *link; int contents; } +(id)new; -(void)setContent:(int)number; -(void)setLink:(Node*)next; -(int)getContent; -(Node*)getLink; @end node.h Class is Node who’s parent is NSObject { class variables } +/- private/public methods of Class Class variables are private
Class Definition (Implementation) #import "node.h” @implementation Node +(id)new { return [Node alloc];} -(void)setContent:(int)number {contents = number;} -(void)setLink:(Node*)next { [link autorelease]; link = [next retain]; } -(int)getContent {return contents;} -(Node*)getLink {return link;} @end node.m Like your C++ .cpp file >>just give the methods here
Creating class instances ClassName *object = [[ClassName alloc] init]; OR ClassName *object= [[ClassName alloc] initWith*];
Destroying a class Like NULL in C ++ Like null in Java object = nil; The underlying system will take care of removing the object from memory for you automatically. Note: a lot of programs don’t explicitly set objects to nil but, is an option for you.
Do you need to test for nill if (object == nill) //or if (object) { //do whatever } Actually, in Objective-C if an objects is nil and you send a message (method call) to it does nothing….however, if you are expecting results and try to use them you could get in trouble –so checking in this case is important.
Setting values for class variables of an object ---- THROUGH methods ClassName *object = [[ClassName alloc] init]; [object setXXXMethod:value1]; [object setYYYYMethod:value2];
Two kinds of methods – calss and instance methods • Class Method call is like a STATIC method – call on the class itself • Example for class NSDate –has class method “date” that will return pointer to an instance of NSDate associated with current dateNSDate *now = [NSDate date]; • Instance method is like normal function – call on an object • Example for class NSDate –has instance method “timeIntervalSince1970 ” that will return seconds of the date object since 1970double seconds = [now timeIntervalSince1970];
Method calls uses “Message syntax” • [receiver message] • [receiver message:argument] • [receiver message:arg1 andArg:arg2] • Example of a Class method to construct and new object NSDate *now = [NSDate date];
More Terminology • Message expression • [receiver method: argument] • Message • [receiver method: argument] • Selector • [receiver method: argument] • Method • The code selected by a message
Message/Method call with multiple arguments [ Object methodp1:v1 methodp2:v2 methodp3:v3] What is the actual method name? It is (yes it is odd!) methodp1:methodp2:methodp3 Example NSCalendar *cal = [NSCalendar currentCalendar]; NSUInteger day = [cal ordinalityOfUnit:NSDayCalendarUnit forDate:now]; What is the name of the method ? It is ordinalityOfUnit:forDate
Nesting Method call [[ Object method1] method 2] method 1 executed first and on the results method 2 is executed Example without nesting NSCalendar *cal = [NSCalendar currentCalendar]; NSUInteger day = [cal ordinalityOfUnit:NSDayCalendarUnit forDate:now]; Example WITH nestingNSUInteger day = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit forDate:now]
Some arbitrary examples Person *voter; //assume this exists [voter castBallot]; inttheAge = [voter age]; [voter setAge:21]; if ([voter canLegallyVote]) { // do something voter-y } [voter registerForState:@"CA“ party:@"Independant"]; NSString *name = [[voter spouse] name];
Accessor Methods • Two kinds: setter methods and getter methods -- used to set and get instance variables. Example Person.h @interface Person : NSObject{ //two instance variables float heightInMeters;intweightInKilos;} - (void)setHeightInMeters:(float)h; //setter instance method - (void)setWeightInKilos:(int)w; //setter instance method - (void)weightInKilos; //getter instance method - (void)heightInMeters; //getter insance method - (float) bodyMassIndex; //instance method @end NOTE: the convention of naming the setter methods as setVariableName NOTE: the convention of naming the getter methods same as the variable they access
Accessor Methods Example Person.m @implementation Person - (float) heightInMeters { return heightInMeters; } - (int) weightInKilos { return weightInKilos; } - (void) setHeightInMeters:(float)h { heightInMeters = h; } - (void) setWeightInKilos:(int)w { weightInKilos = w;} - (float) bodyMassIndex { return weightInKilos / (heightInMeters * heightInMeters); } @end
Lets use our Accessor Methods Example main.m Int main(int argc, const char * argv[]) { @autoreleasepool { //Create an instance of Person Person *person = [[Person alloc] init]; //Give instance variables some values [person setWeightInKilos:96]; [person setHeightInMeters:1.8]; //Call bodyMassIndex method float bmi = [person bodyMassIndex]; //print out NSLog(@”person (%d, %f) has a BMI of %f”, [person weightInKilos], [person heightInMeters], bmi); NOTE: %f mean insert float value, %d is an integer value --- same as you see in printf for C
Properties --simple way to create accessor methods • Declare in one line the getter and setter methods for a variable Example -- newPerson.h @interface Person : NSObject{ //two instance variables float heightInMeters; int weightInKilos;} @property float heightInMeters; //will create setter and getter method for this var @property float weightInKilos; //will create setter and getter method for this var - (float) bodyMassIndex; //instance method @end In Person.h add @property
Properties --just have the @property • Declare in one line the getter and setter methods for a variable Example -- newPerson.h @interface Person : NSObject{ //don’t need to declare the variables here // ---they are done with @property} @property float heightInMeters; //will create setter and getter method for this var @property float weightInKilos; //will create setter and getter method for this var - (float) bodyMassIndex; //instance method @end
Properties --continued • Use @synthisize annotation newPerson.m #import “Person.h” @implementation Person @synthesize heightInMeters, weightInKilos; - (float) bodyMassIndex { return weightInKilos / (heightInMeters * heightInMeters); } Now in .m file must add @synthesize annotation Do not need to create the methods
Properties can take paramenters • @property (a1,a2,*) var Example @property (nonatomic, readonly, strong) NSString *itemName; • nonatomic / atomic = dealing with threading • nonatomic = (YOU USE THIS FOR IOS), not thread-safe • NOTE: no problem if this is UI code because all UI code happens on the main thread of the application. • atomic = (don’t do this for iOS), thread safe, default • readwrite/readonly • readwrite= default value, declares both a setter and a getter. • readonly =means only create setter method. • weak/strong/assign = dealing with memory management • strong= strong reference to object stored in variable –see ARC • weak = weak reference to object stored in variable –see ARC • assign = default for variables that are primitive data types
Keyword --self • self is like “this” in other OOP languages //some code inside a method of a class float h = [self heightInMeters]; //method calss to getter for the variable heightInMeters //another example a method in a class that adds itself (object) to an array that is passed -(void) addYourselfToArrayNSMutableArray *) theArray { [theArray addObject:self]; }
Inheritence • In .h file @interface ClassName : ParentClass { //class variables } //methods @end
Example of Inheritance • Create class Employee that has Person as parent and adds class variable of an employee id Employee.h file #import “Person.h” @interface Employee : Person { intemployeeID; } @property intemployeeID; //remember short cut to declare accessor methods // for employeeID class variable @end
Child class • Can access Parent’s methods and variables • Overriding methods //Employee .m file //override the #import “Employee.h” @implementation Employee @synthesize employeeID; //remember this genearteds the setemployeeID() and employeeID() methods - (float) bodyMassIndex //overridden method of previous Person parent class { return 19.0; } @end • super = keyword to mean parent class - (float) bodyMassIndex //overridden method of previous Person parent class { float normalBMI = [super bodyMassIndex] ; //first call Person’s bodyMassIndex method return normalBMI*0.9; }
Instance variables typically in one of 4 categories • Primitive data types • int age; • float number; • Object-type attributes • NSStringmyName; • NSNumber • To-one relationship = point to a single “complex” object • Employee top_Employee; • Person spouse; • To-many relationships = these are collections (objects or data) • NSMutableArray *friends; • NSArray *emails;
Class Example with some different “kinds” of instance vars Employee.h #import “Person.h” @interface Employee : Person { intemployeeID; //primitive data NSString *lastName; //object type Person *spouse; //To-one more complex object NSMutableArray *children; //To-many collections } //method declarations ***** @end IMPORTANT Have you noticed that objectinstance variables are always Pointers to objects.
STOP: huh? Variables are always pointers to Objects • Objects don’t live inside other objects. • You only points from one object to another • MePerson -> spouse (another Person) • Result: you end up with a lot of distinct objects in your program’s memory • Luckily we have Automatic Reference Counting for our iOS programs to take care of memory leaking and getting rid of no longer needed objects!!! Yes!