C#8.0 基本理論 第 7 章 -- 継承

C#8.0 本質主義 第 7 章 – 継承

7.1派生

7.1.1 基本型と派生型間の変換

派生型は基本型に直接割り当てることができます。これは暗黙的な変換と呼ばれ、常に成功し、例外はスローされません。逆は当てはまりません。基本型から派生型への変換には明示的な Cast が必要ですが、実行時に失敗する可能性があります。

まったく関係のない型を相互に変換することもできます。重要なのは、 2 つの型の間に変換演算子を提供することです。C# では、明示的または暗黙的なキャスト演算子を含めることができます。

class GPSCoordinates
{
    public static implicit operator UTMCoordinates(GPSCoordinates coordinates)
    {
        // ...
    }
}
7.1.2プライベートアクセス修飾子

派生クラスは、コンストラクターとデストラクターを除くすべての基本クラスのメンバーを継承します。ただし、継承はアクセスが保証されることを意味するものではなく、派生クラスは基本クラスのプライベート メンバーにアクセスできません。

7.1.3保護されたアクセス修飾子

派生クラスから保護されたメンバーにアクセスするには、それが派生クラスのインスタンスであることをコンパイル時に判断できなければなりません。(少し長いので、本の説明を読むことをお勧めします)

7.1.4 拡張メソッド

拡張メソッドは技術的にはその型のメンバーではないため、継承できません。基本クラスを拡張すると、派生クラスで拡張メソッドを使用することもできます。

7.1.5 単一継承

C# の単一継承は、オブジェクト指向の点で C# と C++ の主な違いの 1 つです。(C++ の多重継承はバグとみなされます。詳細については別のメモを参照してください)

まれに複数の継承が必要になる場合、一般的な解決策は、継承の代わりに、あるクラスに別のクラスのインスタンスを含めるaggregationを使用することです。

7.1.6 シールタイプ

予期しない派生を避けるために、クラスをシール済みとしてマークします。たとえば、文字列クラスは sealed で変更されます。

7.2 基本クラスのオーバーライド

7.2.1仮想修飾子

C# は、インスタンス メソッドとプロパティのオーバーライドをサポートしていますが、フィールドと静的メンバーのオーバーライドはサポートしていません。基本クラスは、オーバーライドを許可するメンバーを仮想としてマークする必要があります。

C++ は構築中に仮想メソッドをディスパッチしません。代わりに、構築中に、型は派生型ではなく基本クラスの型に関連付けられ、仮想メソッドは基本クラスの実装を呼び出します。一方、C# は、仮想メソッド呼び出しを最も遠い派生型にディスパッチします。ただし、いずれの場合でも、C# ではこの状況は避けるべきです。

仮想はインスタンスを意味し、インスタンスのメンバーのみが仮想になれます。

7.2.2新しい修飾子

override キーワードが使用されていない場合、コンパイラは警告メッセージを生成し、新しい修飾子も使用できます。この状況は脆弱な基本クラスと呼ばれます。

これは、最も遠い派生メンバーを呼び出すのではなく、派生クラスのオーバーライドされた宣言されたメンバーを基本クラスから隠します。代わりに、継承チェーンが検索され、新しい修飾子を持つメンバーの前の最も遠い派生メンバーが検索されます。(newは親クラスのメンバーを書き換えるのではなく非表示にします。仮想関数テーブルの原理を知っておくと理解しやすいです)

override も new も指定されていない場合、デフォルトは new となり、バージョンのセキュリティが維持されます。

CIL の場合、新しい修飾子はコンパイラによって生成されたコードには影響しませんが、メソッドのニューススロット メタデータ特性が生成されます。C# の観点から見ると、その唯一の効果はコンパイラの警告を削除することです。

7.2.3sealed モディファイア

そのクラスからの派生を無効にするには、クラスで sealed 修飾子を使用します。同様に、仮想メンバーを封印することができます。

class A
{
    public virtual void Method()
    {
    }
}
 
class B : A
{
    public override sealed void Method()
    {
    }
}
 
class C : B
{
    // ERROR:  Cannot override sealed members
    //public override void Method()
    //{
    //}
}

シールされたメンバーは親クラスから継承してオーバーライドする必要があり、オーバーライドされたメンバーはシールする必要があります。

7.2.4ベースメンバー

Base の構文はこれとほぼ同じです。オーバーライドで変更されたメンバーは自動的に仮想メンバーと呼ばれ、サブクラスは実装をさらに「特殊化」できます。

7.2.5 基本クラスのコンストラクターの呼び出し

基本クラスにアクセス可能なデフォルト コンストラクターがない場合、基本クラスを構築する方法がわからないため、C# コンパイラはエラーを報告します。

このエラーを回避するには、プログラマは派生クラス コンストラクターのヘッダーでどの基本クラス コンストラクターを実行するかを明示的に指定する必要があります。

    public Contact(string name) : base(name)
    {
    }

7.3 抽象クラス

抽象変更では、抽象メンバーは自動的に仮想になります (オーバーライドする必要があるため) が、明示的に仮想宣言することはできません。抽象メンバーをプライベートとして宣言することはできません。そうしないと、派生クラスからは参照できません。

C# とは異なり、C++ では純粋仮想関数を示すために "=0" を使用します。純粋仮想関数を含むクラスは抽象クラスと呼ばれます。C++ ではクラス自体の特別な宣言は必要ありません。

ポリモーフィズムとは、同じ署名が複数の実装を持つことができることを意味します。抽象メンバーはポリモーフィズムを実現する手段です。

7.4 すべてのクラスは System.Object から派生します

クラスがオブジェクトから派生したことを明示的に示していない場合でも、クラスはオブジェクトから派生する必要があります。

7.5 is 演算子を使用したパターン マッチング

7.5.1 is 演算子を使用して基本型を検証する

is 演算子の利点は、明示的なキャストが失敗する可能性があるコード パスを、例外処理のオーバーヘッドなしで作成できることです。C# 7.0 以降では、is 演算子は型チェックに使用されるだけでなく、変数の宣言や値の割り当てにも使用できるようになりました。

7.5.2 type、var、constのパターンマッチング
7.5.3 タプルのパターンマッチング

変数のバッチをタプルに入れ、is 演算子を使用してタプルのパターン マッチングを実行したり、型のパターン マッチングとタプル内の変数への代入を実行したりできます。

7.5.4 逐次パターンマッチング
7.5.5 属性パターンマッチング

属性パターン マッチングでは、一致する値を指定するために括弧の代わりに中括弧を使用します。第二に、属性パターン マッチングでは、一致する値の順序は重要ではありません。Null 値もチェックします。

7.5.6 再帰的パターンマッチング

is演算子の属性パターンマッチングは判定式をサポートしていません。

7.6 switch ステートメントでのパターン マッチング

7.7 多態性クラスオブジェクトでのパターンマッチングの使用を避ける

is 演算子の利点は、データ項目が特定の型に属しているかどうかを確認できることです。as 演算子は、キャストと同じように、オブジェクトを特定のデータ型に変換しようとします。変換できない場合、as は null を返し、変換によって発生する可能性のある例外を回避します。as は参照型でのみ機能します。

おすすめ

転載: blog.csdn.net/Story_1419/article/details/133295672