Reputation: 29720
I have this little OO problem..
abstract class MyAbstractBaseClass
{
MyHelperClassBase myHelperBaseClass;
protected method foo()
{
//QUESTION....... : when I am here I want to do this...
myHelperBaseClass = new MyHelperSubClass();
//OR...
myHelperBaseClass = new MyOtherHelperSubClass();
//HOWEVER ITS COMPLETELY CONDITIONAL ON THE BASE CLASS
//HOW DO I MAKE SURE THE CORRECT TYPE IS INSTANTIATED DEPENDANT ON
//THE BASE CLASS WITHOUT USING AN 'if' STATEMENT?
}
}
class MySubClass : MyAbstractClass {}
class MyOtherSubClass : MyAbstractClass {}
/////////////
abstract class MyHelperClassBase {}
class MyHelperSubClass : MyHelperClassBase, IMyHelper {}
class MyOtherHelperSubClass : MyHelperClassBase, IMyHelper {}
I want to be able to have a the type basically passed up but cant think of a slick way to do this. Should I just stuck an abstract property on the base class?
Upvotes: 1
Views: 81
Reputation: 24756
The older OO way of solving this (without generics) involves a virtual or abstract method on the base that the derived classes must implement. This is pretty common in parallel hierarchies like your example:
abstract class MyAbstractClass{
MyHelperClassBase myHelper;
protected void foo() {
myHelper = createHelper();
}
protected abstract MyHelperClassBase createHelper();
}
class MySubClass : MyAbstractClass{
protected override MyHelperClassBase createHelper(){
return new MyHelperSubClass();
}
}
class MyOtherSubClass : MyAbstractClass{
protected override MyHelperClassBase createHelper(){
return new MyOtherHelperSubClass();
}
}
Generics come in very handy, but sometimes it's good to know this way, too.
Upvotes: 0
Reputation: 564403
Your goals are somewhat unclear. If the goal is to associate a helper class with a specific implementation of the class, there are a couple of options.
You can use generics:
abstract class MyAbstractBaseClass<T> where T : MyHelperClassBase, new()
{
T myHelper;
protected void Foo()
{
myHelper = new T(); // This will be the appropriate subclass
}
}
// Derived classes become ...
class MySubClass : MyAbstractClass<MyHelperSubClass>
{
}
// Derived classes become ...
class MyOtherSubClass : MyAbstractClass<MyOtherHelperSubClass>
{
}
Alternatively, you could have an abstract property in the base class, and the subclasses could implement it:
abstract class MyAbstractBaseClass<T> where T : MyHelperClassBase, new()
{
MyHelperClassBase myHelper;
abstract protected Func<MyHelperClassBase> MyHelperClassBaseFactory { get; }
protected void Foo()
{
// Construct as needed...
myHelper = MyHelperClassBaseFactory();
}
}
// Derived classes implement...
class MySubClass : MyAbstractClass
{
protected override Func<MyHelperClassBase> MyHelperClassBaseFactory
{
get { return () => new MyHelperSubClass(); }
}
}
Upvotes: 3