方法代表一个行为,一个对象知道,怎样执行这个方法。他是属性的同伴,属性是保存对象数据的。您可以认为方法是一个依附于对象的参数;然而他们的语法是不一样的。
这章我们将学习Object-C的方面命名规约,这个可能让有Java和C++的您感觉很不舒服。
Naming Conventions 命名规约
为了保证方法无二义性,Object-C的方法名比较的长,但是比较描述性。命名方法需要遵守下面这三条建议。
Don’t abbreviate anything.// 不要有缩写
Explicitly state parameter names in the method itself. // 在方法中清楚声明参数的名字。
Explicitly describe the return value of the method. // 清楚的描述方法的返回值。
记住以上的规则,当您阅读下面的代码时:
// Car.h
#import <Foundation/Foundation.h>
@interface Car : NSObject
// Accessors
- (BOOL)isRunning;
- (void)setRunning:(BOOL)running;
- (NSString *)model;
- (void)setModel:(NSString *)model;
// Calculated values
- (double)maximumSpeed;
- (double)maximumSpeedUsingLocale:(NSLocale *)locale;
// Action methods
- (void)startEngine;
- (void)driveForDistance:(double)theDistance;
- (void)driveFromOrigin:(id)theOrigin toDestination:(id)theDestination;
- (void)turnByAngle:(double)theAngle;
- (void)turnToAngle:(double)theAngle;
// Error handling methods
- (BOOL)loadPassenger:(id)aPassenger error:(NSError **)error;
// Constructor methods
- (id)initWithModel:(NSString *)aModel;
- (id)initWithModel:(NSString *)aModel mileage:(double)theMileage;
// Comparison methods
- (BOOL)isEqualToCar:(Car *)anotherCar;
- (Car *)fasterCar:(Car *)anotherCar;
- (Car *)slowerCar:(Car *)anotherCar;
// Factory methods
+ (Car *)car;
+ (Car *)carWithModel:(NSString *)aModel;
+ (Car *)carWithModel:(NSString *)aModel mileage:(double)theMileage;
// Singleton methods
+ (Car *)sharedCar;
@end
Abbreviations 缩写
不使用缩写是增加代码可读性的最简单的方法。这也就是为什么,上面的方法使用了maximumSpeed而不是maxSpeed。
Parameters 参数
关于Object-C 冗余设计哲学最明显的例子就是方法参数命名。C++和Java 将方法名作为一个单独的实体和参数分开,但是Object-C的方法名包括了所有参数名。
例如,使Car转90度,您将可能调用,turn(90),但是Object-C中发现这样是由二义性的。这样不清楚的,什么参数应该传入,即这个有可能是一个方位,也可能是一个角度。Object-C通过一个前置的词描述这个参数,使这个参数的意义更加清楚。最终的api应该保证,不应该被误解,到底是turnByAngle:90或者是turnToAngle:90。
当一个方法接受多个参数,每个参数名包括在方法名中。例如上面的nitWithModel:mileage: 清楚的标示了,参数model和mileage 参数。这样在方法调用,和代码阅读中提供了大量的信息。
Return Values 返回值
每个方法都清楚申明返回值的类型。
Calling Methods 调用方法
和实例化和用法章节所讲一样,是通过将对象和想调用的方法放在一个方括号中,中间用空格分开,完成调用方法的。参数和方法名之间使用冒号隔开,
[porsche initWithModel:@"Porsche"];
当您有多个参数,一个更随一个。每个参数和一个参数名成对出现,多个参数之间使用空格隔开。
[porsche initWithModel:@"Porsche" mileage:42000.0];
从调用者的角度,很容易从上面的命名中知道,调用者的目的。这样使方法调用,更能表达,方法调用的目的。一目了然。下面是Object-C的方法调用和Simula风格的方法调用。
// Python/Java/C++
porsche.drive("Home", "Airport");
// Objective-C
[porsche driveFromOrigin:@"Home" toDestination:@"Airport"];
这样的书写方法的方式,更利于代码的阅读。当一段时间之后,只要您一看方法的名字和参数,就知道这个方法的作用。其他的框架也遵守这样的规约。
Nested Method Calls 方法的嵌套调用
嵌套方法调用在Object-C 是一种常见的编程模式。传递一个方法调用的返回值给另一个方式是很自然的,概念上,它和方法链是一样的,但是方括号的语法让这样方式看起来有点不一样。
// JavaScript
Car.alloc().init()
// Objective-C
[[Car alloc] init];
首先, [Car alloc] 先执行,init方法是在上一个方法调用的返回值上调用的。
Protected and Private Methods
在Object-C中每个保护类型和私有类型的方法标示符。
在.m方法定义和实现的方法就是私有方法。
协议是定义保护方法的方式。