- Home /
Can I access a deriving class through a base/parent class?
I am working on a project that uses inheritance to make my life easier (or at least it will be soon). Let's say that i have a base class "Base Class" and I have two classes that drive from Base Class, let's call them "Class 1" and "Class 2". I don't know ahead of time which one of Class 1 or Class 2 it will be. I would like to have a reference to a singleton of Base Class and reference Class 1 or Class 2 (whichever it would be) through the singleton. I have not gotten to the point in the project that i need to do this yet but it is coming soon so i would like to know if this would work or if there is an alternative. I am not very experienced with inheritance so I might be asking a question with a super simple answer or a question with no answer. Any help is appreciated.
Im not sure I understand what you mean. Can you elaborate or provide some pseudo code?
So you have a singleton base class with a property that is polymorphic between two of its derived classes? Is that what you are trying to say?
Im not sure what it has to do with inheritance other than the fact you are deriving the base class twice.
Is this what you mean?
public class Base
{
public Base derived { get; set; }
}
public class DerivedA : Base
{
}
public class DerivedB : Base
{
}
public class Example
{
public Example() {
var test = new Base {
derived = new DerivedA()
};
Debug.Log(typeof(DerivedA) == test.derived.GetType()); // TRUE
test.derived = new DerivedB();
Debug.Log(typeof(DerivedB) == test.derived.GetType()); // TRUE
}
}
Sorry, I'm new at posting questions here. I'll try to make more sense and be more clear.
The context of my question is that I'm trying to create a game with a bunch of different $$anonymous$$i-games. I want to use one base class for a general game manager with code for spawning, etc. and I want a separate class for each $$anonymous$$i-game containing the gameplay code.
I would like to use the same player script for all $$anonymous$$i-games but the player wouldn't know which $$anonymous$$i-game script it should look for, but it would be able to know the base class (since that would always be consistent). I am wondering what the best way to do this is.
Also, thanks for the super quick responses.
Nothing to apologise for:
You could do it like that or you could use a design pattern like the one I pointed out which would solve some of the problems you may come up against if you just try to solve this problem with inheritance.
The strategy pattern I listed below is literally designed to solve this problem and is generally taught as one of the first OO design patterns so shouldn't be too hard to get your head around.
Answer by sacredgeometry · Aug 10, 2019 at 08:22 AM
Try the strategy pattern instead of inheritance
It will improve extensibility, readability and generally solve you a lot of headaches as your class variants grow more complex .
As said, inheritance is not a particularly good way to implement polymorphic traits. It's something that should generally be avoided unless you are trying to model a specific inheritance structure that, which is unlikely to ever change/ get more complex (and even then I would question the need to use it much).
Strategy Pattern Video
OO Design Patterns Bible
Well, I think I'm going to watch all these videos, good references there.
Is there a video that explains strategy pattern in unity well?
It's language and framework agnostic. It's an Object Oriented pattern.
It does come into play when you want to modify things from the editor no? Let's say I made an IDamagable interface with an instance of it being DamagableShipBehaviour with a value called hitPoints.
I would not be able to modify the DamagableSubsystemBehaviour hitPoints if I have a mono behaviour that has an IDamagable object in it.
I found a good tutorial that taught interfaces and strategy pattern really well (for me). I think it will have the desired effect. Thanks for all the help, both of you. Tutorial
Answer by ownezx · Aug 10, 2019 at 03:10 AM
What you want to do is called upcasting or downcasting.
Let's say you have a WeaponProjectile and a MissileProjectile, child of WeaponProjectile.
You can do something of the sort :
public void myFunction(WeaponProjectile wp)
{
MissileProjectile mp = (MissileProjectile)wp;
mp.range = 400f; // Public variable of type MissileProjectile
mp.damage = 100f; // Public variable of type WeaponProjectile
}
You can also use typof to get the lowest class the object is.
Read more about upcasting and downcasting here : https://www.c-sharpcorner.com/article/polymorphism-up-casting-and-down-casting/
You probably dont want to direct cast in this case as theres a chance it would throw an exception as you are expecting that cast to fail sometimes. Either you would need to wrap it in a try catch, which could get convoluted depending on the amount of variants or I would use "is" or "as" ie:
if(mp is $$anonymous$$issileProjectile)
{
var mp = wp as $$anonymous$$issileProjectile;
}
or if C#7 is supported
if(wp is $$anonymous$$issileProjectile mp)
{
// Code goes here and has been null checked on failure of conversion
}
Also there are better ways to achieve polymorphism than by using inheritance.
Inheritance is a particularly bad way given the alternatives. It locks you into an inheritance structure, it's cumbersome, hard to modify, prone to introduction of passing around larger objects than you need, having to write special case code and generally forces you to break SOLID principals a whole bunch.
Simply using interfaces (and if you need implementations on those interfaces: extension methods) is a much better solution to this problem.
Thats before going into patterns like the strategy pattern (potentially relevant here).