Objective-C vs Java とその周辺
ガベゴレ有効を前提に、ありがちなOOPっぽいコードを、Objective-Cで書いてみました。
以下のコードは、GNUstepを使ってコンパイルしています。
http://www.gnustep.org/
あ、GNUstepのチュートリアルのコード残骸がちらほら…。
#include <stdio.h> #include <Foundation/Foundation.h> @protocol MessageHolder - (NSString *) message; - (void) setMessage: (NSString *) text; @end @interface MessageHolderImpl : NSObject <MessageHolder> { @private NSString * message; } + (const char *) classStringValue; @end @implementation MessageHolderImpl + (const char *) classStringValue; { return "This is the string value of the Test class"; } - (NSString *) message { return message; } - (void) setMessage: (NSString *) text { message = text; } @end @interface MessageHolderFactory : NSObject + (id <MessageHolder>) newInstance; @end @implementation MessageHolderFactory + (id <MessageHolder>) newInstance { return [[MessageHolderImpl alloc] init]; } @end int main(void) { printf("%s\n", [MessageHolderImpl classStringValue]); id<MessageHolder> test = [MessageHolderFactory newInstance]; [test setMessage: @"hoge"]; printf("%s\n", [[test message] cString]); return 0; }
で、Javaで同じようなものを書いてみました。バリバリJava5以上です。printfのギャップを埋めるコードは飛ばして読んでください。C言語みたいに、引数にchar[]を入れると表示可能な文字が出る仕掛けです。
import java.util.List; import java.util.LinkedList; interface MessageHolder { public void setMessage(String text); public String getMessgae(); } class MessageHolderImpl implements MessageHolder { //extends Object private String message = null; public static char[] classStringValue() { return "This is the string value of the Test class".toCharArray(); } public void setMessage(String text) { message = text; } public String getMessgae() { return message; } } class MessageHolderFactory { // extends Object public static MessageHolder newInstance() { return new MessageHolderImpl(); } } public class MessageHolderTest { public static void main(String[] args) { printf("%s\n", MessageHolderImpl.classStringValue()); MessageHolder test = MessageHolderFactory.newInstance(); test.setMessage("hoge"); printf("%s\n", test.getMessgae().toCharArray()); } //C-like printf which translates char[] to String before output. private static void printf(String fmt, Object... values) { List<Object> converted = new LinkedList<Object>(); for(Object v : values){ converted.add((v instanceof char[]) ? String.valueOf((char[])v) : v); } Object[] args = converted.toArray(); System.out.printf(fmt, args); } }
まともにコンストラクタ書いてないので、あまりいいコード例じゃないですが、どんな感じでしょう?C言語資産を使うために、かぎ括弧の多重人格構文を受け入れるかどうか、悩みどころですね。Appleさん、早くNeXT文化からGCJかD言語に切り替えてくれないかな。
以下、ついでにわれらがインタプリタたち。言語仕様がメソッド実装を強制しないので、ソースコードコメントで対処w
#interface restriction!! # Class that has getMessage and setMessage would be assumed as one of MessageHolder. class MessageHolderImpl(object): @staticmethod def classStringValue(): return "This is the string value of the Test class" def getMessage(self): return self.message def setMessage(self, text): self.message = text def newMessageHolder(): return MessageHolderImpl() print MessageHolderImpl.classStringValue() test = newMessageHolder() test.setMessage("hoge") print test.getMessage()
#interface restriction!! # Class that has getMessage and setMessage would be assumed as one of MessageHolder. class MessageHolderImpl def MessageHolderImpl.classStringValue "This is the string value of the Test class" end def message @message end def message= text @message = text end end def newMessageHolder MessageHolderImpl.new end puts MessageHolderImpl.classStringValue test = newMessageHolder test.message = "hoge" puts test.message
驚くべきことに、初回実行でエラーなし。まあ、根本的に使いどころが違うのでずるいのですが、もしメモリとCPUの余剰パワーがあるんなら、Objective-CやJNIでC言語資産を活かすより、実はSWIGのほうが強いんじゃ?
という意味で、これ↓の動機がよくわからないのです。
http://cappuccino.org/
変数宣言に型がある!?へんなの〜。ていうかJavaScriptで別の言語のインタプリタ!
たしかに面白い発想なんだけど、でも、ECMAな言語でOOP構文サポートしたけりゃ、ActionScript2、っていうかhaXeが、記述性の面でも性能の面でも、正解なんじゃないのかな、と思うのですが…(ECMA4とかAS3とかは違う)。かぎ括弧で、ネイティブJavaScriptな部分とそうじゃない部分を区切りやすくしてでも、インタプリタにこだわる理由ってなんなんだろう?
JavaScriptはJavaScriptとして書いておかないと、いま流行の超高速JavaScript実行系が最適化してくれないと思うので、デモ以上のことすると、わりと早くに頭打ちになりそうな気がしてなりません。それ考えると、constructor.prototype...の汚いコードをライブラリに押し込んで隠しておき、関数リテラルを含んだJSONからオブジェクトツリーを構築できるビルダーなんかを公開しておいて、アプリケーションコードはJavaScriptという関数プログラム言語を活かす、っていうレガシーな方法が王道じゃないのかな?
CocoaとObjective-Cって、そんなにハマるもの?「Appleの方法は正しい、Appleがどのぐらい正しいかではなく、Appleだからすべて正しい」って思考回路が出来上がってないかな。