ここが違う!JavaとObjective-Cのクラス定義

先の投稿でActionScript3とObjective-Cのクラス定義の違いについて比較しましたが、今度はJavaとObjective-Cのクラス定義の違いについて見てみましょう。Javaがわかる人がObjective-Cを学ぶために、逆にObjective-Cはわかったから次はJavaを始めようという人にとっての相互の知識補完になると思います。ActionScript3が得意な人はJavaのシンタックスを見て、「あれ?ActionScript3と似てる!?」と思うかもしれませんね。

では、両者のクラス定義のコードを比較してみます。

Javaのクラス定義
JavaでMyClassを定義するならば、クラス名と同名のMyClass.javaを作り、次のような構造のコードを記述します。
package{
  public class MyClass{

  //コンストラクタ
  MyClass(){
  }

  //インスタンスメソッド
  public void hello(){
    System.out.println("ハロー");
  }
}
Objective-Cのクラス定義
Objective-CでMyClassを定義する場合は、ヘッダファイルのMyClass.hと実装ファイルのMyClass.mの2つのファイルを使います。簡単に言えば、ヘッダファイルには他のクラスからアクセスできるプロパティやメソッドの宣言文を書き、実装ファイルでプロパティの値の設定、メソッドの定義文を書きます。

ヘッダファイル MyClass.h
#import <Foundation/Fundation.h>

@interface MyClass:NSObject
- (void)hello;
@end

実装ファイル MyClass.m
#import "MyClass.h"

@implementation MyClass

- (void)hello{
  NSLog(@"ハロー");
}

@end

Objective-Cにはpackageもコンストラクタもありません。メソッドの前の-は、もちろんマイナスの負号ではありません。-はインスタンスメソッドを示します。+ならばクラスメソッドです。クラス図のUMLでは+ -でメンバーのアクセス権を示しますが、それとは違うので間違えないようにしてください。
では、Objective-Cではどうやってクラスのインスタンスを作るのでしょう?次にインスタンスを作る方法を比較してみます。

Javaでインスタンスを作る
JavaではnewキーワードでMyClassコンストラクタを呼び出すとインスタンスが返ります。
MyClass myObj = new MyClass();
Objective-Cでインスタンスを作る
Objective-Cにはコンストラクがありません。次のようにallocメソッドを実行してmyObjインスタンスを作ります。次の行のinitはmyObjインスタンスの初期化メソッド(イニシャライザ)です。
MyClass *myObj = [MyClass alloc];
myObj = [myObj init];
[MyClass alloc]と[myObj init]は、Objective-Cでもっとも特徴的なメッセージ式と呼ばれる書式をしています。

メッセージ式
[オブジェクト メソッド]

[MyClass alloc]の式によってMyClassクラスのallocメソッドを実行します。しかし、MyClassクラスにはallocメソッドが定義されていません。ここで先のMyClassクラス定義のヘッダファイルをもう一度よく見てください。

MyClass.hファイル
#import <Foundation/Fundation.h>

@interface MyClass:NSObject
- (void)hello;
@end

:NSObjectという部分は、MyClassクラスがNSObjectクラスを継承していることを示しています。継承はJavaならば「MyClass extends NSObject」と書きますね。
そうです。allocメソッドはNSObjectクラスから継承しているクラスメソッドです。NSObjectクラスは、Objective-Cのすべてのクラスのルートクラスであり、継承したい特定のクラスがない場合には、NSObjectクラスをスーパークラスとして指定する決まりになっています。

[MyClass alloc]を実行するとMyClassのインスタンスが作られますが、このままではまだmyObjを利用できません。[myObj init]を実行することでmyObjが初期化され、インスタンスとして使えるようになります。allocメソッドはNSObjectクラスのクラスメソッドですが、initメソッドはNSObjectクラスで定義されているインスタンスメソッドです。
インスタンスの作成と初期化は必ず実行する手順なので、先の式は次のように1行で記述するのが一般的です。

Objective-Cでのインスタンスの作成と初期化
MyClass *myObj = [[MyClass alloc] init];
ところで、myObjの前の*はタイプミスではありませんよ。オブジェクトを入れる変数は*を付けて宣言するのです。別の言い方をすれば、*はアドレスを参照する値を示しています。

さて、インスタンスの作り方がわかったところで、MyClassで定義したhelloメソッドを実行するところまで見ておきましょう。

Javaでhelloメソッドを実行する
myObjに対してドットシンタックスでhello()メソッドを実行します。
MyClass myObj = new MyClass(); //myObjを作る
myObj.hello(); //helloメソッドを実行する

Objective-Cでhelloメソッドを実行する
先ほどインスタンスを初期化するためにinitインスタンスメソッドを使ったので、もうわかりますね。
メッセージ式を使ってmyObjのhelloメソッドを実行します。hello()のようにカッコが付かない点にも注意しましょう。
MyClass *myObj = [[MyClass alloc] init]; //myObjを作る
[myObj hello]; //helloメソッドを実行する

Objective-Cのクラス定義にはまだ謎がたくさんありますが、それはまた改めて書くことにします。