1. ホーム
  2. c#

[解決済み] サブクラスでのフィールドやプロパティのオーバーライド

2022-04-25 05:10:33

質問

抽象的な基底クラスがあり、この親クラスを継承する各クラスで異なる値を持つフィールドまたはプロパティを宣言したい。

ベースクラスで定義して、ベースクラスのメソッドで参照できるようにしたい。たとえば、ToStringをオーバーライドして、"このオブジェクトの型は プロパティ/フィールド となります。 これを行うには3つの方法がありますが、これを行うための最良の方法または受け入れられた方法は何でしょうか?初心者の質問です、すみません。

オプション1:

抽象プロパティを使用し、継承されたクラスでそれをオーバーライドします。これは強制力があり(オーバーライドしなければならない)、クリーンであることが利点です。しかし、フィールドをカプセル化するのではなく、ハードコードの値を返すのは少し間違っているように感じますし、ちょうどではなく、数行のコードです。また、私は "set" のためにボディを宣言しなければなりませんが、それはあまり重要ではありません(そして、私が知らないそれを回避する方法がおそらくあります)。

abstract class Father
{
    abstract public int MyInt { get; set;}
}

class Son : Father
{
    public override int MyInt
    {
        get { return 1; }
        set { }
    }
}

オプション2

publicフィールド(またはprotectedフィールド)を宣言して、それを継承したクラスで明示的にオーバーライドすることができるんだ。下の例では "new" を使うように警告が出るので、おそらくそうすることができますが、間違っていると感じますし、肝心のポリモーフィズムを壊してしまいます。良いアイデアとは思えませんね...。

abstract class Mother
{
    public int MyInt = 0;
}

class Daughter : Mother
{
    public int MyInt = 1;
}

オプション3

protectedフィールドを使用し、コンストラクタで値を設定することができます。しかし、コンストラクタが常にこの値を設定するようにしなければなりません。また、複数のオーバーロードされたコンストラクタを使用する場合、一部のコードパスで値が設定されない可能性があります。

abstract class Aunt
{
    protected int MyInt;
}

class Niece : Aunt
{
    public Niece()
    {
        MyInt = 1;
    }
}

ちょっと理論的な質問ですが、答えは選択肢1しかないと思います。 セーフ しかし、私はC#を使い始めたばかりで、より経験豊富な人々にこれを尋ねたいと思いました。

どのように解決するのですか?

3つのソリューションのうち、唯一 オプション1 ポリモーフィック .

フィールド単体でのオーバーライドはできません。これはまさに オプション2 が返されます。 新しい キーワードの警告を表示します。

警告に対する解決策は、"new "キーワードを追加することではなく、オプション1を実行することです。

フィールドをポリモーフィックにする必要がある場合、それをプロパティでラップする必要があります。

オプション3 は、ポリモーフィックな動作が必要ない場合は、OKです。しかし、実行時に MyInt プロパティがアクセスされた場合、派生クラスは返される値を制御できないことを覚えておく必要があります。ベースクラスはそれ自体でこの値を返すことができるのです。

これは、プロパティの真のポリモーフィック実装がどのように見えるかであり、派生クラスが 制御 .

abstract class Parent
{
    abstract public int MyInt { get; }
}

class Father : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "X" and return a value */ }
    }
}

class Mother : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "Y" and return a value */ }
    }
}