简体   繁体   中英

The best way to use child classes and methods

Have some newbie questions. I have 6 classes:

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
{
}

Now the questions. ChildClass_1 with SubSettingsClass_1 and ChildClass_2 with 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;

The main thing that if i need get "c" variable using "firstClassVar.settings" i need everytime write:

 ((firstClassSettings)firstClassVar.settings).c
  1. Is it right way to access variables?
  2. Or there is a better ways exists?
  3. Is this code corresponds programming rules? Or its not correct?

Sorry for bad english.

  1. Is that the "right" way to access the c variable? No . If you have to downcast, at least check it first:

     firstClassSettings derivedSettings = firstClassVar.settings as firstClassSettings; if (derivedSettings != nulL) { //Do whatever with derivedSettings.c } 
  2. There's a better way :) Its called polymorphism . Your classes are super general, so its hard to say exactly how your design should look, but your main class should have some method that the derived classes override to get the custom behavior.

  3. Downcasting is a huge code-smell. Sometimes there is no way around it (especially in legacy code, or in certain Object overrides and WPF interfaces) but, you should avoid it if at all possible. Doubly so in your own objects/code.

What you have is technically fine, although there's a few somewhat problematic aspects. First, there's no need to cast to MainSettingsClass . Since both SubSettingsClass_1 and SubSettingsClass_2 inherit from MainSettingsClass , ParentClass , and all derivatives thereof, will accept either as the value for a field defined as being of type MainSettingsClass .

Second, fields (of which settings is one) aren't typically made public. Properties, which have defined getters and setters are generally your interface to data on a object.

Third, settings here is a dependency, and as such, should really be injected via the constructor of the class. Something like:

public class ParentClass
{
    protected MainSettingsClass settings;

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

UPDATE

One more thing I just thought about that would be beneficial for you to know. Keep in mind that by using a least common denominator like MainSettingsClass , you lose the ability to work with specific members of the more specific derived classes SubSettingsClass_1 and SubSettingsClass_2 . However, generics can be used to give you a bit more flexibility:

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>
{
    ...
}

With that, you can now work with c in ChildClass_1 and d in ChildClass_2 because the type of your settings field will be SubSettingsClass_1 and SubSettingsClass_2 , respectively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM