Javaプログラマーのための衝撃的なObjective-C、パート2

Javaプログラマーを驚かせるObjective-Cの機能の簡単な概要を続けます( 前編 )。 2番目の部分では、言語の哲学、名前空間のサポート、およびidのタイプについて少し説明します。 最初の部分のコメントから判断すると、少し哲学する必要があるので、約束されたプロパティは3番目の部分に転送されます。 また、アメリカのスーパーマーケットでどのような質問がされるのかを調べます。







完璧は、追加するものがないときではなく、奪うものがないときです。





bobermaniacは最初の部分のコメントに正しく記載されているため、構文はそれほど重要ではないため、言語のイディオムを理解することがより重要です。 言語構築の一般原則、その哲学を理解することも同様に重要です。 震え自体は華やかさから来ています。



私は最初にハックニーの引用から始めましたが、C言語のデザインを完全に特徴づけており、可能性を損なうことなく、シンプルさ、表現力、簡潔さなどすべてを特徴づけています。 Cの作成者は人々を信じていました。その結果、コンパイラとプログラマの間の論争では、後者が常に勝ちます(エンドユーザーは常にこれに満足しているわけではありませんが)。 しかし、プログラマーはオブジェクトを操作したいと考えていました。 また、コンパクトな基盤の上に、オブジェクト指向のC列が吊り上げられました。 C ++はこれで最大の成功を収めました。 しかし、正式にはCをベースとして使用しているため、C ++はそのミニマリストの精神に従っていません。 Kernigan-RitchieとStraustrupの厚さの違いは暗示的です。



Brad Coxは、まったく新しい言語を作成せずにSmallTalk機能をCに追加したいと考えていました。 彼は成功し、彼が作成したObjective-CはC言語のスーパーセットであり、オブジェクト拡張でその設計の精神を保持しています。 つまり C言語はそのままで、オブジェクト指向の革新は明確に定義された境界内で行われ、それらの多くはありません。 これはObjective-Cの珍しい構文を部分的に説明していますか? これらの[]と@はすべて、建設区域を囲む黄色いリボンです(または、黄色いリボンは犯罪現場でのみ垂れ下がっていますか?)。 ミニマリズムの典型的な例としては、Objective-Cには、コンストラクターとデストラクターを定義するための特別な構文がないのと同様に、オブジェクトを作成するための特別な構文さえありません。 メソッドalloc、init、new、deallocは、言語の一部ではなく、フレームワークの一部です。



Javaの作成者はわずかに異なるパスを取り、言語のセキュリティに焦点を当て、より厳格な型チェック、配列の範囲外のチェック、必須の処理と例外の指定などを導入しました。 人間への信仰は、魂のないコンパイラへの信仰に置き換えられました。 したがって、Javaプログラマにとって、Objective-CはCと同様に、多くの場合コードセキュリティを損なうほど作成者を制限することを覚えておくことが非常に重要です。 私はメモリ管理についても話していませんが、カテゴリ、コンパイラによってチェックされない例外、非公式のプロトコル、メソッドの存在の保証の欠如などの言語の機能(常にではありませんが、起こります)。 必要に応じて、足元の両手からバーストを撃つことができます。



ここで、Javaプログラマーを注意深く見ながら、いくつかの実際的な問題を考えてみましょう。



IDはありますか?





北米でアルコールを購入するときに、同様の質問を聞くことができます。 これに応じて、年齢データ(通常は運転免許証)を含むIDを表示する必要があります。 質問で「アイデア」を初めて聞いたとき、結果を出さずに6本すべてのビールを飲むことに驚きました。 売り手は慎重にパッケージを引っ張りました。



Objective-Cにはidタイプもあります。これは、任意のクラスのオブジェクトへの普遍的な参照です。 JavaプログラマーがObjectへの参照のようなものだと思った場合、彼は間違っています。 Cプログラマーがvoid *のようだと思った場合、彼は間違っています。 コンパイラは、idをクラスのオブジェクトへの参照と正確に見なします。 任意のクラスの以前に定義されたメソッドを呼び出すことができます(ただし、メソッドが定義されていない場合はできません)、型キャストなしで任意のクラスのオブジェクトを割り当てることができます。 唯一の制限は、オブジェクトのフィールドにアクセスできないことです。



もう一度、前の記事のクラスの構造を思い出します



@interface Profile : NSObject @property (readonly) int version; @end @interface Feature : NSObject - (Profile*) getProfile:(NSString*)name; @end @interface Phone : NSObject + (Phone*) designAndProduce:(NSString*)name; -(Feature*) getFeature:(NSString*)name; @end
      
      







次に、idの使用例をいくつか示します。



 //   id idPtr = [Phone designAndProduce:@"iphone5"]; //    Phone* anotherPhone = idPtr; //    (     ) Feature* badFeature = idPtr; //   -  ,   getFeture      Feature* anotherBadFeature = [idPtr getFeture:@"bt"]; //    Feature* btFeature = [idPtr getFeature:@"bt"]; //   ,  ,   ,   Profile* profile = [idPtr getProfile:@"a2dp"];
      
      







後者の場合、プログラムの起動時にエラーメッセージが表示されます: キャッチされない例外 'NSInvalidArgumentException'によるアプリの終了、理由: '-[Phone getProfile:]:認識されないセレクターがインスタンス0x100114510に送信されました'

メッセージのディスパッチの仕組みについて少し理解を深めます。



プラスチックまたは紙?





アメリカのスーパーマーケットのレジ係からの別の良い質問。 彼らはどのパッケージを提供するかを尋ねますが、初めてだと思う人はほとんどいません。



だから、パッケージについて。 Javaプログラマにとって悪いニュース-パッケージはここにはありません。 名前空間管理メカニズムはまったくありません。 ヘッダーファイルを含めるかどうかのみを選択できます。 CのミニマリズムとObjective-Cの作者の保守主義に感謝します。 名前の競合を避けるため、プレフィックスを推奨します。 たとえば、 NSObjectクラス名の NSは、NeXTのNextStep OS用に開発されたクラスのプレフィックスです。 後者は、Appleで働くこととAppleで働くことの間にSteve Jobsによって設立されました。



Javaとの重要な違いを1つ覚えておく必要があります。 Javaプラットフォームのすべてのクラスは、JVMからアクセスできます。すべてのクラスは、ユーザーがクラスパスおよび/またはlib / extで追加したもの、およびその他のものです。 したがって、名前の競合を避けることは非常に困難です。 Objective-Cプログラムは、コードで使用されるクラスのみを処理するため、競合の可能性は低くなります。 これは、JavaのインポートとObjective-Cの#importのセマンティクスが異なるためです。 最初は名前空間をインポートし、コードで短いクラス名を使用できるようにします。 ただし、クラス自体はそれなしでも使用できます。クラスのフルネーム(つまり、 Listではなくjava.util.List )を記述するだけです。 Objective-Cは実際にクラス定義をインポートしますが、これがないと、コンパイラはこのクラスに関する知識を持ちません。



半分のメジャーが役立つ場合があります - @classディレクティブを使用すると、クラスを定義せずに宣言できます



 @class Profile @interface Feature : NSObject - (Profile*) getProfile:(NSString*)name; @end
      
      







この場合、そのようなクラスが存在し、コードをコンパイルすることに同意することをコンパイラーに保証します。 なぜなら コンパイラはまだクラスの構造について何も知らないため、このクラスのオブジェクトにメッセージを送信するとコンパイルエラーが発生します。 しかし、これは通常必要ありません。なぜなら ディレクティブは、一般的にヘッダーファイルで使用されます。 問題が発生します- #importで取得できるのに、なぜそれが必要なのですか? 通常、大規模プロジェクトでコンパイルを最適化するには、 インポートにより、コードの量が大幅に増加し、それに応じてコンパイル時間が長くなります。 2番目の理由は、クラス間の循環参照です。



おわりに



読んだ後に残された唯一の質問は、アメリカのスーパーマーケットがそれと何をしなければならないかです。 わかりません、そのような小見出しだけが判明しました。



All Articles