47

折れ線グラフをレンダリングするクラスがあります。これを LineGraph と呼びましょう。サブクラス化する必要がありますが、派生クラスは 1 か所でのみ使用され、それを使用するクラスに結合されています。だから私は内部クラスを使用しています。

これを行うには2つの方法があります。

匿名の内部クラス

public class Gui {
    LineGraph graph = new LineGraph() {
        // extra functionality here.
    };
}

名前付き内部クラス

public class Gui {
    MyLineGraph graph = new MyLineGraph();

    private class MyLineGraph extends LineGraph {
        // extra functionality here.
    }
}

私は匿名の内部クラスのファンではありません。率直に言って、それは本当に醜いと思うからです。しかし、1 つの場所でしか使用されないサブクラスの場合、名前付き内部クラスはやり過ぎでしょうか? 受け入れられている慣行は何ですか?

4

15 に答える 15

53

匿名内部クラスの利点の 1 つは、名前付き内部クラスを使用できるのに対し、名前付き内部クラスを使用できることです (非公開にすると、それを作成したクラスだけが使用できます)。小さな違いですが、内部クラスが他の場所で誤って使用されるのを防ぐことができるということです。

また、匿名の内部クラスを使用すると、コードを読んでいる人に「このクラスはここだけで使用されており、他の場所では使用されていません」という警告が表示されます。名前付き内部クラスが表示された場合、クラス内の複数の場所で使用されていると考える人がいるかもしれません。

それらは非常に似ているため、どちらの点もゲームチェンジャーではありません. 1回限りの匿名内部クラスを使用し、クラス内で複数回使用される場合は名前付き内部クラスを使用すると、明確にするのに役立つと思います。

于 2009-04-03T16:12:17.837 に答える
38

(ダニエル・リューへの反論)

匿名内部クラスの欠点の 1 つは、名前付き内部クラスを使用できるのに対し、名前付き内部クラスを使用できることです (非公開にすると、それを作成したクラスだけが使用できます)。これは小さな違いですが、内部クラスが別の場所で誤って再作成されないようにするのに役立つことを意味します。

また、匿名の内部クラスを使用すると、どこからともなく出てきたこのクラスを解析する必要があるため、コードを読むのが難しくなります。名前付き内部クラスを使用すると、ソースをさらに整理できます。

まったく同じコードを持つ 2 つ (またはそれ以上) の匿名内部クラスが存在するケースを見てきました。特に GUI (同じアクションを実行する複数のコントロールがある場合) では、これが発生する可能性があります (学生が書いたコードではなく、プロダクション コードについて話しているのです)。

可読性の問題は双方向に起こります。匿名の内部クラスの方が、一度に何が起こっているかを確認できるため、より良いと考える人もいれば、気を散らすものだと考える人もいます。その部分は個人の好みに帰着します。

また、クラスを静的にすることはより効率的です。インスタンスで匿名の内部クラスを宣言している場合は、より多くのオーバーヘッドが発生します。インスタンス変数へのアクセスが必要ない場合、これは無駄です (しかし、おそらく心配する必要はありません)。問題が発生するまで)。

私の個人的な好みは、コードが後で変更されたときに柔軟性が増すため、非匿名クラスを使用することです。

于 2009-04-03T16:41:59.980 に答える
10

なぜサブクラス化する必要があるのですか?既存の仮想メソッドをオーバーライドするだけなら、匿名の内部クラスでいいと思います。機能を追加する場合は、名前付きクラスを使用します。ただし、ネストされたクラスにします(つまり、static修飾子を使用します)-推論が簡単だと思います:)

于 2009-04-03T16:11:16.403 に答える
4

匿名の内部クラスは、Eclipse でデバッグするのが困難です (私はそれを使用しています)。右クリックするだけでは、変数の値を確認したり、値を挿入したりすることはできません。

于 2009-04-03T16:30:49.790 に答える
3

私の個人的な経験則: 匿名の内部クラスが小さい場合は、匿名のクラスに固執します。小とは、約 20 ~ 30 行以下と定義されます。長くなると読みづらくなるので、名前付きインナークラスにしています。4000 行以上の匿名内部クラスを見たことがあります。

于 2009-07-30T18:55:23.493 に答える
3

内部クラスの欠点は、静的にできないことです。これは、それらを含む外部クラスへの参照を保持することを意味します。

非静的内部クラスが問題になる可能性があります。たとえば、最近、シリアル化された内部クラスがありましたが、外部クラスはシリアル化できませんでした。非表示の参照は、外部クラスもシリアル化されることを意味し、もちろん失敗しましたが、理由を見つけるのに時間がかかりました。

私が働いている場所では、コーディングのベスト プラクティスで (可能な場合) 静的内部クラスが推奨されています。

于 2009-04-03T17:11:21.190 に答える
2

一般的には、匿名の内部クラスが適しています。とても読みやすいと思います。ただし、そのクラスのインスタンスをシリアル化する必要がある場合 (それが別のフィールドであるためであっても)、名前付き内部クラスを使用することを強くお勧めします。バイトコード内の匿名の内部クラスの名前は非常に簡単に変更される可能性があり、これによりシリアル化が中断される可能性があります。

于 2009-04-03T16:35:38.590 に答える
2

匿名クラスには名前がないため、コンストラクターを持つことはできません。拡張するクラスのコンストラクターにある変数以外の変数を渡す必要がある場合は、(静的) 名前付き内部クラスを使用する必要があります。これは、周囲のメソッド/コードで最終変数を使用することで克服できる場合がありますが、少し見苦しいです (そして、ロビンが言ったことにつながる可能性があります)。

于 2010-11-20T04:15:44.293 に答える
1

匿名クラス:

  • 定義に何も含めることはできませんstatic(静的クラス、静的フィールド、静的初期化子など)
  • Eclipseではフィールドを検査できません
  • タイプとして使用できません(Foo$1 myFoo=new Foo$1(){int x=0;}機能しません)
  • Eclipseでクラス名を使用して見つけることができません(検索しFoo$1ても機能しません)
  • 再利用できません

ただし、匿名クラスには、次のような初期化子を含めることができます。{super.foo(finalVariable+this.bar);}

名前付き内部クラスにはこれらの制限はありませんが、長いプロシージャの途中で排他的に使用される場合でも、宣言を次の名前付きクラスに移動する必要があります。

制限が適用されない場合、私は個人的に匿名の内部クラスを好みます。理由は次のとおりです。

  • 追加のフィールドはクラス定義でのみ参照されていることを私は知っています。
  • Eclipseはそれらをネストされたクラスに簡単に変換できます。
  • 使用したい変数をコピーする必要はありません。それらを最終として宣言し、参照することができます。これは、パラメーターがたくさんある場合に特に便利です。
  • 相互作用するコードは互いに接近しています。
于 2012-05-26T21:01:06.607 に答える
0

この場合、あなたがしたことは完全に理にかなっていると思います。どちらにしても、この特定の問題で本当に髪を分けていると思います。どちらも非常に似ており、どちらでも機能します。

于 2009-04-03T16:11:38.073 に答える
0

今日、同僚とこの議論をしたところ、世論を探し回っていました.

私はTofuBeerに同意します。コードに 2 行以上ある場合、それはおそらく「1 回限り」ではなく、いつか再利用される可能性があります。MVC パターンを使用してフォームを作成している場合、大量の匿名クラスでビューを乱雑にする代わりに、1 ページに 20 の制御可能な要素がある可能性があります (ビューはおそらく GUI ビルダーを使用して作成され、コードは自動生成されたものです)オプションでさえないソースを編集する)おそらく、各要素をコントローラーにフィードします。コントローラー内に内部クラスをネストして、ビューに必要なそれぞれの異なるハンドラー/リスナー インターフェイスを処理できます。これにより、特にハンドラー クラスに GUI 要素名を使用して名前を付ける必要があるという規則がある場合 (backButtonElement の backButtonHandler など)、コードが非常によく整理されます。これは私たちにとって非常にうまく機能し、また、自動登録ツールを作成しました (コントローラーをビューに登録すると、ビューは要素名を使用して内部クラスを検索し、それらを各名前付き要素のハンドラーに使用します)。これは匿名クラスでは不可能であり、コントローラーをよりリサイクルしやすくします。

TLDR: 疑わしい場合は、名前付き内部クラスを記述してください。いつか誰かがあなたのコードを再利用したいかどうかはわかりません (2 行でない限り、「このコードのにおいは?」と考える必要があります)。よく整理されたコードは、特にプロジェクトがメンテナンス中の場合、長期的にははるかに大きな利益をもたらします。

于 2013-04-16T22:23:40.987 に答える
0

匿名の内部クラスでは、含まれているクラス メンバーの状態を変更できません。それらは final として宣言する必要があります。

于 2016-02-27T12:18:12.123 に答える
0

これは好みの問題だと思います。Functorsには匿名クラスを使用することを好みます。しかし、あなたの場合、私は内部クラスを使用します。なぜなら、そこに数行以上のコード、おそらく単なるメソッド以上のものを詰め込むことになると思うからです。また、メソッドのどこかに隠すのではなく、クラス内に配置することで、スーパークラスに機能を追加しているという事実を強調します。さらに、いつの日か他の場所でサブクラスが必要になるかもしれません。もちろん、これは、ソフトウェアがどのように進化するかについてどれだけ知っているかによって異なります。それ以外は、コインを投げるだけです。:)

于 2009-04-03T16:24:28.947 に答える