OOPの概念:継承とは何ですか?
継承は、オブジェクト指向プログラミング(OOP)言語のコア概念の一つです。 これは、属性とメソッドのセットを共有するクラスの階層に対して、別のクラスからクラスを派生させることができるメカニズムです。
これを使用して、さまざまな種類の例外を宣言したり、既存のフレームワークにカスタムロジックを追加したり、ドメインモデルをデータベースにマップ,
継承階層を宣言します
Javaでは、各クラスは他のクラスからのみ派生できます。 そのクラスはスーパークラスまたは親クラスと呼ばれます。 派生クラスは、サブクラスまたは子クラスと呼ばれます。
extendsキーワードを使用して、サブクラスが拡張するクラスを識別します。 スーパークラスを宣言しない場合、クラスは暗黙的にclassオブジェクトを拡張します。 Objectはすべての継承階層のルートであり、Javaの唯一のクラスであり、別のクラスを拡張しません。
次の図とコードスニペットは、単純な継承階層の例を示しています。,
BasicCoffeeMachineクラスはスーパークラスを宣言せず、クラスオブジェクトを暗黙的に拡張します。 GithubでCoffeeMachineサンプルプロジェクトを複製できます。
PremiumCoffeeMachineクラスは、BasicCoffeeMachineクラスのサブクラスです。
継承およびアクセス修飾子
アクセス修飾子は、どのクラスが属性またはメソッドにアクセスできるかを定義します。 カプセル化に関する私の以前の記事の一つで、私はあなたが情報隠蔽メカニズムを実装するためにそれらを使用する方法を示しました。 しかし、それはあなたが異なる修飾子に精通している必要がある唯一のケースではありません。, また、継承階層内でアクセスできるエンティティおよび属性にも影響します。
さまざまな修飾子の概要は次のとおりです。
- プライベート属性またはメソッドは、同じクラス内でのみアクセスできます。
- アクセス修飾子のない属性およびメソッドは、同じクラス内および同じパッケージ内の他のすべてのクラスによってアクセスできます。
- 保護された属性またはメソッドは、同じクラス内、同じパッケージ内のすべてのクラス、およびすべてのサブクラスでアクセスできます。,
- パブリック属性とメソッドは、すべてのクラスからアクセスできます。
そのリストでわかるように、サブクラスはスーパークラスのすべてのprotected属性とpublic属性とメソッドにアクセスできます。 場合、サブクラスは、スーパークラスに所属するパッケージには、サブクラスでのアクセスもすべてのパッケージ-個人の属性とメソッドは、スーパークラス.
私はPremiumCoffeeMachineクラスのコンストラクタで二度それを行います。
最初にsuperキーワードを使用して、スーパークラスのコンストラクタを呼び出します。 コンストラクタは、サブクラスが目にすることができます。, キーワードスーパー参照にはスーパークラス. 利用できるアクセス属性は、メソッドの呼び出しは、スーパークラスを取得するメソッドは、他のメソッドの現在のサブクラス. しかし、次のセクションでそれについての詳細。
保護された属性configMapは、BasicCoffeeMachineクラスによって定義されます。 そのクラスを拡張することにより、属性もPremiumCoffeeMachineクラスの一部になり、エスプレッソをマップに醸造するために必要な構成を追加できます。,
メソッドオーバーライド
継承は、スーパークラスのすべてのpublicおよびprotectedメソッドをサブクラスに追加するだけでなく、その実装を置き換えることもできます。 の方法のサブクラスはその後オーバーライドは、スーパークラス. そのメカニズムは多型と呼ばれます。
これをPremiumCoffeeMachineクラスで使用して、コーヒーマシンのコーヒー醸造機能を拡張します。 BasicCoffeeMachineメソッドのbrewCoffeeメソッドは、フィルターコーヒーのみを醸造できます。私はCoffeeSelectionのサポートを追加するためにPremiumCoffeeMachineクラスでそのメソッドをオーバーライドします。,エスプレッソ コードスニペットでわかるように、superキーワードはメソッドをオーバーライドする場合に非常に便利です。 BasicCoffeeMachineのbrewCoffeeメソッドは、すでにCoffeeSelectionを処理しています。サポートされていないCoffeeSelectionsに対して、Filter_coffeeおよびCoffeexceptionをスローします。
新しいbrewCoffeeメソッドで再利用できます。 同じロジックを再実装する代わりに、CoffeeSelectionがESPRESSOであるかどうかを確認するだけです。 そうでない場合は、superキーワードを使用して、スーパークラスのbrewCoffeeメソッドを呼び出します。,
メソッドがオーバーライドされないようにする
メソッドの実装を変更できるサブクラスがないことを確認する場合は、finalと宣言できます。 この投稿の例では、BasicCoffeeMachineクラスのaddBeansメソッドに対してそれを行いました。
コンストラクタによって呼び出されるすべてのメソッドをfinalにすることは、しばしば良い考えです。 これにより、サブクラスが意図せずにコンストラクタの動作を変更することを防ぎます。,
サブクラスもそのスーパークラスの型です
サブクラスはスーパークラスの属性とメソッドを継承するだけでなく、スーパークラスの型も継承します。 この例では、BasicCoffeeMachineのタイプはBasicCoffeeMachineおよびObjectです。 また、PremiumCoffeeMachineオブジェクトは、PremiumCoffeeMachine、BasicCoffeeMachine、およびObject型です。
これにより、PremiumCoffeeMachineオブジェクトをBasicCoffeeMachine型にキャストすることができます。
BasicCoffeeMachinee coffeeMachine = (BasicCoffeeMachine) PremiumCoffeeMachine(beans);
これにより、スーパークラスを使用するコードを記述し、すべてのサブクラスで実行できます。,
この例では、createCoffeeMachineメソッドのコードが返され、makeCoffeeメソッドはBasicCoffeeMachineクラスを使用します。 ただし、createCoffeeMachineメソッドは、新しいPremiumCoffeeMachineオブジェクトをインスタンス化します。 メソッドによって返されると、オブジェクトは自動的にBasicCoffeeMachineにキャストされ、コードはBasicCoffeeMachineクラスのすべてのパブリックメソッドを呼び出すことができます。coffeeMachineオブジェクトはBasicCoffeeMachineにキャストされますが、それでもPremiumCoffeeMachineです。, したがって、makeCoffeeメソッドがbrewCoffeeメソッドを呼び出すと、PremiumCoffeeMachineクラスのオーバーライドされたメソッドが呼び出されます。
抽象クラスの定義
抽象クラスは、これまでに説明した他のクラスとは異なります。 拡張は可能ですが、インスタンス化はできません。 これにより、特定のドメインには存在しない概念的一般化を表現するのに理想的ですが、コードの一部を再利用できます。
キーワードabstractを使用して、クラスまたはメソッドを抽象として宣言します。 抽象クラスには抽象メソッドを含める必要はありません。, しかし、抽象メソッドは抽象クラスによって宣言される必要があります。
コーヒーマシンの例をリファクタリングし、AbstractcoffeemachineクラスをBasicCoffeeMachineクラスのスーパークラスとして紹介しましょう。 私はそのクラスを抽象クラスとして宣言し、抽象brewCoffeeメソッドを定義します。
public abstract class AbstractCoffeeMachine { protected Map<CoffeeSelection, Configuration> configMap; public AbstractCoffeeMachine() { this.configMap = new HashMap<CoffeeSelection, Configuration>(); } public abstract Coffee brewCoffee(CoffeeSelection selection) throws CoffeeException; }
ご覧のとおり、抽象brewCoffeeメソッドの本体は提供していません。 私はちょうど私がインターフェイスで行うように宣言します。, AbstractCoffeeMachineクラスを拡張するときは、サブクラスをabstractとして定義するか、brewCoffeeメソッドをオーバーライドしてメソッド本体を実装する必要があります。
私はBasicCoffeeMachineクラスにいくつかのマイナーな変更を行います。 これでAbstractCoffeeMachineクラスが拡張され、既存のbrewCoffeeメソッドがスーパークラスの抽象メソッドをオーバーライドします。
私が変更したもう一つのことは、BasicCoffeeMachineクラスのコンストラクタです。 これで、スーパークラスのコンストラクターを呼び出し、マップをインスタンス化せずにconfigMap属性にキーと値のペアを追加します。, 抽象スーパークラスによって定義およびインスタンス化され、すべてのサブクラスで使用できます。
これは抽象スーパークラスとインターフェイスの主な違いの一つです。 抽象クラスでは、メソッドを宣言できるだけでなく、静的およびfinalではない属性を定義することもできます。
概要
これまで見てきたように、継承はスーパークラスを拡張するサブクラスを実装できる強力な概念です。 これにより、サブクラスはすべてのprotected属性とpublic属性とメソッド、およびスーパークラスの型を継承します。, を利用できますの継承された属性のスーパークラス、使用、またはオーバーライドの継承方法、キャストのサブクラスの任意の型、そのスーパークラス.
抽象クラスを使用して、インスタンス化できない一般的な抽象化を定義することができます。 内スク以外のリスクにつきを宣言する抽象メソッドをオーバーライドする非抽象サブクラス. これは、そのメソッドの実装が各サブクラスに固有であるが、階層のすべてのクラスに対して一般的なAPIを定義する場合によく使用されます。