クラスメソッドとインスタンスメソッドの違いは何ですか?


448

クラスメソッドとインスタンスメソッドの違いは何ですか?

インスタンスメソッドはアクセサ(ゲッターとセッター)ですが、クラスメソッドは他のほとんどすべてです。

回答:


673

他のほとんどの回答で述べたように、インスタンスメソッドはクラスのインスタンスを使用しますが、クラスメソッドはクラス名だけで使用できます。Objective-Cでは、次のように定義されています。

@interface MyClass : NSObject

+ (void)aClassMethod;
- (void)anInstanceMethod;

@end

その後、次のように使用できます。

[MyClass aClassMethod];

MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];

クラスメソッドのいくつかの現実の世界の例では、多くの財団のようなクラスの便利なメソッドですNSStringさん+stringWithFormat:NSArrayさん+arrayWithArray:。インスタンスメソッドはNSArray-countメソッドになります。


7
いい答えです。また、メソッドを説明するための特定の省略表記が表示されることにも注意してください。たとえば、+ [NSString stringWithFormat:]は、NSStringのクラスメソッド+ stringWithFormat:です。-[NSArray objectAtIndex:]はインスタンスメソッドです。複数のセレクター部分を持つメソッドは、-[NSMutableDictionary setObject:forKey:]などのように記述されます。この表記は、Cocoa応答、ドキュメント、およびXcodeでよく見られます。
クインテイラー

149
他の多くの言語では、クラスメソッドは「静的」メソッドと呼ばれていることを付け加えておきます。また、元の質問に答えるために、アクセサは特定のインスタンスの状態を設定および取得するため、インスタンスメソッドです。上記の例では、NSArray countは特定のインスタンスのオブジェクトの数を返します。
ブライアンパン

2
「クラスメソッドはクラス名だけで使用できます。」またはクラスオブジェクト
user102008

2
わくわくしてしまい申し訳ありません...しかし、違いとその可能性を知りました。クラスメソッドは揺るがず、シングルトンクラスもそうです!私は恋に落ちたよ!<3
Pavan

2
@BrianPan静的メソッドとクラスメソッドは同じではありません。それらは似ていますが、名前が異なるのは、動作が異なるためです。たとえば、静的メソッドはオーバーライドできません。
2013年

190

技術的な詳細はすべて、他の回答でうまくカバーされています。クラスとインスタンスの違いをうまく説明していると思う単純な類推を共有したいだけです。

ここに画像の説明を入力してください

クラスが似ている青写真家の:あなたは唯一の青写真とを持っている(通常は)あなただけでは青写真でその多くを行うことはできません。

ここに画像の説明を入力してください

インスタンス(またはオブジェクト)実際のあるあなたが設計図に基づいて構築することを:あなたは、同じ設計図からの家屋の多くを構築することができます。次に、他のインスタンスに影響を与えずにクラスの各インスタンスのプロパティを個別に変更できるのと同じように、各家の壁に異なる色をペイントできます。


6
@JohannesFahrenkrugクラスとオブジェクトのコンセプトをここでうまく説明しましたdifference between class method and an instance method 。実際の質問は、
Shekhu

1
クラスとクラスのインスタンスの完全な説明。クラスは初心者にとっては奇妙な概念であり、これは最も基本的な方法でそれを説明します。
Alex McPherson

1
@JohannesFahrenkrugは本当に良い説明でした。両方のrの差分と、いつ両方を使用するのかを考えさせられました
ChenSmile

1
そのような素晴らしい説明:)
Praveenkumar

1
良いアナロジー。誰かがこの男に一年分のピザをあげてください。
GeneCode、2017

102

他の答えが言ったように、インスタンスメソッドはオブジェクトを操作し、そのインスタンス変数にアクセスできますが、クラスメソッドはクラス全体を操作し、特定のインスタンスの変数にはアクセスできません(インスタンスをパラメータ)。

クラスメソッドの良い例は、クラスのインスタンスの総数を返すカウンタータイプのメソッドです。クラスメソッドはで始まり+ますが、インスタンスメソッドはで始まります-。例えば:

static int numberOfPeople = 0;

@interface MNPerson : NSObject {
     int age;  //instance variable
}

+ (int)population; //class method. Returns how many people have been made.
- (id)init; //instance. Constructs object, increments numberOfPeople by one.
- (int)age; //instance. returns the person age
@end

@implementation MNPerson
- (id)init{
    if (self = [super init]){
          numberOfPeople++;
          age = 0;
    }    
    return self;
}

+ (int)population{ 
     return numberOfPeople;
}

- (int)age{
     return age;
}

@end

main.m:

MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(@"Age: %d",[micmoo age]);
NSLog(@"%Number Of people: %d",[MNPerson population]);

出力:年齢:0人数:2

もう1つの例は、ユーザーが呼び出せるようにするメソッドがある場合です。クラスメソッドにするとよい場合もあります。たとえば、MathFunctionsというクラスがある場合、次のようにできます。

+ (int)square:(int)num{ 
      return num * num;
}

したがって、ユーザーは次のように呼び出します。

[MathFunctions square:34];

クラスをインスタンス化する必要はありません!

NSArrayのような自動解放されたオブジェクトを返すためにクラス関数を使用することもできます

+ (NSArray *)arrayWithObject:(id)object

これはオブジェクトを取得して配列に入れ、メモリ管理の必要がない配列の自動解放バージョンを返します。これは一時配列などに適しています。

クラスメソッドを使用するタイミングと理由を理解していただけたら幸いです。


1
micmoo、「static int numberOfPeople = 0;」を置くことをお勧めします。コード形式のテキストで?サンプルコードの上に気づくまで混乱しました。それ以外は、本当に簡潔な答えです。
mobibob 2010

2
私の初心者の混乱を許してください、しかしなぜあなたはインスタンス変数「age」とインスタンスメソッド「age」の両方が必要なのですか?インスタンス変数「age」のゲッターとセッターは@synthetizeで作成されませんか?
2013

@selytch "age"は、synthetizeを使用するためにプロパティとして定義する必要があります。
micah94 2014年

36

インスタンスメソッドはクラス(つまりオブジェクト)のインスタンスに適用されますが、クラスメソッドはクラス自体に適用されます。

C#では、クラスメソッドは静的とマークされます。staticとマークされていないメソッドとプロパティはインスタンスメソッドです。

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}

1
ああ、申し訳ありませんが、これはObj-Cの質問だと気づきました。うまくいけば私の答えはまだ適用されますが、投票するか投票して削除してください。
Robert Horvick、2009年

6
大丈夫です。あなたの答えの最初の部分は一般的なOOP原則として正しいです、そしてそれは間違いなくObjective-Cに適用されます。タグのリストに「objective-c」を追加して、そのような質問を見たくない場合は無視することができますが、参加は大歓迎です。:-)
クイン・テイラー

16

あなたの質問への答えはobjective-cに固有ではありませんが、異なる言語では、クラスメソッドは静的メソッドと呼ばれる場合があります。

クラスメソッドとインスタンスメソッドの違いは次のとおりです。

クラスメソッド

  • クラス変数を操作する(インスタンス変数にアクセスできない)
  • オブジェクトを適用するためにインスタンス化する必要はありません
  • コードのにおいがすることもあります(OOPを初めて使用する人の中には、オブジェクト指向環境で構造化プログラミングを行うための松葉杖として使用する人もいます)。

インスタンスメソッド

  • インスタンス変数とクラス変数を操作する
  • 操作するインスタンス化されたオブジェクトが必要です

インスタンスメソッドはクラス変数を操作できますか?
蘇健豪

16

これを理解する最善の方法はallocinit。この説明で違いを理解することができました。

クラスメソッド

クラスメソッドは、クラス全体に適用されます。allocメソッドを確認すると、それは、+それはメソッド宣言の前にでです。これは、クラスの特定のインスタンスを作成するためにクラスに適用されるため、クラスメソッドです。

インスタンスメソッド

インスタンスメソッドを使用して、クラス全体ではなく、そのインスタンスに固有のクラスの特定のインスタンスを変更します。initたとえば、(-メソッド宣言の前にで示されています)はインスタンスメソッドです。これは、通常、で作成された後にそのクラスのプロパティを変更しているためですalloc

NSString *myString = [NSString alloc];

allocそのクラスのインスタンスを生成するために、クラスメソッドを呼び出しています。メッセージの受信者がクラスであることに注意してください。

[myString initWithFormat:@"Hope this answer helps someone"];

そのインスタンスにいくつかのプロパティを設定して、NSString呼び出さmyStringれたのインスタンスを変更しています。メッセージの受信者がインスタンス(クラスのオブジェクトNSString)であることに注意してください。


「alloc」メソッドをチェックするとはどういう意味ですか?ドキュメントの特定の場所を教えていただけますか?(編集) - - >ああ用事、ええNSObjectのドキュメントにその「タスク」の下に言うdeveloper.apple.com/library/ios/documentation/cocoa/reference/...
イーサン・パーカー

これを把握するために実際に何が行われているのかを理解する必要はありません。クラスに適用されるだけです。簡単に言うallocと、オブジェクトに十分なメモリを割り当てinit、それらのメモリアドレスの内容を変更して、オブジェクトの状態を定義します。オブジェクトを変更するスペースがない限り、オブジェクトを変更することはできません。そのため、そのスペースを指定するallocクラスを使用します。
アダムウェイト2014年

6

クラスメソッドは通常、そのクラスのインスタンスを作成するために使用されます

たとえば、送信されたパラメータを持つインスタンスを[NSString stringWithFormat:@"SomeParameter"];返しますNSString。したがって、その型のオブジェクトを返すのはClassメソッドであるため、簡易メソッドとも呼ばれます。


6

だから私がそれを正しく理解すれば。

classこの方法は、使用/プロセス、それにそのオブジェクトのインスタンスを割り当てるためにあなたを必要としません。classこの方法は、自己完結型であり、そのクラスのすべてのオブジェクトの状態のいずれかに依存することなく動作することができます。あclass方法が行われた場合、そのクラスのインスタンスは、クラスメソッドの前回の呼び出しで割り当てられたメモリを解放することができないので、すべての独自の作業と割り当て解除のためにメモリを割り当てることが期待されます。

instanceこの方法は正反対です。そのクラスのインスタンスを割り当てない限り、それを呼び出すことはできません。これは、コンストラクターがあり、デストラクターを持つことができる(割り当てられたすべてのメモリをクリーンアップする)通常のクラスのようなものです。

ほとんどの場合(再利用可能なライブラリを作成しているのでない限り、class変数は必要ありません)。


1
クラスメソッドが必要な明らかなケースは、インスタンスの作成です。インスタンスを作成せずにインスタンスを作成できる必要があります。そうしないと、最初のインスタンスを作成できません。そのため、+ allocはクラスメソッドである必要があります。
gnasher729 2014年

4

インスタンスメソッドは、クラス(つまり、「オブジェクト」)のインスタンスを操作します。クラスメソッドはクラスに関連付けられています(ほとんどの言語staticはこれらの人のためにキーワードを使用しています)。


3

たくさんの車がスポーンされるゲームを例にとります。それぞれがCCarクラスに属しています。車がインスタンス化されると、

[CCar registerCar:self]

したがって、CCarクラスは、インスタンス化されたすべてのCCarのリストを作成できます。ユーザーがレベルを終了し、すべての車を削除したいとします...次のいずれかを実行できます... 1-手動で作成したすべてのCCarのリストを調べて実行するwhicheverCar.remove(); か、2- removeAllCarsメソッドをCCarに追加します。 [CCar removeAllCars]を呼び出すとあなたのために。すなわち allCars[n].remove();

または、たとえば、起動時に読み込まれ、保存されるアプリ全体のデフォルトのフォントサイズをユーザーが指定できるようにします。クラスメソッドなしでは、あなたは次のようなことをしなければならないかもしれません

fontSize = thisMenu.getParent().fontHandler.getDefaultFontSize();

クラスメソッドを使用すると、を回避できます[FontHandler getDefaultFontSize]

removeVowels関数については、C#などの言語には、toLowerやtoUpperなどの特定のメソッドの両方が実際にあることがわかります。

たとえばmyString.removeVowels() and String.removeVowels(myString) (ObjC [String removeVowels:myString]では)。

この場合、インスタンスはクラスメソッドを呼び出す可能性が高いため、両方を使用できます。すなわち

public function toLower():String{
  return String.toLower();
}

public static function toLower( String inString):String{
 //do stuff to string..
 return newString;
}

基本的に、myString.toLower() 呼び出し [String toLower:ownValue]

明確な答えはありませんが、クラスメソッドを押し込むことでコードが改善されると感じた場合は、試してみてください。クラスメソッドでは、他のクラスメソッド/変数しか使用できないことに注意してください。


3

クラスメソッド

静的として宣言されているメソッドです。メソッドは、クラスのインスタンスを作成せずに呼び出すことができます。クラスメソッドはインスタンスメンバーを認識しないため、クラスメソッドはクラスメンバーでのみ動作し、インスタンスメンバーでは動作しません。クラスのインスタンスメソッドは、そのクラスのインスタンスで呼び出されていない限り、クラスメソッド内から呼び出すこともできません。

インスタンスメソッド

一方、クラスのインスタンスを呼び出す前に、クラスのインスタンスが存在する必要があるため、newキーワードを使用してクラスのインスタンスを作成する必要があります。インスタンスメソッドは、クラスの特定のインスタンスを操作します。インスタンスメソッドは静的として宣言されていません。


「新規」だけでなく、「alloc」キーワードを使用して作成することもできます。また、Objective-Cは、インスタンスメソッドを呼び出すためにインスタンスの存在を要求しません。メッセージをnullポインターに送信できます。
Elviss Strazdins 2015年

3

Objective-Cでは、すべてのメソッドは「-」または「+」の文字で始まります。例:

@interface MyClass : NSObject
// instance method
- (void) instanceMethod;

+ (void) classMethod;
@end

「+」と「-」の文字は、メソッドがそれぞれa class methodかan かを指定しますinstance method

これらのメソッドを呼び出すと、違いは明らかです。ここでは、メソッドはで宣言されていMyClassます。

instance method クラスのインスタンスが必要です:

MyClass* myClass = [[MyClass alloc] init];
[myClass instanceMethod];

MyClass他のメソッドの内部では、以下MyClassを使用するインスタンスメソッドを呼び出すことができますself

-(void) someMethod
{
    [self instanceMethod];
}

ただし、class methodsクラス自体で呼び出す必要があります。

[MyClass classMethod];

または:

MyClass* myClass = [[MyClass alloc] init];
[myClass class] classMethod];

これは動作しません:

// Error
[myClass classMethod];
// Error
[self classMethod];

3

クラスメソッド


クラスメソッドは通常、クラスの新しいインスタンスを作成するか、クラスのいくつかのグローバルプロパティを取得します。クラスメソッドは、インスタンスを操作したり、インスタンス変数にアクセスしたりすることはありません。


インスタンスメソッド


インスタンスメソッドは、クラスの特定のインスタンスを操作します。たとえば、実装したアクセサメソッドはすべてインスタンスメソッドです。それらを使用して、特定のオブジェクトのインスタンス変数を設定または取得します。


呼び出す


インスタンスメソッドを呼び出すには、クラスのインスタンスにメッセージを送信します。

クラスメソッドを呼び出すには、メッセージをクラスに直接送信します。


出典:IOS-Objective-C-クラスメソッドとインスタンスメソッド


1

クラスメソッドは、インスタンス変数の値を変更または認識できません。これは、インスタンスメソッドをクラスメソッドにできるかどうかを判断するための基準になります。


-1です。インスタンスをクラスメソッドに渡すことができ、変数の値を変更して知ることができるためです。
Elviss Strazdins 2015年

1

また、同じ考え方が変数にも当てはまります。メソッド/関数の場合と同じように変数について話すと、静的、メンバー、インスタンス、クラスなどの用語に出くわします。

Obj-Cコミュニティの一般的な用語はインスタンス変数のivarですが、私はまだObj-Cの人ではありません。


1

上記の回答の更新、インスタンスメソッドはクラスのインスタンスを使用することに同意しますが、クラスメソッドはクラス名だけで使用できます。

Objective-Cで自動参照カウントが存在するようになった後は、インスタンスメソッドとクラスメソッドの間に違いはありません。

たとえば[NS StringWithformat:..]、クラスメソッドと[[NSString alloc] initwihtformat:..]インスタンスメソッドの場合、ARCの後はどちらも同じです。


1

注:これは疑似コード形式のみです

クラスメソッド

ほとんど必要なことは、コンパイル時だけです。ユーザー入力は必要ありません。また、その計算はインスタンスに基づいています。それに関するすべては、クラス/ブループリントに基づいています-これはユニークです。つまり、1つのクラスに複数のブループリントがないということです。コンパイル時にさまざまなバリエーションを使用できますか?いいえ、したがって、クラスは一意であるため、クラスメソッドを何度呼び出しても、それを指すポインタは同じになります。

PlanetOfLiving: return @"Earth" // No matter how many times you run this method...nothing changes.

インスタンスメソッド

それとは逆に、インスタンス化のたびに変化する可能性がある何かのインスタンスを作成したのそのときだけなので、実行時にインスタンスメソッドが発生します。

initWithName: @"John" lastName: @"Doe"Age:12 @"cool"
initWithName: @"Donald" lastName: @"Drumpf"Age:5 attitude:@"He started"
initWithName: @"President" lastName: @"Obama"Age:54 attitude: @"Awesome"
//As you can see the value can change for each instance.

他の言語を使用している場合、静的メソッドはクラスメソッドと同じです。
Swiftの場合、型メソッドはクラスメソッドと同じです。


0

上記の回答に追加

クラスメソッドはクラスで機能します。これを+ stringWithFormat、クラスのサイズなどの一般的な目的に使用します。最も重要なのはinitなどです。

NSString *str = [NSString stringWithFormat:@"%.02f%%",someFloat]; 

インスタンスメソッドは、2人の人間がいて、インスタンスメソッドを使用する必要があるそれぞれのバランスを個別に知りたい場合など、クラスではなくクラスのインスタンスで機能します。それは一般的な応答を返さないからです。たとえば、NSSArrayの数などを決定します。

[johnson getAccountBalance];
[ankit getAccountBalance];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.