Search Unity

Cannot cast base class to extended class, best workaround?

Discussion in 'Getting Started' started by MCrafterzz, Apr 2, 2019.

  1. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Hello. I have a class called BridgeSettings that have some variables that all bridges use and then I have HangingBridgeSettings and SteelBridgeSettings that both extend BridgeSettings. I thought the road object could have a BridgeSettings instance and both extended classes would work. The problem is that the base class can't be extended to the extended class. Therefore using this:
    bridgeSettings = new HangingBridgeSettings();
    isn't a good idea as there's no way to access the HangingBridgeSettings unique values. What is the best way to have some base values that all versions/classes have but having more values at the same time? There must be a better way than having an instance for every class type like this:
    HangingBridgeSettings hangingSettings;
    SteelBridgeSettings steelSettings;
    ….

    If I have like 10 different bridge types, then it feels really broken to do it this way. I've heard about interfaces but they can't be serialized so how would that work?

    EDIT: I feel like others have had this problem as well so how do you usually solve it?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    You were correct.

    Not true; you can always typecast as needed. For example:

    Code (csharp):
    1. float hangHeight = ((HangingBridgeSettings)bridgeSettings).height;
    But if you're doing this more than rarely, you're probably not thinking about the problem correctly. Your base class is BridgeSettings, and it should encapsulate everything there is about bridge settings, for any kind of bridge. Users of this class (such as the road object) shouldn't know or care about the subclasses. If knowing how high it hangs is something roads need to do, then BridgeSettings itself should have a method for that, even if it always returns 0 in the base class (and is overridden only in HangingBridgeSettings).

    Approach it this way: what is it that a user of the bridge settings class needs to know/do? Whatever that answer includes, put it in the base class. Anything that is none of the user's business, such as the details of how certain things are calculated, can go into subclasses. Again, the users will not know or care about that.

    The whole point of most design patterns is to reduce how much stuff you need to have in your head at any given time. So you should be able to completely forget all the implementation details when you're working on code that uses the (base) class. And when working some subclass, you should be able to completely forget all about how it's used. If you can do that, you've probably factored it correctly.
     
    MCrafterzz likes this.