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

class or interface ?

投稿者投稿内容
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-08-27 11:08
ども、ほむらです。
元記事で続けるのはすれ違いかなと思いまして
新たにスレッドを立ててみました。
副題:違いのわかる(古w 男を目指して。です
引用については元記事をご覧ください。
---------------
かずくん氏へ
引用:

OOPの3本柱である継承には、実装の継承と仕様に継承の2つが含まれていると考えています。この考えに基づけば、extendsは実装の継承、implementsは仕様の継承に相当します。


オブジェクト指向にはカプセル化・多様化・継承の3つが基本になっていると思いましたが
この3本柱という側面で考えた場合個人的には
interfaceは多様化(ポリモルフィズム?)に属するのではないかなと思っています。
ちなみに、classはカプセル化です。
まぁ、そう考えてしまうとclassに使用するextendsすら
継承に含まれないとも考えられますけれども、classによってカプセル化した機能(操作)を
拡張するという意味で継承だと考えられます。
そして。。。
implementsによって(使用して)、拡張したモジュールを取り込むことによって
カプセル化されたオブジェクトを多様化していくのだと考えています。

#まぁ、なんていうか、仕様の継承=多様化とも取れなくもない
#ただの屁理屈ですが^^;;;;;

Wata氏へ
引用:

もし、インターフェイスAとその骨格実装のAbstractA、
インターフェイスBとその骨格実装のAbstractBがあるときに
A, B両方のインターフェイスを実装したければ、A,Bの両方をimplementsし、
AbstractAまたはAbstractBのどちらかを継承し、
もう一方を内部クラスで実装して転送メソッドを記述すればよいだけです。
ほむらさんがC++でやっていたのもこのスタイルですね。


JAVA用語についてまだまだ勉強中ですのでもう少しお時間をいただくとして、
僕のやっていたことはWata氏の考えているものと同等と思います。
ただ、両方とも継承しない場合も
あったということを一言付け加えさせてください。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-08-27 11:42
引用:

interfaceは多様化(ポリモルフィズム?)に属するのではないかなと思っています。



多態(ポリモルフィズム)はオブジェクトに与えた指示に対して、オブジェクトがそのものの種類に応じて適切な処理を行ってくれるものであり、interfaceはポリモルフィズムには属さないと思います。

引用:

#まぁ、なんていうか、仕様の継承=多様化とも取れなくもない


むしろ、implementsによる多重継承はこのように受け取っています。
いわゆるひとつのMix-inってやつです。

ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-08-27 14:28
ども、ほむらです。
頭固くてごめんなさい(笑
説明が不適切だったのかもしれません。
--------------
引用:
多態(ポリモルフィズム)はオブジェクトに与えた指示に対して、オブジェクトがそのものの種類に応じて適切な処理を行ってくれるものであり、interfaceはポリモルフィズムには属さないと思います


僕の考えではinterface そのものが属するというわけではなくて
implements するという結果を考えた上で属するという言葉を使用させてもらいました。
例えばこんなケースはいかがでしょう。
意味合い的なものなのでコンパイルは通りません^^;;;
コード:
interface INKF
{
 int SHIFT_JIS   = 1;
 int EUC_JP      = 2;
 int Encode(String org, int from);
 String Decode(String org, int to);
}

class JCodeString
{
 private String __text;

 public void   setText(String org);
 public String getText();
 public String EUC2SJIS(String org);
 public String SJIS2EUC(String org);
 public String Convert(int toNKF);
}

class String_SJIS extends JCodeString
 implements INKF
{
 public int Encode(String org, int from);
 public String Decode(String org, int toNKF);
}


こんな形で考えていたので。。。
interface は ポリモルフィズムに属するのではないかなと考えていました。
(実際にはimplementsとあわせて初めて言えることなのかもしれませんが)

この場合 interface内で宣言している Encode(),Decode()をimplementsした
先で多様化しているという説明で表現できるかなとおもいます。

# でもそうするとオーバーライドは微妙な位置になってしまう?(^^;;;
# 個人的にはオーバーライドは多様化ではなく継承に含めたいですね
# オーバーロードならば多様化でもいいかもしれませんが。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-08-27 15:00
内容を少し変更します
コード:

interface INKF
{
int SHIFT_JIS = 1;
int EUC_JP = 2;
int Encode(String org, int from);
String Decode(String org, int to);
}

class JCodeString
{
private String __text;

public void setText(String org);
public String getText();
public String EUC2SJIS(String org);
public String SJIS2EUC(String org);
public String Convert(int toNKF);
}

class String_SJIS extends JCodeString
implements INKF
{
public int Encode(String org, int from) {}
public String Decode(String org, int toNKF) {...}

....
}

class String_EUC_JP extends JCodeString implements INKF {
public int Encode(String org, int from) {...}
public String Decode(String org, int toNKF) {...}
}

public class Main {
public static void main(String[] args) {
INKF inkf;

inkf = new String_SJIS(); // -- (1)
inkf.Encode(...); // String_SJIS.Encode(...)が呼ばれる

inkf = new String_EUC_JP(): // -- (2)
inkf.Encode(...) // String_EUC_JP.Encode(...)が呼ばれる
}
}



上のmainメソッドに書いたように、(1)の代入先の型はINKFだけど、ちゃんとString_SJIS.Encode(...)が呼ばれ、(2)の代入先の型もINKFだけど、ちゃんとString_EUC_JP.Encode(...)が呼ばれる。
このような働きをポリモルフィズム(多態)って言うんじゃないのかな。

# ポリモルフィズムを多様化と訳している時点で、話がかみ合っていないような気がする。

私はオブジェクト指向の専門家じゃないので、あとはもっと詳しい方に議論を委ねます。


[ メッセージ編集済み 編集者: かずくん 編集日時 2003-08-27 15:01 ]
Jun
大ベテラン
会議室デビュー日: 2003/08/25
投稿数: 141
投稿日時: 2003-08-27 15:35
interfaceについて現在のjava では継承というよりむしろ参照といったほうがぴったり
するような気がします.

つまりinterfaceは単に仕様を定義するものでそれをimplementしたclassはその型を持って
いるということに過ぎないといったほうがより現実を正確に言い表していると思います.
それを仕様の継承である などと継承という言葉を使うから混乱するのであって
参照といったほうがよいのでないでしょうか
そういった意味でabstract class とは異なっているのでしょう

そのことの証拠としてinterfaceの中で定義されているネストしたクラスをimplement
したclassから使用するときはinterface名での修飾が必要となります.
これは多重継承していてあいまいさが生じる場合以外でも必要ですから結局
interfaceとそれをimplementしたクラスは継承関係に無いということになりませんか?
つまりimplementはinterfaceで宣言されたものと同じインターフェースを持つといって
いるに過ぎず継承関係ではありえないと思うのです.
従ってそれは一見publicである必要があるように見えます
(特にネストしたクラスやデータ属性の場合)

しかしそうであればinterfaceは仕様を定義するだけということになりますからアクセス修飾子は何であってもよいはずです
すると少なくともメソッドについてはpublic以外があっても不思議はないということに
なるでしょう.
こう考えると, ではデータ属性についてはむしろ継承と考えたほうが現実にあっている
ではということをいわれそうですが, これはまさにそのとおりです.

つまり今のjavaの仕様ではこの辺に矛盾がありもう少し整理されて良いのでないか
という気がします.
ただimplementsを継承と考えるにしろ参照と考えるにしろpublicでないメソッドを
禁止する理由にはなりません.
参照の場合はpublicでないメソッドの実在を要求するものとして,
継承の場合はむしろ当たり前のこととしてpublicでないメソッドを考えればよいのです.

それにすべてpublicに限るのなら元々interfaceのデータ属性やメソッドにpublicという
キーワードは不要なはずですよね.それならアクセス修飾子をつけないことにしたほうが
すっきりするはずです.

だからこれは今はたまたまpublic以外のものが言語仕様として組み込まれていないだけだ
というように思ってしまいます.

ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-08-27 16:49
ほむらです。
お付き合いいただきありがとうございます。
------------------
かずくん氏へ
引用:

上のmainメソッドに書いたように、(1)の代入先の型はINKFだけど、ちゃんとString_SJIS.Encode(...)が呼ばれ、(2)の代入先の型もINKFだけど、ちゃんとString_EUC_JP.Encode(...)が呼ばれる。
このような働きをポリモルフィズム(多態)って言うんじゃないのかな。


もしかして思っていることは同じなのでしょうか。。。こういう動作があるからこそ
>interfaceは多様化(ポリモルフィズム?)に属するのではないかなと思っています。
などという考えが生まれてきています。

しかし、
引用:
# ポリモルフィズムを多様化と訳している時点で、話がかみ合っていないような気がする。


とあるように僕自身、多態化と多様化の違いがわかっていません。
それと、interfaceでMainにあるような使い方が出来るという
ことも今回始めて知りました。(もしかしてC++でも出来たのかな?(笑 )

僕の勉強不足が浮き彫りになっている感じです(汗
もっと勉強してきます。ありがとうございました。

Jun氏へ
引用:

しかしそうであればinterfaceは仕様を定義するだけということになりますからアクセス修飾子は何であってもよいはずです
すると少なくともメソッドについてはpublic以外があっても不思議はないということに
なるでしょう.


前スレで、誰かが言っていましたが。たとえば、
interfaceのメソッドにprotected等 隠蔽できる仕様が追加されたとして
一体誰が使用するのでしょうか?

かずくん氏のサンプルにみるinterfaceの使い方について、かなり有効な方法と
思いますがあのサンプルにprotectedのメソッドが追加されたとして
誰がアクセスできるのでしょうか?

そして、現在の仕様同様使用できないものとして
同じ物を作った場合にどんなメリット/デメリットがうまれますか?

僕としては共通定義として存在しているのにアクセスできない。
そういった仕様の方が複雑なように思えます。
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-08-27 16:53
つっこみばかりですいません・・・

引用:

そのことの証拠としてinterfaceの中で定義されているネストしたクラスを
implementしたclassから使用するときはinterface名での修飾が必要となります.
これは多重継承していてあいまいさが生じる場合以外でも必要ですから結局
interfaceとそれをimplementしたクラスは継承関係に無いということになりませんか?


サブクラスがスーパークラスのネストされたクラスを修飾無しで使えるのが、
オブジェクト指向でいう「継承」に当たるんですかね?
ネストしたクラスはスーパークラスの特徴(属性&操作)では無いですよね?

ネストしたクラスと継承は分けて考えるべきでは。
(「Interfaceでは修飾が必要で、Classでは必要では無い」理由はこれから考えてみます・・・)
[追記]
Interfaceでも必要ないですね...

引用:

それにすべてpublicに限るのなら元々interfaceのデータ属性やメソッドに
publicというキーワードは不要なはずですよね.
それならアクセス修飾子をつけないことにしたほうがすっきりするはずです


interfaceのアクセス修飾子は不要ですが・・・
(付けても付けなくてもコンパイルは通りますが)

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-09-02 10:35 ]
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2003-08-27 16:53
>しかしそうであればinterfaceは仕様を定義するだけということになりますからアクセス修飾子は何であってもよいはずです

なりません。「仕様」という言葉を恣意的に使いすぎです。OOの文脈では「仕様」は「型」
とも「プロトコル」とも言い換えができますが、ようするにオブジェクトの外部仕様を
定義したものです。ですから、

>すると少なくともメソッドについてはpublic以外があっても不思議はないということに
なるでしょう.

public以外のものがあったらおかしいでしょう。

>こう考えると, ではデータ属性についてはむしろ継承と考えたほうが現実にあっている
ではということをいわれそうですが, これはまさにそのとおりです.

データ属性ってなんですか?

>ただimplementsを継承と考えるにしろ参照と考えるにしろpublicでないメソッドを
禁止する理由にはなりません.
参照の場合はpublicでないメソッドの実在を要求するものとして,
継承の場合はむしろ当たり前のこととしてpublicでないメソッドを考えればよいのです.

すいません、この辺まったく意味がわからないです。

>それにすべてpublicに限るのなら元々interfaceのデータ属性やメソッドにpublicという
キーワードは不要なはずですよね.それならアクセス修飾子をつけないことにしたほうが
すっきりするはずです.

interfaceの定義ではpublicキーワードは省略可能ですよね。そうでなくても十分すっきり
していると思いますが。

>だからこれは今はたまたまpublic以外のものが言語仕様として組み込まれていないだけだ
というように思ってしまいます.

結論が強引過ぎませんか?

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