@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

interface のメソッドは、なぜ protected にできないのでしょうか?

投稿者投稿内容
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-07-22 23:02
JavaHouseに辿り着いた時点で、僕の役目は終わりかと思いますが、一応

引用:

unibonさんの書き込み (2003-07-22 16:49)
#レレレのおじさんが頭の中でうごめいています。




原因はinterfaceを「(一般的な意味での)公開インターフェース」
 という使い方のみで捉えているからでは無いでしょうか?
interfaceには「役割(又は責務)」という使い方もあります。
 (java.io.Serializableが典型的な例)
先ほど例では後者の使い方をしてます。

http://java-house.jp/ml/archive/j-h-b/007424.html#bodyより
引用:

> ・継承によってもたらされるポリモフィズムは、
>  XXの一種(is Kind of)という抽象化メカニズムを提供する。
>
> ・interfaceよってもたらされるポリモフィズムは、責任を保有する
>  (has a responsibility) という抽象化メカニズムを提供する。



上記の説明を「掃除係」に当てはめて、class(abstract class)と
interfaceで表した場合を比較します。

A.山田君 extends 掃除係(掃除係がclassの場合)
訳:山田君は「掃除係」の一種です。

B.山田君 implements 掃除係(掃除係がinterfaceの場合)
訳:山田君は「掃除係」という責任を保有します。

AとBではまったく違う意味ですよね?
ゆえにinterfaceとclassは明確に区別されるべきと考えます。


interfaceが「役割(又は責務)」を表すという考え方に、
否定的な意見があるっていうのは今回は無しで・・・

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-07-22 23:04 ]

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-07-23 00:04 ]
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-07-23 01:40
yamasaです。

# 私の言いたいことは、ほとんど他の方におっしゃって頂いているので手短に…

>unibonさん
abstract class と interface の表記や挙動がよく似ているのは
あくまで表面的な話で、根底にある考え方は大きく異なっていると思います。

少なくとも私は、(abstract) class や interface を設計するときに
以下のような方針で考えています。

(abstract) class : どういうモノなのか?
interface : どういうコトができるのか?

ですから、interface には「できること(=publicメソッド)」だけ
定義できれば十分であると考えています。
cats
大ベテラン
会議室デビュー日: 2002/11/29
投稿数: 221
お住まい・勤務地: 東京
投稿日時: 2003-07-23 09:31
参考までに

JavaではなくてC#では、unibonさんのやりたいことに近いことができます。
コード:
interface I1
{
  void f();
}

class C1 : I1
{
  void I1.f(){} // (1)
  protected void f(){} // (2)
}

  C1 c1 = new C1();
  I1 i1 = c1;
  c1.f(); // (2) 派生クラスのみアクセス可
  i1.f(); // (1)


unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-07-23 14:32
unibon です。こん○○○。

#以下、interface と class の類似性の有無について触れ、
#protected については触れていません(単に話の単純化のため)。

引用:

ぽんさんの書き込み (2003-07-22 23:02) より:
http://java-house.jp/ml/archive/j-h-b/007424.html#bodyより
引用:

> ・継承によってもたらされるポリモフィズムは、
>  XXの一種(is Kind of)という抽象化メカニズムを提供する。
>
> ・interfaceよってもたらされるポリモフィズムは、責任を保有する
>  (has a responsibility) という抽象化メカニズムを提供する。




同じ著者つながりで、@IT にも連載がありました。
http://www.atmarkit.co.jp/fjava/devs/renew_uml05/renew_uml05.html

引用:

ぽんさんの書き込み (2003-07-22 23:02) より:
上記の説明を「掃除係」に当てはめて、class(abstract class)と
interfaceで表した場合を比較します。

A.山田君 extends 掃除係(掃除係がclassの場合)
訳:山田君は「掃除係」の一種です。

B.山田君 implements 掃除係(掃除係がinterfaceの場合)
訳:山田君は「掃除係」という責任を保有します。

AとBではまったく違う意味ですよね?
ゆえにinterfaceとclassは明確に区別されるべきと考えます。


すみません。正直なところ、
私は、A の山田君と B の山田君の違いがよく分からないです。
(掃除係と別に給食係も加えると良いのでしょうか、
とも自分では思っているのですが、よく分かりません。)
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-07-23 18:43
引用:

unibonさんの書き込み (2003-07-23 14:32) より:

(掃除係と別に給食係も加えると良いのでしょうか、
とも自分では思っているのですが、よく分かりません。)



前回の例に「トイレ掃除係 extends 掃除係」を加えて、
A.山田君とB.山田君を比べてみました。

A.山田君≒A.トイレ掃除係
A.トイレ掃除係≠B.山田君
ゆえにA.山田君≠B.山田君である。

余計分りにくいですかね・・・

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-07-23 18:47 ]

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-07-23 22:48 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-08-09 11:55
unibon です。こん○○○。
#古いスレッドですが。

みなさま、ありがとうございます。
いろいろと教えていただいて自分なりに考えをまとめたものを以下に書きます。
#まず最初に、このスレッドの最初の疑問であった protected に付いて触れ、
#次に、class と interface の類似性の有無について触れます。

interface の生い立ちは、
多重継承(とくに菱形継承)に対する、便宜的で簡潔な回避手段であると、
Java の教科書の類によく書いてあることに気づきました
#ある資料にこういう文言で書いてあったわけではなく、
#私がこう解釈したという意味ですが(以下も同様)。

そのため interface は、きわめて簡素な構造に抑えてあり、
結局は、メソッド名のテーブル(一覧表)でしかなく、
そう考えると、そのテーブルに含まれるメソッドのアクセス修飾には、
あまり重要度がないのはうなずけます。
とくに、つぎのような菱形継承のコードだと、

コード:
interface Foo {
    void bar();
}

interface SubA extends Foo {
    void bar();
}

interface SubB extends Foo {
    void bar();
}

interface SubSub extends SubA, SubB {
    void bar();
}


この場合、interface 本来の仕様ならば、
たんなるメソッド名のテーブルでしかないため、あいまいさは生じませんが、
もしも SubA と SubB それぞれが持つ bar メソッド個別に
アクセス修飾(public/protected/private)を持たせると、
SubSub の bar は、SubA の bar に由来するのか、SubB の bar に由来するのか、
といった解決をおこなう必要が出てきて、これは多重継承の問題になると思います。
だから、そういう面倒を避けるためにも interface のメソッドには、
アクセス修飾ができないのだと理解しました。
もちろん、多重継承の問題をなんらかの方法で解決すれば
interface のメソッドを protected にしたりもできるのかもしれませんが、
そこまでいじるとそもそも interface の存在理由がなくなってしまいますので、
無意味ですよね。

次に、class と interface の類似性の有無についてですが、
そもそも上述のように interface の生い立ちから考えると、
interface は class からメソッドの解決の機能を取り除いているわけなので、
そう考えると、class のメソッドと interface のメソッドの取り扱いは
違うと言えます。
interface のメソッドは、
単にメソッド名の文字列で振り分けられて呼ばれるためのエントリでしかなく、
interface のメソッドは class で実装してはじめて一人前になる、
と思います。なお、実装(メソッド内にコードを書くかどうか)が重要ではなく、
class にバインドされたメソッドであるかどうかが大事だと感じます。
#「バインド」という言葉があいまいですが。

ただ、上記ではメソッドレベルの話を書きましたが、
型(type)の空間では class と interface は共有しますので、
型のレベルでは class と interface は
類似というか同一であることには変わりないと思っています。
お犬様
ベテラン
会議室デビュー日: 2003/01/26
投稿数: 67
投稿日時: 2003-08-10 12:15
引用:
unibonさんの書き込み (2003-08-09 11:55) より:

この場合、interface 本来の仕様ならば、たんなるメソッド名のテーブルでしかないため、あいまいさは生じませんが、もしも SubA と SubB それぞれが持つ bar メソッド個別にアクセス修飾(public/protected/private)を持たせると、SubSub の bar は、SubA の bar に由来するのか、SubB の bar に由来するのか、といった解決をおこなう必要が出てきて、これは多重継承の問題になると思います。

仮に、interface のメンバに public 以外のアクセス修飾子を許した場合であっても、どのような記述をすれば「多重継承の問題」が発生するのか理解できません。上位クラスや上位インターフェイスより緩いアクセス規制を許す、などの変更を行えば問題を発生させられるかもしれませんが…
Jun
大ベテラン
会議室デビュー日: 2003/08/25
投稿数: 141
投稿日時: 2003-08-25 14:10
初めて投稿します.
まだ java は初心者ですが, unibon さんとほぼ同じと思われる疑問について
投稿しましたところ, ここを紹介していただいたので便乗させてもらいます.

きっかけはコールバックルーチンに相当するものをprotectedなメソッドにして
多態性を利用して実現していたものにダイヤモンド継承の問題が生じたため
それを解決するためインタフェースを定義しようとしたことにあります.
いくつかのタイプのインターフェースを定義しようとしたのですが, ある
インターフェースは他のインターフェースとの違いはこのprotected なメソッド
だけでした.
したがってこのインターフェースではprotected なメソッド一つを定義すれば
良いのですが, ご存知のようにこれはコンパイルエラーとなります.

これに関してこれまでここでいろいろ議論がなされているようですが
それは別として言語としてこのような仕様とすることで解決するのではないか
という私の考えを述べてみたいと思います.(簡単のためメソッドについての話に
限定することにします. 本当はネストしたクラスなども含めるべきですが)
もちろんVMの互換性とかそういうものは考えないでの話です.

メソッドのアクセス修飾として以下のものを考える

1.private
クラスにおけるprivate:
 定義してあるクラス以外からはアクセスできず, 派生したクラスではオーバーライド
 されず, 隠蔽される.
インターフェースにおけるprivate:
 インターフェースを継承するabstractでない最下層のクラス(複数ありうる)と
 インターフェースの間のいずれか実装が可能なクラスでのみアクセスされる.
 アクセスされるクラスから派生するクラスではオーバーライドされず隠蔽される.
派生する具象クラスの祖先のどこかのクラスで必ず実装される.
2.protected private
 privateと同様であるが, 隠蔽されずオーバーライドされる.
3.その他(protected, private protected, public, 省略時)
クラスにおけるもの:
 通常のもの.(今の1.4ではprivate protectedはエラーですが)
インターフェースにおけるもの:
 1と同様に具象クラスの祖先のどこかで実装される.アクセス,オーバーライドに
 ついてはクラスにおけると同様.

インターフェースでのメソッドはそのインターフェースがあることを定義するもので
公開かどうかというのは本質的とは思えないのですが

スキルアップ/キャリアアップ(JOB@IT)