클래스 정의하기
Objective-C에서는 클래스를 인터페이스와 구현부로 분리해서 작성한다.
헤더파일에는 클래스의 인터페이스를 작성하여 외부에서 클래스의 프로퍼티나 메서드 등에 접근할 수 있게 한다.
Xcode에서 코코아 터치 클래스를 생성하면 자동으로 헤더파일과 구현파일이 분리되어 추가되는 것을 확인할 수 있다.
예를 들어, MyRect라는 클래스의 헤더를 작성한다면 아래와 같이 작성할 수 있다.
인터페이스
//MyRect.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyRect : NSObject {
int width;
int height;
}
-(instancetype)initWithWidth:(int)w
height:(int)h;
-(int)getSquare;
-(void)setWidth:(int)w;
-(void)setHeight:(int)h;
@end
NS_ASSUME_NONNULL_END
클래스명은 대문자로 시작하는 카멜케이스로 쓰는 것이 Objective-C의 일반적인 컨벤션이다.
인스턴스명은 소문자로 시작하는 카멜케이스로 작성하면 된다.
MyRect라는 클래스의 인터페이스를 작성하기 위해서는 @interface라고 쓰고 어떤 클래스를 상속 받는 클래스인지 써야 한다.
이전 포스팅에서 언급했듯이 Objective-C에서는 모든 클래스가 NSObject에서 파생된 클래스로 작성이 되어야 한다.
다음 중괄호 블럭에서 width와 height라는 정수형 멤버 변수를 선언했다.
이는 인스턴스 변수라고 부르며, 각각의 인스턴스 마다 가지게 되는 변수이다.
일반적으로는 인스턴스 변수보다는 프로퍼티를 자주 사용하게 되는데, 이것은 나중에 따로 정리할 계획이다.
프로퍼티를 사용하지 않고 인스턴스 변수를 사용하기 위해서는 별도의 getter와 setter를 구현해주는 것이 필요하다.
아래에 1개의 생성자와 3개의 메서드가 선언되어 있다.
메서드의 가장 앞단에 오는 '-'는 이 메서드가 인스턴스 메서드임을 알린다.
만약 '+'로 시작하게 된다면 해당 메서드는 클래스 자체가 가지는 클래스 메서드이다.
swift에서 static 메서드와 유사하다고 보면 된다.
메서드명의 좌측의 타입은 반환 타입이다.
즉, getSquare의 반환 타입은 int형이다.
메서드명의 우측에는 매개변수가 있는 경우에 어떤 매개변수가 있는지 순서대로 나열되어 있다.
@end 키워드를 통해 인터페이스 작성이 끝났음을 표시한다.
NS_ASSUME_NONNULL 매크로는 해당 구문 안에 nil이 아님을 보장한다는 뜻이다.
해당 구문 내에서 nil을 사용할 수 없는 것은 아니지만 코드의 혼란을 줄이기 위해 nil을 쓰지 않는 것이 좋다.
구현
//MyRect.m
#import "MyRect.h"
@implementation MyRect
-(instancetype)initWithWidth:(int)w
height:(int)h{
self = [super init];
if (self) {
width = w;
height = h;
return self;
}
return self;
}
-(int)getSquare{
return width * height;
}
-(void)setWidth:(int)w{
width = w;
}
-(void)setHeight:(int)h{
height = h;
}
@end
구현 파일에서는 클래스의 실제 구현부를 작성한다.
구현부의 시작은 @implementation 으로 시작하고 @end로 끝난다.
헤더에서 선언한 메서드는 반드시 구현부에서 구현이 되어야 한다.
반대로 구현부에서 작성된 모든 메서드가 반드시 헤더 파일에 명시될 필요는 없다.
결론적으로 클래스 외부에서 사용되지 않고 노출되지 않아도 되는 메서드는 헤더에 작성하지 않는 것이 맞다.
개인적인 공부를 위해 작성한 내용이므로 틀린 내용이나 수정이 필요한 부분이 있을 수 있으니 감안하고 봐주시면 감사하겠습니다.
'Objective-C' 카테고리의 다른 글
[Objective-C] Objective-C의 특성 (0) | 2023.12.16 |
---|