オブジェクト指向 - shirai/SwiftLearning GitHub Wiki

オブジェクト指向

目標

  • オブジェクト指向について理解している

わかったこと

  • オブジェクトは「属性」「操作」「関係」「アイデンティティ」という特性を持っている

属性

  • 「属性」のことをObjective-Cでは、「メンバー変数」という
  • メンバ変数の定義は以下のように.hファイルに行う
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
	// 名前
	NSString *_name;

	// 年齢
	NSInteger _age;
}
@end

操作

  • 「操作」とは「メソッド」の事である
  • メソッドは.hファイルで宣言することができ、.mファイルで処理を実装する

<Person.h>

@interface Person : NSObject
{
	/// 名前
	NSString *_name;

	/// 年齢
	NSInteger _age;
}
/// 名前を取得する
- (NSString *)name;
/// 名前を設定する
- (void)setName:(NSString *)name;
/// 年齢を取得する
- (NSInteger)age;
/// 年齢を設定する
- (void)setAge:(NSInteger)age;
@end

<Person.m>

#import "Person.h"
@implementation Person
/// 名前を取得する
- (NSString *)name {
	return _name;
}
/// 名前を設定する
- (void)setName:(NSString *)name {
	_name = name;
}
/// 年齢を取得する
- (NSInteger)age {
	return _age;
}
/// 年齢を設定する
- (void)setAge:(NSInteger)age {
	_age = age;
}
@end

アイデンティティ

  • 対象のクラスをインスタンス化することで、 アイディンティ(メモリ上のアドレス) を得る
    • 基本的にalloc,initを行うことでクラスインスタンスが生成され、オブジェクトはアイデンティティを得る
    • クラスをインスタンス化することで、そのクラスの.hファイルで宣言されているインスタンス変数やインスタンスメソッドにアクセスできるようになる

<ViewController.m>

#import "ViewController.h"
// Personクラスをインポートする
#import "Person.h"
@implementation ViewController
- (void)viewDidLoad {
	[super viewDidLoad];

	// Personクラスのインスタンスを生成する
	Person *yuki = [[Person alloc] init];

	// 名前を設定する
	[yuki setName:@"平井祐樹"];

	// 年齢を設定する
	[yuki setAge:28];

	// 名前と年齢をコンソールに表示する
	NSLog(@"こんにちは、私の名前は%@です。年齢は%d歳です。", [yuki name], [yuki age]);
}
@end

関係

  • クラス内の別のオブジェクトと関係が持てることを表している

<Person.h>

#import <Foundation/Foundation.h>
@interface Person : NSObject
{
	/// 名前
	NSString *_name;

	/// 年齢
	NSInteger _age;

	/// 父親
	Person *_father;
}
/// 名前を取得する
- (NSString *)name;
/// 名前を設定する
- (void)setName:(NSString *)name;
/// 年齢を取得する
- (NSInteger)age;
/// 年齢を設定する
- (void)setAge:(NSInteger)age;
/// 父親を取得する
- (Person *)father;
/// 父親を設定する
- (void)setFather:(Person *)father;
@end

<Person.m>

#import "Person.h"
@implementation Person
/// 名前を取得する
- (NSString *)name {
	return _name;
}
/// 名前を設定する
- (void)setName:(NSString *)name {
	_name = name;
}
/// 年齢を取得する
- (NSInteger)age {
	return _age;
}
/// 年齢を設定する
- (void)setAge:(NSInteger)age {
	_age = age;
}
/// 父親を取得する
- (Person *)father {
	return _father;
}
/// 父親を設定する
- (void)setFather:(Person *)father {
	_father = father;
}
@end  

<ViewController.m>

#import "ViewController.h"
// Personクラスをインポートする
#import "Person.h"
@implementation ViewController
- (void)viewDidLoad {
	[super viewDidLoad];

	// Personクラスのインスタンスを生成する
	Person * yuki = [[Person alloc] init];
	// 名前を設定する
	[yuki setName:@"平井祐樹"];
	// 年齢を設定する
	[yuki setAge:28];

	// 父親インスタンスを作成する
	Person *father = [[Person alloc] init];
	// 名前を設定する
	[father setName:@"平井太郎"];
	// 年齢を設定する
	[father setAge:56];

	// fatherインスタンスをyukiインスタンスに設定する
	[yuki setFather:father];

	// 名前と年齢と父親の名前をコンソールに表示する
	NSLog(@"こんにちは、私の名前は%@です。年齢は%d歳です。父親の名前は%@です。",
		[yuki name],
		[yuki age],
		[[yuki father] name]
	);
}
@end
  • オブジェクト指向は「カプセル化」「継承」「ポリモーフィズム」「抽象化」という4つの特徴を持っている

カプセル化

  • 他のクラスのオブジェクトには、メソッドを介してしかアクセスできないこと
  • objective-Cでは @property を使うことで、メソッドを使っていないように見せることができる
    • @property を利用すると、内部的には「メンバ変数」と「getter/setterメソッド」を定義している
    • @property で定義した変数へアクセスするときは、自動生成された「getter/setterメソッド」を介してアクセスが行われている
  • 例:表示したい文字列を生成するメソッドがあり、表示するメソッドがそれとは別のクラスにある場合、
    表示したい文字列を生成するメソッドさえ変更すれば、表示が変わる。

継承

  • 親クラスに書いたメンバ変数やメソッドは、親クラスを継承した子クラスであれば、何か定義をしなくても使えるということ

抽象化

  • 同じような特性を持つオブジェクトの共通項を最低限、抽象クラスとして切り出す。
    それを継承した子クラスを作り、抽象クラスのメソッドをオーバーライドすることで、
    それぞれに共通した部分をもたせつつ、独自の特徴を持つクラスを作り出せるということ

ポリモーフィズム

  • 子クラスで親クラスのメソッドをオーバーライドした際に、呼び出すクラスインスタンスがによって処理が変わること
    • 例:親クラスA、子クラスBをとし、introduceMyselfというメソッドを両方で定義したとする(子クラスBでオーバーライドしたと同義)。
      その際ViewControllerクラスで、AとBのインスタンスを生成し[A introduceMyself][B introduceMyself]とすると、
      それぞれそのクラスで定義した内容の処理を行う

わからなかったこと

  • とどのつまり関係性とはなんなのか
    • オブジェクトは他のオブジェクトへの 参照 を持つことができる

次にやること

  • それぞれの具体的な例をソースコードで表す
⚠️ **GitHub.com Fallback** ⚠️