[ Eiffel Liberty | GUERL | sOOap ]


[ 目次 ] [ イントロ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Copyright ] [ html (full) | ps | pdf ]

[Logo-Eiffel:Advance Intro]

Eiffel: 一歩進んだ入門

by

Alan A. Snyder
and
Brian N. Vetter

2章:

継承、オブジェクトの利用、クライアントとサプライア

2 - 継承、オブジェクトの利用、クライアントとサプライア
    2.1 他のクラスから継承する
    2.2 オブジェクトを利用する - ドット (.)演算子
    2.3 クライアントとサプライア
    2.4 公開状態
        2.4.1 多重公開

2.1 他のクラスから継承する

 Eiffel は、オブジェクト指向の言語であるので、継承の機構をサポートしています。特に、多重継承は、完全にサポートしています。クラスは、一つ以上の親クラスから特徴を継承することもでき、それをクラス定義のinherit 句で宣言します。次の例は、Eiffel の継承の構文を示しています。

  
   class  CHILD  
      inherit  
         PARENT_1;  
         PARENT_2;  
  
      feature  
         ...  - CHILD自体の特徴
   end --CHILD

 ここで、クラス CHILD は、PARENT_1PARENT_2 から継承しています。この二つのクラスから継承したどの特徴も、CHILD で定義される特徴に加えて、クラス CHILD の一部になります。同じ名前を持つ特徴を PARENT_1PARENT_2 から継承したときに、問題が起きることもあります。継承でありうる曖昧さは、選択、再定義、名称変更、そして定義の取消を通じて、すべて解決することができます。これらの話題は、「継承と特徴の適応」という題の付いた5章で詳細に扱うことにします。

2.2 オブジェクトを利用する - ドット(.)演算子

 ひとたびオブジェクトを生成したならば、ルーチンを呼び出すため、あるいは属性へアクセスするために、ドット(.)演算子を使用します。オブジェクトの型(参照型か拡張型か)に関わらず、ドット演算子は、首尾一貫して使用されます。伝統的な言語は、拡張型(あるいは等価なもの)のためにはドット演算子を、参照型(あるいは等価なもの)には別の演算子(^. あるいは->)を明示的に使用するように要求し、このことは、もし拡張型から参照型、あるいはその逆へ切り替えることを決定したならば、それを変更するためにかなりの時間を費やすこともあります。Eiffel でのドット演算子の一貫した使用は、プログラムの書き易さと、実装の詳細というよりは概念の可読性と理解容易性の両方にとって、利益溢れる特徴です。

 いま、私たちは、ドット演算子の使用をより詳しく記述するために、次の例を提示します。

   c : CONVERTER;  
   !!c.make();  
   c.SetValue(32);

 ここで、生成演算子(!!)は、生成ルーチン make を呼び出して、c を型 CONVERTER のオブジェクトとして生成し初期化します。それから、 set_temperature は、実際の INTEGER のパラメータによって記述したように、c の temperature という特徴を 32 へ設定します。ドット演算子は、set_temperature を CONVERTER の特定の実例、ここでは c 、へ関連付けます。その時存在するかもしれない、他のどの CONVERTER も、影響を受けないままです。

2.3 クライアントとサプライア

 上記の2.1節で記述した継承の関係は、'is-a'(「の一種である」)関係として知られています。実例として、 CAR(車) は、VEHICLE(乗り物)「である」(CAR は、VEHICLE から継承する)、あるいは、PEN(ペン)は、WRITING_IMPLEMENT(書く道具)「である」(PEN は、WRITING_IMPLEMENT から継承する)。

 オブジェクト指向のパラダイムにおける(オブジェクト間に)存在する他の関係は、集合体<aggregation>で記述する、'has-a'(を持つ) 関係です。たとえば、PERSON(人)は、HEAD(頭)「を持つ」とか、あるいは、DIGITAL_CLOCK(デジタル時計)は、DISPLAY(表示器)「を持つ」とかです。Eiffel では、'has-a' 関係は、特定のクラスにおいて、特徴の一つが属性であると記すことによって単純に実装されます。

   class DIGITAL_CLOCK
   feature
      display : DISPLAY;
   ...  
   end -- DIGITAL_CLOCK

 ここで、DIGITAL_CLOCK は、その表示の特徴を通じて DISPLAY を使用しているので、DIGITAL_CLOCKDISPLAY のクライアントであるということができます。反対に、DISPLAY は、DIGITAL_CLOCK のサプライアになります。この頭の中にある単純な概念を用いて、私たちは、あなたを、特徴の公開<export>状態に関する次の節へ導きます。

2.4 公開状態

 私たちがどんなクライアントにもクラスの特徴をすべて使用することを許そうと望まない時もあります。あるクライアントは、利用可能な特徴のすべてを使用できるべきであり、他のクライアントは、いくつかの選択されたものだけを使用できるべきです。Eiffel では、私たちは、どのクライアントに、どの特徴へのアクセスを(ドット(.)演算子経由で)許すかを記述することもできます。このことは、下記のように、選択可能な公開状態<export status>の機構を用いて達成します。

   class ACCOUNT  
   feature  
      balance : INTEGER;  
      ...  
   end --ACCOUNT

 私たちは、もしこのクラスを成り立たせようとすべきであったならば、私たちが望むようにペナルティ無しで、balance の特徴を変更できたでしょう。このことが意味するのは、私たちは百万ドルの値を保持するように balance を設定できたであろうが、(多分、口座を保持する銀行を除いて)誰もこの事実を議論しないであろう、ということです。

 私たちは、私たちが誰も直接 balance へアクセスできることを望んでいない、ということを記す方法を必要としています。このことは、次のように行えます。

  
   class ACCOUNT  
   feature {NONE}  
      balance : INTEGER;  
      ...  
   end --ACCOUNT

 いま、balance が NONE クラスだけへ公開されているので、どのクラスも balance をアクセスできません。どのオブジェクトも型 NONE で実例を作成できないので、どのオブジェクトも決して balance を使用できないことになります。feature という予約語の後に現れる {NONE} は、続く特徴のすべてが型 NONE であるオブジェクトに対して利用できる、ということを述べています。

 このことは、この場合にとって、あまり制限的であるようには見えません。銀行が、deposit あるいは withdrawal を作るために、あなたの balance をアクセスする必要がありました。 この場合、私たちは、次のように、balance という特徴をクラス BANK へ公開できます。

   class ACCOUNT  
   feature {BANK}  
      balance : INTEGER;  
      ...  
   end --ACCOUNT

 上記で、クラス BANK であると宣言したクライアント、あるいは BANK から継承する ACCOUNT のクライアントだけが、直接 balance をアクセスしてよいのです。balance のこの制限的な公開は、「信用」しうるクラスにだけ、balance を使用することを可能とします。私たちは、balance をどれかだけに公開しないのではないが、あらゆるものに balance への自由なアクセスを持たせることを望みません。

 この宣言に基づいて、次のように書くこともできます。

   class BANK
   feature  
      presidential_account : ACCOUNT
      ...  
      deposit (amount : INTEGER) is  
      do  
         presidential_account := presidential_account + amount;  
      end -- deposit
   end -- BANK

 次のものは、書いてはならないことを示すことになります。ROBBERSACCOUNT のクライアントであり、その特徴 balance が型 ROBBERS のクライアントへ公開されていないので、次のものは許されないでしょう。

  
   class ROBBERS  
   feature  
      hacking_account : ACCOUNT
      ...  
      wipe_account is  
      do  
         hacking_account.balance := 0; -- 違法 !!  
      end -- wipe_account
   end

 あるクラスの一つの特徴あるいは特徴の集合にアクセスできるということを選択的に宣言する能力は、選択的公開と呼ばれます。Eiffel は、特徴を選択的に公開するための、あるいは特徴をグループ化するための構文を学習し思い出すための容易さを提供します。

2.4.1 多重公開

 私たちの ACCOUNT の balance という特徴を単一のクラスだけに公開する代わりに、私たちは、クラスのグループがこの特徴をアクセスできるように望むこともできます。この場合に、私たちは、次のように、balance をクライアントのグループへ公開できます。

  
   class ACCOUNT  

   feature {BANK, IRS}  
      balance : INTEGER;  
      ...  
   end --ACCOUNT

 いま、もし BANK または IRS のオブジェクトが ACCOUNT のクライアントであるならば、それらは、balance という特徴へのアクセス権を持つことになります。つまり、次のようにです。

   class IRS  

   feature  

      your_account : ACCOUNT;

      check_for_fraud is  
         do  
            if your_account.balance > 1000000 then  
               schedule_audit;  
            end;  
         end; -- check_for_fraud

   end --IRS

 IRS というクラスは、balance を公開するクライアントとして並べられているので、上記の IRS クラスは、合法的です。IRS は、それが適していると思えるように、your_account 内の balance を変更することを許されています。それで、他のクラスへの属性となる特徴を公開するときには、注意しなければなりません。信用は、IRS が balance という特徴に破壊的に干渉しないであろうといった、クライアントのクラス、ここでは IRS、に教え込まなければなりません(はい、IRS における信用は、信じがたいものですが、ときには必要です!)。

[Logo-Eiffel:Advance Intro]

[ 目次 ] [ イントロ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Copyright ] [ html (full) | ps | pdf ]

[ Eiffel Liberty | GUERL | sOOap ]


Page is http://www.elj.com/eiffel/intro/s2/
Date : 21 Nov 97