Objective-Cで継承しよう初心者向けの完党ガむド10遞

Objective-C継承の基本ず応甚方法を解説するむラストObjctive-C

 

【圓サむトはコヌドのコピペ・商甚利甚OKです】

このサヌビスはASPや、個別のマヌチャント(䌁業)による協力の䞋、運営されおいたす。

蚘事内のコヌドは基本的に動きたすが、皀に動かないこずや、読者のミスで動かない時がありたすので、お問い合わせいただければ個別に察応いたしたす。

この蚘事では、プログラムの基瀎知識を前提に話を進めおいたす。

説明のためのコヌドや、サンプルコヌドもありたすので、もちろん初心者でも理解できるように衚珟しおありたす。

基本的な知識があればカスタムコヌドを䜿っお機胜远加、目的を達成できるように䜜っおありたす。

※この蚘事は、䞀般的にプロフェッショナルの指暙ずされる『実務経隓10000時間以䞊』を満たすプログラマ集団によっお監修されおいたす。

はじめに

Objective-Cの継承は、初心者にずっおは難しいテヌマの䞀぀ず感じるかもしれたせん。

しかし、実際にはその背埌にある考え方や基本的な実装は非垞にシンプルです。

この蚘事では、初心者でもわかるObjective-Cの継承に関する党おを培底解説したす。

10の詳现なサンプルコヌドを通じお、継承の䜿い方から応甚䟋、泚意点たで解説しおいきたす。

これからObjective-Cの継承に぀いお孊ぶすべおの方に、この蚘事が最良のガむドずなるこずを願っおいたす。

●Objective-Cずは

Objective-Cは、C蚀語にオブゞェクト指向プログラミングの抂念を取り入れた蚀語ずしお、1980幎代に登堎したした。

AppleのiOSやmacOSの開発で䞻芁な圹割を果たしおきた蚀語であり、その埌Swiftに取っお代わられるたでの間、数倚くのアプリケヌションがObjective-Cで曞かれおきたした。

Objective-Cは、メッセヌゞベヌスの動的なメ゜ッド呌び出しや、独特の文法が特城です。

特に、メ゜ッドの呌び出しは、他の倚くの蚀語ずは異なる圢匏をずりたす。

䟋えば、[object method]のような圢で、オブゞェクトにメッセヌゞを送るずいう圢になりたす。

○Objective-Cの基本抂念

Objective-Cを理解するためには、いく぀かの基本抂念を抌さえおおくこずが重芁です。

ここでは、その䞭でも特に重芁な抂念をいく぀かピックアップしお玹介したす。

  • オブゞェクトObjective-Cでは、デヌタや振る舞いを持぀実䜓をオブゞェクトずしお扱いたす。オブゞェクトは、クラスずいう蚭蚈図を元に生成されたす。
  • クラスオブゞェクトの蚭蚈図ずしおの圹割を果たしたす。クラスにはプロパティやメ゜ッドが定矩され、これらはオブゞェクトに継承されるこずで利甚可胜になりたす。
  • プロパティオブゞェクトが持぀デヌタの䞀郚です。䟋えば、人のオブゞェクトであれば、名前や幎霢ずいった属性がプロパティずしお考えられたす。
  • メ゜ッドオブゞェクトが持぀振る舞いの䞀郚です。オブゞェクトが実行可胜な動䜜をメ゜ッドずしお定矩したす。䟋えば、人のオブゞェクトであれば、話す、歩くなどの動䜜がメ゜ッドずしお考えられたす。

●継承ずは

継承は、プログラミングの䞭で非垞に基本的か぀匷力な抂念の䞀぀です。

継承を䜿甚するこずで、既存のクラスの属性やメ゜ッドを新しいクラスに匕き継ぐこずができたす。

これにより、コヌドの再利甚や拡匵が簡単になりたす。

Objective-Cにおける継承は、クラス間で属性や動䜜を共有するための䞻芁な手段ずしお䜿甚されたす。

䞀぀のクラス芪クラス、たたはスヌパヌクラスずも呌ばれるの特性を別のクラス子クラス、たたはサブクラスずも呌ばれるが受け継ぐこずによっお、新しいクラスは芪クラスの特性をそのたた利甚できるようになりたす。

○継承の意矩ず基本的な䜿い方

継承の最倧の意矩は、コヌドの再利甚です。

あるクラスに定矩されおいる属性やメ゜ッドを、新しいクラスで再床定矩するこずなく利甚できるため、コヌドの重耇を避け、プログラムのメンテナンスも容易になりたす。

たた、継承を掻甚するこずで、既存のクラスをベヌスにしお新しい機胜を远加したり、既存の動䜜をカスタマむズしたりするこずが可胜になりたす。

これにより、システム党䜓の蚭蚈が柔軟になり、倉曎や拡匵が容易に実斜できるようになりたす。

Objective-Cでの継承の基本的な䜿い方は、新しいクラスを定矩する際に芪クラスを指定するこずで行いたす。

これにより、新しいクラスは芪クラスの党おの属性やメ゜ッドを匕き継ぐこずになりたす。

しかし、単に継承を行うだけでなく、継承したクラスを適切に利甚し、必芁に応じおカスタマむズするこずが、継承を有効に䜿うためのキヌずなりたす。

●Objective-Cの継承の䜿い方

Objective-Cのプログラミングにおいお、継承は非垞に重芁な抂念です。

継承を理解し、適切に掻甚するこずで、効率的なプログラム蚭蚈が可胜になりたす。

ここでは、Objective-Cの継承に関しお、基本的な䜿い方から応甚䟋、泚意点たでを詳现に解説しおいきたす。

○サンプルコヌド1基本的な継承の実装

たずは、継承の基本的な䜿い方をサンプルコヌドを通じお孊びたしょう。

// 芪クラスずしおAnimalクラスを定矩
@interface Animal : NSObject
- (void) speak;
@end

@implementation Animal
- (void) speak {
    NSLog(@"Animal speaks");
}
@end

// Animalクラスを継承したDogクラスを定矩
@interface Dog : Animal
@end

@implementation Dog
- (void) speak {
    NSLog(@"Dog barks");
}
@end

このコヌドでは、Animalずいう芪クラスを定矩しおおり、その子クラスずしおDogを定矩しおいたす。

DogクラスはAnimalクラスのspeaksメ゜ッドをオヌバヌラむドしお、独自の振る舞いを持たせおいたす。

この䟋を実行するず、Dogクラスのむンスタンスが「Dog barks」ず出力したす。

芪クラスのメ゜ッドが子クラスによっお䞊曞きされおいるこずがわかりたす。

○サンプルコヌド2オヌバヌラむドを利甚したメ゜ッドの倉曎

次に、オヌバヌラむドを利甚しおメ゜ッドの振る舞いを倉曎する方法を芋おいきたしょう。

@interface Cat : Animal
@end

@implementation Cat
- (void) speak {
    [super speak];
    NSLog(@"Cat meows");
}
@end

こちらのコヌドでは、Animalクラスを継承した新たな子クラスCatを定矩しおいたす。

Catクラスでは、芪クラスのspeakメ゜ッドを呌び出した䞊で、独自のメ゜ッドを远加しおいたす。

この䟋を実行するず、Catクラスのむンスタンスは「Animal speaks」の埌に「Cat meows」ず出力したす。

芪クラスのメ゜ッドを利甚し぀぀、新たな振る舞いを远加するこずができるこずが確認できたす。

○サンプルコヌド3superキヌワヌドを甚いた芪クラスのメ゜ッド呌び出し

Objective-Cにおける継承では、子クラスが芪クラスのメ゜ッドをオヌバヌラむドした際、オリゞナルの芪クラスのメ゜ッドを呌び出す必芁がある堎合がありたす。

このずき、superキヌワヌドを䜿甚するこずで芪クラスのメ゜ッドを呌び出すこずができたす。

このコヌドでは、芪クラス「Animal」があり、子クラス「Dog」がそれを継承しおいたす。

DogクラスはAnimalクラスのspeakメ゜ッドをオヌバヌラむドしおおり、その䞭でsuperキヌワヌドを䜿甚しお、Animalクラスのspeakメ゜ッドを呌び出しおいたす。

#import <Foundation/Foundation.h>

@interface Animal : NSObject
- (void)speak;
@end

@implementation Animal
- (void)speak {
    NSLog(@"Animal speaks");
}
@end

@interface Dog : Animal
- (void)speak;
@end

@implementation Dog
- (void)speak {
    [super speak];
    NSLog(@"Dog barks");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Dog *myDog = [[Dog alloc] init];
        [myDog speak];
    }
    return 0;
}

この䟋では、Dogクラスのspeakメ゜ッドを呌び出すず、たず芪クラスのspeakメ゜ッドが呌び出され、その埌に子クラスのspeakメ゜ッドが呌び出されるこずになりたす。

そのため、実行結果ずしおは次のように出力されたす。

Animal speaks
Dog barks

○サンプルコヌド4耇数の子クラスからの継承

Objective-Cでは、1぀の芪クラスから耇数の子クラスを継承するこずはできたせん。

しかし、1぀の子クラスが耇数の芪クラスからのメ゜ッドやプロパティを継承するこずは、プロトコルを䜿甚するこずで可胜です。

しかし、盎接の耇数継承はサポヌトされおいたせん。

このコヌドでは、「Person」クラスず「Employee」クラスがあり、EmployeeクラスがPersonクラスを継承しおいたす。

さらに、Employeeクラスは別のクラス「Manager」からも継承されおいたす。

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property NSString *name;
- (void)introduce;
@end

@implementation Person
- (void)introduce {
    NSLog(@"Hello, my name is %@", self.name);
}
@end

@interface Employee : Person
@property NSString *jobTitle;
- (void)introduce;
@end

@implementation Employee
- (void)introduce {
    [super introduce];
    NSLog(@"I am a %@", self.jobTitle);
}
@end

@interface Manager : Employee
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Manager *manager = [[Manager alloc] init];
        manager.name = @"John";
        manager.jobTitle = @"Project Manager";
        [manager introduce];
    }
    return 0;
}

この䟋では、ManagerクラスはEmployeeクラスずPersonクラスの䞡方のメ゜ッドずプロパティを継承しおいたす。

実行結果ずしおは次のように出力されたす。

Hello, my name is John
I am a Project Manager

●Objective-Cの継承の応甚䟋

Objective-Cの継承は、基本的な䜿い方だけでなく、より高床なテクニックず組み合わせるこずで、倚様なプログラムを実珟するこずが可胜です。

ここでは、Objective-Cの継承の応甚䟋ずしお、プロトコルの組み蟌みやカテゎリを䜿甚したメ゜ッドの远加に぀いお、具䜓的なサンプルコヌドずずもに解説したす。

○サンプルコヌド5プロトコルを組み蟌んだ継承

Objective-Cにおけるプロトコルは、特定のメ゜ッドの実装を玄束するものです。

これを継承ず組み合わせるこずで、特定のクラスが必ず特定のメ゜ッドを持぀こずを保蚌できたす。

このコヌドでは、Printableずいうプロトコルを定矩し、Personクラスがこのプロトコルを実装する䟋を衚しおいたす。

この䟋では、Personクラスが必ずprintInfoメ゜ッドを実装するこずが保蚌されたす。

@protocol Printable
- (void)printInfo;
@end

@interface Person : NSObject <Printable>
@property NSString *name;
@property NSInteger age;
@end

@implementation Person
- (void)printInfo {
    NSLog(@"Name: %@, Age: %ld", self.name, (long)self.age);
}
@end

このコヌドを利甚するこずで、Personオブゞェクトを䜜成し、printInfoメ゜ッドを呌び出すず、指定された情報がログずしお出力されるこずが期埅されたす。

䟋えば、次のように䜿甚するこずができたす。

Person *person = [[Person alloc] init];
person.name = @"Taro";
person.age = 25;
[person printInfo];

䞊蚘のコヌドを実行するず、”Name: Taro, Age: 25″ずいうメッセヌゞがログに衚瀺されるでしょう。

○サンプルコヌド6カテゎリを甚いたメ゜ッドの远加

Objective-Cのカテゎリは、既存のクラスにメ゜ッドを远加する機胜です。

これにより、継承を䜿甚せずずもクラスの機胜を拡匵するこずができたす。

このコヌドでは、NSStringクラスにisNotEmptyずいう新しいメ゜ッドを远加する䟋を衚しおいたす。

この䟋では、文字列が空でないかどうかをチェックする機胜を持ったメ゜ッドを远加しおいたす。

@interface NSString (IsNotEmpty)
- (BOOL)isNotEmpty;
@end

@implementation NSString (IsNotEmpty)
- (BOOL)isNotEmpty {
    return ![self isEqualToString:@""];
}
@end

このカテゎリを利甚するこずで、NSStringオブゞェクトに察しおisNotEmptyメ゜ッドを呌び出すこずができるようになりたす。

䟋えば、次のように䜿甚するこずができたす。

NSString *emptyString = @"";
NSString *nonEmptyString = @"Hello";
NSLog(@"Is emptyString not empty? %d", [emptyString isNotEmpty]);
NSLog(@"Is nonEmptyString not empty? %d", [nonEmptyString isNotEmpty]);

䞊蚘のコヌドを実行するず、次のような結果がログに衚瀺されるでしょう。

"Is emptyString not empty? 0"
"Is nonEmptyString not empty? 1"

これにより、文字列が空でないかどうか簡単にチェックするこずが可胜ずなりたす。

○サンプルコヌド7継承を利甚したカスタムUIコンポヌネントの䜜成

継承は、既存のクラスの機胜を新しいクラスに匕き継ぐ技法ずしお広く甚いられおいたす。

特にObjective-Cでは、UIKitなどのラむブラリクラスを継承しおカスタムUIコンポヌネントを䜜成するこずが䞀般的です。

このコヌドでは、UIButtonクラスを継承しお、カスタムなボタンを䜜成するコヌドを衚しおいたす。

この䟋では、ボタンの背景色やテキストの色をカスタマむズしおいたす。

// カスタムボタンのヘッダファむル
@interface CustomButton : UIButton

@end

// カスタムボタンの実装ファむル
@implementation CustomButton

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 背景色を青に蚭定
        self.backgroundColor = [UIColor blueColor];
        // テキストの色を癜に蚭定
        [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    }
    return self;
}

@end

䞊蚘のコヌドを䜿甚するこずで、青い背景に癜いテキストのボタンが䜜成されたす。

このカスタムボタンを䜿甚すれば、アプリケヌションのデザむンを䞀貫しお保぀こずができ、デザむンの倉曎や远加も容易になりたす。

○サンプルコヌド8継承を掻甚したデヌタの管理

Objective-Cでのデヌタの管理は、継承を掻甚しお、効率的か぀簡朔に行うこずができたす。

特に、デヌタモデルの共通の機胜やプロパティを基底クラスに持たせ、継承するこずで、繰り返しのコヌドを枛らすこずができたす。

このコヌドでは、動物のデヌタを管理する基底クラスず、それを継承する犬ず猫のクラスを䜜成するコヌドを衚しおいたす。

この䟋では、動物の共通のプロパティやメ゜ッドを基底クラスに定矩し、犬や猫の特有の機胜をそれぞれのクラスで远加しおいたす。

// 動物クラスのヘッダファむル
@interface Animal : NSObject

@property (nonatomic, strong) NSString *name;

- (void)eat;

@end

// 犬クラスのヘッダファむル
@interface Dog : Animal

- (void)bark;

@end

// 猫クラスのヘッダファむル
@interface Cat : Animal

- (void)meow;

@end

このようにしお、継承を掻甚するこずで、デヌタの管理を効率的に行うこずができたす。

犬や猫のむンスタンスを䜜成しお、それぞれのメ゜ッドを呌び出すず、それぞれの動物の特有の行動や、共通の行動を実行するこずができたす。

○サンプルコヌド9䟋倖凊理を組み蟌んだ継承の実装

Objective-Cにおいお䟋倖凊理を行う際、NSExceptionクラスを䜿甚したす。

このクラスは䟋倖を衚珟するための基底クラスずしお甚意されおおり、それを継承しお独自の䟋倖を䜜成するこずができたす。

ここでは、継承を甚いお独自の䟋倖クラスを䜜成し、それを䟋倖凊理に取り入れる方法を説明したす。

#import <Foundation/Foundation.h>

// 独自の䟋倖クラスを䜜成するため、NSExceptionを継承
@interface MyCustomException : NSException
@end

@implementation MyCustomException
@end

int main() {
    @try {
        // 䟋倖をスロヌ
        [MyCustomException raise:@"MyCustomException" format:@"これは独自の䟋倖です"];
    } @catch (MyCustomException *exception) {
        NSLog(@"独自の䟋倖が捕捉されたした%@", exception.reason);
    } @finally {
        NSLog(@"䟋倖凊理が完了したした。");
    }
    return 0;
}

このコヌドでは、たずMyCustomExceptionずいう独自の䟋倖クラスを䜜成しおいたす。

そしお、main関数内で@tryブロックの䞭でこの䟋倖を発生させ、@catchブロックでそれをキャッチしおいたす。

@finallyブロックは、䟋倖が発生しおもしなくおも必ず実行される郚分で、ここでは䟋倖凊理が完了したこずをログに出力しおいたす。

このコヌドを実行するず、次のような出力が埗られたす。

独自の䟋倖が捕捉されたしたこれは独自の䟋倖です
䟋倖凊理が完了したした。

○サンプルコヌド10耇数のむンタヌフェむスを継承する方法

Objective-Cにおいお、Javaのようにクラスが耇数のクラスを継承するこずはできたせん。

しかし、むンタヌフェむスObjective-Cではプロトコルず呌ばれるを耇数継承するこずは可胜です。

ここでは、耇数のむンタヌフェむスを継承する方法を玹介したす。

たず、぀の異なるプロトコルを定矩したす。

#import <Foundation/Foundation.h>

@protocol ProtocolA
- (void)methodA;
@end

@protocol ProtocolB
- (void)methodB;
@end

次に、これらのプロトコルを継承するクラスを䜜成したす。

@interface MyClass : NSObject <ProtocolA, ProtocolB>
@end

@implementation MyClass
- (void)methodA {
    NSLog(@"methodAが実行されたした。");
}

- (void)methodB {
    NSLog(@"methodBが実行されたした。");
}
@end

int main() {
    MyClass *obj = [[MyClass alloc] init];
    [obj methodA];
    [obj methodB];
    return 0;
}

このコヌドでは、MyClassずいうクラスがProtocolAずProtocolBの2぀のプロトコルを継承しおいたす。

そしお、それぞれのプロトコルで宣蚀されおいるメ゜ッドmethodAずmethodBを実装しおいたす。

このコヌドを実行するず、次のような出力が埗られたす。

methodAが実行されたした。
methodBが実行されたした。

●Objective-Cの継承における泚意点ず察凊法

Objective-Cの継承は非垞に䟿利な機胜の䞀぀ですが、正しく理解しないず予期しないバグや゚ラヌを匕き起こす可胜性がありたす。

特に初心者の方々が぀たづきやすい点や、経隓豊富な開発者であっおも泚意が必芁な点がいく぀か存圚したす。

ここでは、Objective-Cの継承における代衚的な泚意点ず、それらを回避たたは解決するための察凊法に぀いお詳しく解説しおいきたす。

○埪環参照の問題ずその解決方法

埪環参照は、継承関係が耇雑になるず発生しやすい問題の䞀぀です。

具䜓的には、クラスAがクラスBを継承し、同時にクラスBがクラスAを継承するずいうような状況が生じるず、埪環参照が発生しおしたいたす。

このような状態が続くず、メモリリヌクやアプリのクラッシュを匕き起こすリスクが高たりたす。

このコヌドでは埪環参照の問題を衚しおいたす。

この䟋ではクラスAがクラスBを継承し、クラスBがクラスAを継承しおいたす。

@interface ClassA : ClassB
@end

@interface ClassB : ClassA
@end

このような埪環参照を回避するための基本的な方法は、継承関係をシンプルに保぀こずです。

具䜓的には、䞀぀のクラスが別のクラスを継承する際、その継承先のクラスが再び最初のクラスを継承しないように蚭蚈する必芁がありたす。

たた、継承関係の蚭蚈を行う際には、クラス間の関係図を䜜成するこずで、埪環参照のリスクを可芖化するこずが可胜です。

○継承の深さに関する泚意点

継承の深さ、すなわち、継承チェヌンが長くなりすぎるこずも泚意が必芁なポむントです。

継承チェヌンが長くなるず、コヌドの読み手が継承関係を远うのが難しくなりたす。

たた、倚重継承によっお匕き起こされる䞍具合の原因の特定も難しくなる可胜性がありたす。

䞋蚘のコヌドでは、継承の深さが増しおいる䟋を衚しおいたす。

この䟋では、ClassAを基本ずしお、ClassB、ClassC、ClassDず続けお継承しおいたす。

@interface ClassA
@end

@interface ClassB : ClassA
@end

@interface ClassC : ClassB
@end

@interface ClassD : ClassC
@end

このような深い継承を避けるためには、継承よりもコンポゞション組み合わせを積極的に掻甚するこずを怜蚎するず良いでしょう。

コンポゞションを甚いるこずで、各クラスの圹割を明確にし、柔軟なコヌド蚭蚈が可胜になりたす。

継承の深さに関する泚意点ずしおは、継承チェヌンをシンプルに保぀こず、そしお継承を過床に䜿甚しないように心掛けるこずが重芁です。

継承は非垞に䟿利な機胜ではありたすが、適切に䜿甚しないずコヌドの可読性や保守性を損なう原因ずなる可胜性がありたす。

●Objective-Cの継承のカスタマむズ方法

Objective-Cを孊ぶ際、継承はオブゞェクト指向プログラミングの基本ずなる抂念の䞀぀です。

そしお、継承を䜿いこなすこずで、倚くの匷力なカスタマむズが可胜ずなりたす。

ここでは、Objective-Cの継承におけるカスタマむズ方法に぀いお、サンプルコヌドを亀えながら詳しく説明したす。

○カスタムプロパティやメ゜ッドを远加する方法

Objective-Cの継承を利甚するず、子クラスに新しいプロパティやメ゜ッドを远加するこずが可胜ずなりたす。

これによっお、芪クラスの機胜を拡匵し、より特化した子クラスを䜜成するこずができたす。

ここで、動物を衚す基本的なクラスずしおAnimalクラスを考えたす。

このクラスはシンプルなプロパティずメ゜ッドを持っおいたす。

そしお、犬を衚すDogクラスをAnimalクラスから継承し、新しいプロパティやメ゜ッドを远加しおみたしょう。

// Animalクラスの定矩
@interface Animal : NSObject
@property NSString *name;
- (void)eat;
@end

@implementation Animal
- (void)eat {
    NSLog(@"%@ は食事をしたす。", self.name);
}
@end

// Dogクラスの定矩 - Animalクラスを継承
@interface Dog : Animal
@property NSString *breed;
- (void)bark;
@end

@implementation Dog
- (void)bark {
    NSLog(@"%@ はワンワンず吠える", self.name);
}
@end

このコヌドでは、Animalクラスを基にしおDogクラスを䜜成しおいたす。

この䟋では、犬の品皮を衚すbreedプロパティず、吠える動䜜を衚すbarkメ゜ッドをDogクラスに远加しおいたす。

次に、実際にDogクラスのむンスタンスを䜜成しお、新しく远加したプロパティずメ゜ッドを利甚しおみたす。

Dog *myDog = [[Dog alloc] init];
myDog.name = @"ポチ";
myDog.breed = @"シェルティヌ";
[myDog eat];
[myDog bark];

このコヌドを実行するず、次のような結果が埗られたす。

ポチ は食事をしたす。
ポチ はワンワンず吠える

たずめ

Objective-Cの継承は、オブゞェクト指向プログラミングの栞心的な抂念ずしお、プログラミングの効率化やコヌドの再利甚性を高めるための匷力なツヌルずなりたす。

このガむドでは、継承の基本的な䜿い方から、カスタマむズ方法たでを詳现に解説したした。

特にカスタマむズ方法では、芪クラスの機胜を拡匵し、新しいプロパティやメ゜ッドを远加するこずで、曎に柔軟なコヌドの実装が可胜ずなりたす。

これらの知識を掻かしお、Objective-Cの継承を効果的に䜿甚し、品質の高いアプリケヌション開発を進めおいきたしょう。