iPhone用アプリケーション開発で注目を集める言語「Objective-C」。C++とは異なるC言語の拡張を目指したこの言語の基本を理解しよう(編集部)
唐突ですが、皆さんは新たに1つのプログラミング言語を修得しようと思い立ったとき、最初に何をしますか。その言語の入門用サイトを見て回る、関連書籍を立ち読みする、サンプルを入手して取りあえず動かしてみる、といったところでしょうか。ちなみに私は書籍が好きで、しかも立ち読みではなく購入派です。
いずれにしても、まずはその言語のコードを目で見て、「いったいどんな言語なのか」というイメージをつかむのが最初の一歩となるでしょう。何かしらのプログラミング経験がある人なら、コードを眺めて、「ああ、あの言語に似ているな」とか「うわ、これはとっつきにくい」といった印象を抱くはずです。例えば、初めて見たPerlのコードが複雑な正規表現でびっしりだった場合、それは不幸な出合いといえるかもしれません。
さて、Objective-Cのコードの特徴的な部分をいくつか盛り込み、かつ不幸な出合いとならないようになるべくシンプルにまとめたコードを提示してみましょう。
#import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <stdio.h> // クラスの宣言 @interface MyTestClass : NSObject { NSString *myTestString; } - (void)setMyTestString :(NSString *)testString; - (void)printMyTestString; @end // クラスの実装 @implementation MyTestClass : NSObject - (void)setMyTestString :(NSString *)testString { myTestString = testString; } - (void)printMyTestString { printf("myTestString is %s \n", [myTestString UTF8String]); } @end // 実行プログラム int main(void) { id myTestClass; myTestClass = [[MyTestClass alloc] init]; [myTestClass setMyTestString:@"aiueo"]; [myTestClass printMyTestString]; return 0; }
細かい話は後にして、まずは上記のコードを先入観抜きでさらっと眺めてみましょう。所々に「おや?」と思う個所があるはずです。ほかの言語との「見た目」の違いはどこでしょうか。
最初に目に付くのは「@(アットマーク)」かもしれません。「@interface」とか「@implementation」とかが目に付きますね。
Objective-CはC言語を拡張することで成立しているので(これについては後ほど説明します)、コンパイラに対して特にObjective-C的な概念や処理方法を明示するために、@で始まる記述が用意されています。これをコンパイラディレクティブと呼びます。
たいていのオブジェクト指向型の言語では、クラスの定義は「class」という予約語で始まります。ところが上記のコードではそういったキーワードが見当たりません。「MyTestClass」がクラス名であることは想像がつくと思いますが、その前に記述されているのは、@で始まるコンパイラディレクティブで、しかも「@xxx クラス名……」という記述が2つも存在します。
Objective-Cでは、クラスの定義にはコンパイラディレクティブを利用します。かつ、クラスの宣言と実装は分けて記述します。「@interface」でクラスを宣言し、そのクラスがどんな変数やメソッドを保持しているかを示します。「@implementation」ではメソッドの具体的な処理内容を実装します。
Objective-Cでは、オブジェクト型の変数を宣言する場合、idという共通のデータ型が利用できます。どんなクラスのオブジェクトでも保存できる便利なデータ型です。もちろん、クラス名を明示してクラス名 *変数名と記述することもできます。
もう1つ、上記のコード中で特徴的な部分があります。[と]で囲まれた部分です。
Objective-Cでは、あるオブジェクトのメソッドを呼び出したいときには、そのオブジェクトに対してメッセージを送ります。そのための記述が、[と]で囲まれた部分で、これはメッセージ式と呼ばれます。
C++やJavaなどでは、メソッドの呼び出しは「オブジェクト.メソッド()」のようにドットでつないで記述されますから、この部分も異質と感じる人は多いかもしれません。
ここまで、コードの「見た目」からObjective-Cの記述上の特徴をいくつか見てみました。
Objective-Cの少し風変わりな記述法は、この言語が、C言語を拡張してオブジェクト指向を実現している言語であるということ、オブジェクト指向のお手本としてSmalltalkという言語を参考にしているということに由来しています。
C++も「C言語を拡張してオブジェクト指向を実現している言語」ですが、C++とObjective-Cでは「拡張」の考え方が少々異なるようです。
言語を拡張するということは、新たな概念やそれに伴うコードの表記方法を導入し、それらを解釈・処理できるようにコンパイラを拡張することが中心となります。例えばオブジェクト指向を取り入れたいのならば、「クラス」などの概念と、それを表現するための表記方法を決め、しかるべくコンパイラを拡張する、といった具合です。
このとき、既存の概念と同等のキーワードとして新たな概念を導入するのか、あるいはコンパイラに対して「これ、ちょっと特殊な処理をしてほしいんだけど……」といった明示的な記述として導入するのか、といった選択が考えられます。C++は前者、Objective-Cは後者ですね。
C++とObjective-Cの名前の違いにも表れているように、前者はより抜本的に言語仕様を改変し、新たな言語として生まれ変わらせる拡張、後者は基となる言語の記述法を保持しつつ拡張機能を明示的に埋め込むことで、言語に新たな側面を付与する拡張、と考えることもできます。
このような違いから、Objective-Cは、基のC言語に対し「マクロ的である」とか「メタ言語的である」などといわれることがあります。先ほど紹介した、コンパイラディレクティブによるクラスの定義などはその代表例で、Objective-Cのコードの最大の特徴ともいえます。
マクロ的な言語拡張の場合、コードの「見た目」の面では、純粋なC言語の世界との境界が明確で分かりやすいというメリットがあります。半面、特殊な表記がコードの中に溶け込まず、なんだかマニアックでとっつきにくく見えてしまう場合もあるかもしれません。
Copyright © ITmedia, Inc. All Rights Reserved.