11

この問題があるとします

public class Father{
    public void method1(){...}
}

public class Child1 extends Father{
    public void method1() throws Exception{
    super.method1();
    ... 
    }

}

Child1拡張Fatherおよびオーバーライドしますmethod1が、実装がChild1.method1例外をスローするようになりました。オーバーライド メソッドは新しい例外をスローできないため、これはコンパイルされません。

最善の解決策は何ですか?

  • 必要な例外を に伝播しFatherます。私にとって、これはカプセル化、継承、および一般的な OOP に反します (Father決して発生しない例外をスローする可能性があります)。
  • RuntimeException代わりにaを使用しますか? このソリューションは に伝播しませんがExceptionFatherOracle のドキュメントやその他のソースでは、「クライアント コードで何も実行できない」場合に例外のクラスを使用する必要があると記載されています。これはそうではなく、この例外は blablabla を回復するのに役立ちます (RuntimeException代わりに使用するのがなぜ間違っているのでしょうか?)。
  • 他の..
4

5 に答える 5

4

RTE を使用することは悪い考えではありません。これは Spring フレームワークの方法論であり、非常にうまく機能します。アプリケーションを実装している場合は、おそらくこのソリューションを使用してください。

ただし、API IMHO を公開するライブラリを実装している場合は、チェック済み例外を使用する必要があります。この場合、たとえば独自の例外を作成する必要がありますBaseException。の方法method()Father投げます。それをスローする子クラスの定義ChildException extends BaseExceptionと宣言。method1()

これはカプセル化を壊しません: 基本クラスは基本例外をスローします。具体的な例外については何もわかりません。子クラスは具体的な例外をスローしますが、基本例外を拡張するため、クライアント コードで基本例外として扱うことができます。

例として、私はあなたに与えることができIOExceptionFileNotFoundExceptionそれはそれを拡張します. IOException具体的なストリームがFileInputStreamあり、それがスローされている間に、入力ストリームのキャッチを操作できますFileNotFoundException。しかし、クライアントはこれを知りません。キャッチしIOExceptionます。

于 2012-10-19T16:58:15.350 に答える
2

スーパー クラス メソッドが Exception を宣言しない場合、サブクラスのオーバーライドされたメソッドはチェック済み例外を宣言できません。したがって、未チェックの例外のみを使用できます。

他のオプションは、スーパークラスが宣言できるようにすることですParentException。その後、オーバーライドされた子メソッドは、の子である例外を宣言できます。ParentException

于 2012-10-19T17:01:13.630 に答える
1

Child1 で何が例外をスローするかによって異なります。いくつかの前提条件などがあれば、いつでも IllegalArgumentException などの RuntimeException のサブクラスを使用できます。

ただし、何らかの種類の CheckedException がある場合、ロジックは、そのメソッド自体を処理し、他の方法でメッセージをバブルアップする必要があることを示唆しています。

一般的な経験則は次のとおりだと思います

あなたがそれを処理する方法を知っているなら..チェックされた例外を使用してくださいそうでなければチェックされていない例外

于 2012-10-19T16:57:21.230 に答える
0

必要な例外を父に伝播します..私にとって、これはカプセル化、継承、および一般的なOOPに反します(父は潜在的にスローし、決して起こらない例外)

Au contraire: これは良いOO です。呼び出し側をイメージします。

Father f = factory.getSomeImplementation();
f.method1();
// user has no chance to see the `Exception` of Child coming...

Fatherファクトリは、またはChildまたは のような完全に異なるもののインスタンスを返すことができますBrother。ただし、 の契約はすべてのmethod1場合で同じでなければなりません。そして、このコントラクトにはチェック例外が含まれています。これがリスコフ置換原理であり、OO の基本ルールの 1 つです。

そのため、例外がビジネス コントラクトの一部である場合はmethod1 、ルートで宣言する必要があります。そうでない場合 (例: 単純な引数チェック)、RuntimeExceptionとにかく a が進むべきルートです (つまり、継承がなくても)。

于 2012-10-19T17:05:20.123 に答える
0

「スロー」部分は、メソッド シグネチャの一部です。
これが、「子」クラスのメソッドが親クラスのメソッドのオーバーライドではない理由です。

于 2012-10-19T16:54:42.183 に答える