読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

さくっと基本を振り返る

Objective-C 日記

言語仕様からいえば、ポリモーフィズムに継承やインプリメントが要らないのは楽でよい。
というかメッセージという考え方の時点で既に Java のそれと全然違うのは明白。
だれだ Javaオブジェクト指向で「メッセージ」とかぬかした奴(なんかかなりいた気がするぞw)。

Hello クラスで見るオブジェクト指向の違い

Java 版。

class Hello {
  public string hello(String name) {
    return "Hello " + name + ".";
  }

  public static void main(String args[]) {
    Hello hello = new Hello();
    System.out.println(hello.hello("Azalea"));
  }
}

Objective-C

// hello.h
#import <Cocoa/Cocoa.h>
@interface Hello : NSObject {
}
-(NSString*)hello:(NSString*)name;
@end
#import <Foundation/Foundation.h>
#import "Hello.h"
@implementation Hello
-(NSString*)hello:(NSString*)name {
	return [NSString stringWithFormat:@"Hello %@.",name ];
}
@end

int main (int argc, const char * argv[]) {
	Hello* hello = [Hello alloc];
    NSLog([hello hello:@"Azalea"]);
    return 0;
}

へなへなっと。
実行結果で見れば一緒。でも意味合いがだいぶ違う。

Objective-C はこれができる。

int main (int argc, const char * argv[]) {
    id* hello = [Hello alloc];
    NSLog([hello hello:@"Azalea"]);
    [hello release];
    return 0;
}

これを java で安易に書くとこう。

public static void main(String args[]) {
  object hello = new Hello();
  System.out.println(hello.hello("Azalea"));
}

当たり前だけどコンパイルエラーになる。
Java で正確に書くならこんな感じか?

import java.lang.reflect.*;

Method method = hello.getClass().getMethod("hello", new Class[] {String.class});
method.Invoke(hello, new String[] {"Azalea"});

返値忘れてるが多分こんな感じ。
オブジェクト内から一致するメソッド情報抜き出して実行する。
Objective-C は実質これをやってるに等しいと思う。

故に、すべてのオブジェクトが object(id) で扱われ、ポリモーフィズムとか「そんなの関係ねぇ!」と動き回る。
実際の実装はどうこう別にせよ、「メッセージ」ってのはメソッドコールとは別のもので、オブジェクトに対する問いかけである。
あくまでただの問いかけだから、問いかける相手が誰だろうと知った事ではない。*1

*1:そして関係ないのに問いかけると「んな事知るかヴォケ!」と切れて例外を出すと、、、