- PR -

特集「私がJavaからC#に乗り換えた10の理由」について

投稿者投稿内容
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-18 13:26
引用:

yaさんの書き込み (2003-07-18 02:31) より:
>>英-Ranさん
やっとすれ違いがわかりました(と思います)。
私は、個人的には委譲(実装責任を他者に渡すこと?ですか?)という概念(もちろん既にあるものです)にからめた理論展開ができていなかったようです。



読み返してみると、もしかしてyaさんは誤解しているのかも……とか思い始めてきたので、申し訳ないんですが以前示した二つについてyaさんなりの回答を示してはいただけませんか。
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2003-07-18 14:35
少しだけ本題からずれます^^;

コード:
typedef void (ClassA::*Func)();
Func methodPtr = &ClassA::Foo;
ClassA aObj;
(aObj.*methodPtr)();



C++におけるメンバへのポインタの使用例です。
以前、上記とtemplateを組み合わせてdelegateっぽいことを
実現しているのをみたことがあったような…
いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2003-07-18 15:01
無名インナークラスと、delegate
結局のところ、両者が目指すのは、匿名を扱いたいケースってことですよね。

私の感覚では、匿名っていうのは、本来厳しい制限があるものを緩和して認めるって
意味で匿名という言葉を使っています・・・。

C#は入口を緩和する。(インターフェイスより緩和した制限方法delegate)
javaは 偽装する ってところかなあ。(必要最低限のインターフェイスに合わせる)

interface IObserver
{
void Update();
}


delegate は クラスの型を要求せず(この時点でクラスの型については匿名 つまりなんでもいいよと)、メソッドのシグネチャ(というより名前もなんでもいいので、引数の組み合わせ)だけの一致を求めている。(まあその際、delegateという型は要求しているのですが。。)


java は クラスを無名にすることで、あるインターフェイスを実装した一時的なクラスを
作成して、インターフェイスを要求するメソッドに渡している。(クラスを匿名化している)


このとき、果たして インターフェイスを要求する側のメソッドは
本当にインターフェイス(型)までが必要だったのか、Update() というメソッド名でなければならなかったのか?
 ってところです。

必要であればそれでかまわないわけですが、
 このメソッドは単に「インターフェイスで定義したシグネチャが保証されたメソッドを
呼びたかっただけ」で、 厳密なインターフェイスで定義された型が本当に必要なわけでは
ない場合はどうでしょう。

インターフェイスを要求したメソッドは、(本来は不必要な部分まで求めた)贅沢な要求をしているように見えます。

と概念を結び付けようとするとこじつけているようにも見えるし、
なくても済むでしょ といわれると たしかにそのとおり。
無くても他に方法はあるし、概念でdelegateを使うかどうか
を判断するのは、逆にしんどいかも。(思考停止してしまったか・・)


でも便利。だからあるものは使えってところが本音ですが・・(^^:
java も delegate というキーワードこそ使わないだろうけど
generics が導入されたら delegate風な役割のテンプレートとかが登場して、結局あの議論はなんだったんだろう〜 ってことはなりません?ならないか。。
リフレクションとかと組み合わせればできそうですが・・。
(javaのリフレクション機能は知りません。NETと大体同じかなあとの想像です)


delegateというキーワードが言語機能に取り入れられていることは否定されていますが、
結局だれもdelegate で実現できる機能自身は全否定されていないようですし。

未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-18 16:43
的外れな意見でしたらなんですが・・・。
inner class で扱う変数やメソッドはすぐ外側クラスは別として、他のクラスからは
同じ手続きでは参照できないところが特長ではないかと思ってます。
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2003-07-18 17:49
Ken-Lab様の意見からもう少しインナークラスを勉強してみました。
で、下記のページを参考にしたのですが、

http://www.applitips.com/java/kiso/innerclass.htm
http://www.applitips.com/java/kiso/innerclass2.htm

インナークラスに対する理解を根本的に間違ってました。
インナークラスは外側クラスのインスタンスへの参照を隠しもっているのですね。
(C++などのネストクラスとは根本的に別物、と)

・インナークラスインスタンスは、外側クラスインスタンスへの参照とメソッドを持つ
・delegateインスタンスは、何らかのクラスのインスタンスへの参照とメソッドへの参照を持つ

似ているところもありますけど、でも使われるパターンを考えるとぜんぜん
別物のような気もします。(もう少し整理しないと^^;)

追記:
 ランキングをみて思ったのですが、「プレゼント当選の喜びのスレ」を
 超えたみたいですね^^;
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-18 19:56
う〜ん、実はinner classとdelegateの関係までは良くわからないです。
というのは私がdelegateを理解していないんで比較できないというのが本音でして。
恐らく英-Ran氏でしたら何らかのお答えをお持ちではないかと思います。
それから、inner classをうまく操縦すればプロパティと同じ意味を持たせられると思ったり

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-07-18 19:57 ]
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-07-19 00:16
meiです。

遙か昔に買ったままだったJava入門書をひっくり返しています(笑)。
で、innerクラスについて見てみたんですが・・・

// ネストクラス
class Outer {
class Inner implements MyInterface {
public void MyMethod() {
// Outerのメンバにアクセス出来る
}
}

public MyInterface getInterface() {
return new Inner();
}
}

// 別なクラス
class Other {
public void Method(MyInterface mi) {
// Other -> Inner -> Outer
mi.MyMethod();
}
}

↑innerクラスでの委譲ってこんな感じでしょうか?


innerクラスの外側のクラスへの参照を持っているクラスなので、
Iteratorとかの実装に便利そうですね。

ちょっと話はそれますが、
このネストされたクラスというのが馴染めないかも。
オブジェクトがネストになるのは分かるのですが、
型がネストになるのがどういうことなのか、イメージがわかなくて(汗)。
名前空間の保護ならそれこそnamespaceを使えば良いし・・・


例えば自動車というクラスが作るとして、
class 自動車 {
class タイヤ {
}
}
みたいな型は作らないだろうし。
オブジェクト指向設計ではネストクラスって、
どんなところで使われるのかしら。
#識者の方よろしく(笑)
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-19 00:28
引用:

恐らく英-Ran氏でしたら何らかのお答えをお持ちではないかと思います。



自分なりの帰結はもっていますが、今の段階で言ってもJava信者の戯言だと思われるのが落ちだろうと思っているので、ちょっとだけ黙っていようかと思います。

とりあえず、Ken-Labさんの持っている疑問は、「「委譲」の目的は何か 」はということさえわかればすぐに解決します。

別に難しいことを言うつもりはなくて、私の答えは「(データではなく)処理を受け渡し実行してもらうこと」というものです(当たり前の回答だと思うけれど異論あります?)

# yaさんの「実装責任を他者に渡すこと」というのは、意図はわかりますがそれでは
# interfaceになってしまう

とはいえ、処理を実行できるのは当たり前なので重要なのは「処理を受け渡すこと」です。当然、この目的を満たすものはすべてdelegate(=委譲)として見ることができますし、言語にそのような機能を入れようと思うならば、それらの中から選ぶことになります。「C#のdelegate」、「メソッドオブジェクト」、「関数ポインタ」といったものは、まさにこの目的のために用意されています(逆に言えば、もしプログラミングにおいて「処理を受け渡す」という目的がなければ、これらの機能は必要がないかもしれない)。

で、ここで忘れがちなのがオブジェクト指向言語におけるオブジェクトが「データと処理の塊」であるということです。C言語では関数ポインタがなければ委譲を実現できませんが、オブジェクト指向言語でのオブジェクトは本来備わった性質として委譲を実現できます(「オブジェクト指向における再利用のためのデザインパターン」にも多数のデザインパターンが委譲により実現されているときちんと書かれています)。

ここまでわかれば、「C#のdelegate」も「メソッドオブジェクト」も「無名InnerClass」も単なるクラスも「委譲」という同じことを実現するための仕組みとして比較可能であることがわかります。

# うーむ、いまいち説明がうまくないかも。疑問や反論があったらきいとくれ

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