使用子类和方法的最佳方式

The best way to use child classes and methods

有一些新手问题。 我有 6 类:

public class MainSettingsClass
{
    int a;
    int b;
}

public class SubSettingsClass_1 : MainSettingsClass
{
    int c;
}

public class SubSettingsClass_2 : MainSettingsClass
{
    int d;
}

public class ParentClass
{
    public MainSettingsClass settings;
}

public class ChildClass_1 : ParentClass
{
}

public class ChildClass_2 : ParentClass
{
}

现在是问题。 ChildClass_1 与 SubSettingsClass_1 和 ChildClass_2 与 SubSettingsClass_1

ChildClass_1 firstClassVar = new ChildClass_1();
ChildClass_2 secondClassVar = new ChildClass_2();
SubSettingsClass_1 firstClassSettings = new SubSettingsClass_1();
SubSettingsClass_2 secondClassSettings = new SubSettingsClass_2();
firstClassVar.settings = (MainSettingsClass)firstClassSettings;
secondClassVar.settings = (MainSettingsClass)secondClassSettings;

如果我需要使用 "firstClassVar.settings" 获取 "c" 变量,我每次都需要写的主要内容是:

 ((firstClassSettings)firstClassVar.settings).c
  1. 这是访问变量的正确方法吗?
  2. 或者有更好的方法存在?
  3. 这段代码是否符合编程规则?还是不正确?

抱歉英语不好。

  1. 这是访问 c 变量的 "right" 方式吗? 没有。如果你要沮丧,至少先检查一下:

    firstClassSettings derivedSettings = firstClassVar.settings as firstClassSettings;
    if (derivedSettings != nulL)
    {
        //Do whatever with derivedSettings.c
    }
    
  2. 有一个更好的方法:)它叫做多态性。您的 class 是超级通用的,因此很难 确切地说 您的设计应该是什么样子,但是您的主要 class 应该有一些派生的方法 classes 覆盖以获得自定义行为。

  3. 向下转型是一种巨大的代码味道。有时没有办法解决它(尤其是在遗留代码中,或在某些 Object 覆盖和 WPF 接口中)但是,您应该尽可能避免它。在你自己的 objects/code.

  4. 中更是如此

您所拥有的 技术上 很好,尽管存在一些问题。首先,不需要强制转换为 MainSettingsClass。由于 SubSettingsClass_1SubSettingsClass_2 都继承自 MainSettingsClassParentClass 及其所有派生词,都将接受任何一个作为定义为 [=12= 类型的字段的值].

其次,字段(其中 settings 是一个)通常不会 public。定义了 getter 和 setter 的属性通常是您与对象上的数据的接口。

第三,settings 这里是一个依赖项,因此,确实应该通过 class 的构造函数注入。类似于:

public class ParentClass
{
    protected MainSettingsClass settings;

    public ParentClass(MainSettingsClass settings)
    {
        this.settings = settings;
    }
}

更新

我刚刚想到的另一件事对您了解会有所帮助。请记住,通过使用像 MainSettingsClass 这样的最小公分母,您将无法使用更具体的派生 classes SubSettingsClass_1SubSettingsClass_2 的特定成员。但是,可以使用泛型为您提供更多灵活性:

public class ParentClass<TSettings>
    where TSettings : MainSettingsClass
{
    protected TSettings settings;

    public ParentClass(TSettings settings)
    {
        this.settings = settings;
    }
}

public class ChildClass_1 : ParentClass<SubSettingsClass_1>
{
    ...
}

public class ChildClass_2 : ParentClass<SubSettingsClass_2>
{
    ...
}

这样,您现在可以在 ChildClass_1 中使用 c 并在 ChildClass_2 中使用 d,因为 settings 字段的类型将是 SubSettingsClass_1SubSettingsClass_2