在派生 classes 中定义基础 class 构造方法
Define base class constructor methods in derived classes
我正在尝试创建一个全面的 abstract
BaseClass
,它定义了所有派生 classes 的创建方式,但允许派生 classes specialize/aggregate 创建过程中使用的字段和方法。这是一个简化的例子:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
list = new List<String>();
}
protected void doSomething()
{
// do something w/ list here
}
protected void optionalDoSomething() {}
}
public class DerivedClass : BaseClass
{
protected void defineList()
{
base.defineList();
list.Add("something");
}
public DerivedClass() : base() { }
}
public class SecondDerivedClass : DerivedClass
{
protected void defineList()
{
base.defineList();
list.Add("somethingElse");
}
protected void optionalDoSomething()
{
// do something special
}
public SecondDerivedClass() : base() { }
}
这将使所有派生的 classes 不必重新创建相同的初始化逻辑,并且每个派生的 class 只需要 "overwrite" 中使用的必要字段和方法创建进程(可能在 class 的其他地方)。
问题:
我无法将 BaseClass
' 方法标记为 virtual
,因为您不能在基础构造函数中调用 virtual
方法(无论如何,我不想使用 virtual
方法,因为,例如,我不希望 DerivedClass
使用 SecondDerivedClass
' defineList
方法)。
我可以将它们标记为 abstract
,但那样我就无法将 "default implementations" 放入 BaseClass
并且每个派生的 class 都会有replicate/implement 这些默认值。此外,SecondDerived
class 仍然需要一种方法来 "override" DerivedClass
的实现。
简单地使用new
关键字"hide" less derived class'方法是行不通的。
获得这个图案的正确方法是什么?
TLDR:根据我在下面的评论:
如果 BaseClass
是使用方法 A
的 abstract
class,并且 DerivedClass
是从 BaseClass
派生的 class(不一定是BaseClass
的直接子代),然后在 BaseClass
中调用 A
' 构造函数应该在继承层次结构中的每个 class 中调用 A()
,直到并包括 DerivedClass
(但没有进一步)。我们可以假设 A
(强制)定义在每个中间 class 上。
实现您想要的方法的一种方法是向基 class 添加显式 Initialize
方法并在那里执行初始化逻辑,例如:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
}
public void Initialize()
{
defineList();
optionalDoSomething();
doSomething();
}
}
试试这个解决方案,实现是用受保护的虚拟方法实现的,所以它从外部不可见,在派生中也不需要 类:
public abstract class BaseClass
{
public List<String> List { get; protected set; }
protected BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
// default implementation here
List = new List<String>();
internalDefineList();
}
protected void doSomething()
{
// default implementation here
internalDoSomething();
}
protected void optionalDoSomething()
{
// default implementation here
internalOptionalSomething();
}
protected virtual void internalDefineList()
{
}
protected virtual void internalDoSomething()
{
}
protected virtual void internalOptionalSomething()
{
}
}
public class DerivedClass : BaseClass
{
protected override void internalDefineList()
{
var list = List;
}
protected override void internalDoSomething()
{
}
// this method is not required
/*
protected override void internalOptionalSomething()
{
}
*/
}
我认为你应该参考template-method-design-pattern
Define the skeleton of an algorithm in an operation, deferring some
steps to subclasses. Template Method lets subclasses redefine certain
steps of an algorithm without changing the algorithm's structure.
你可以尝试类似的东西
abstract class AbstractClass
{
public List<String> list;
public abstract void PrimitiveOperation1();
public void TemplateMethod()
{
//initialize code that each class should perform
PrimitiveOperation1();
}
}
class DerivedClass: AbstractClass
{
public override void PrimitiveOperation1()
{
list.Add("something");
}
}
用法
AbstractClass abstractClass1 = new DerivedClass();
abstractClass1.TemplateMethod();
我正在尝试创建一个全面的 abstract
BaseClass
,它定义了所有派生 classes 的创建方式,但允许派生 classes specialize/aggregate 创建过程中使用的字段和方法。这是一个简化的例子:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
list = new List<String>();
}
protected void doSomething()
{
// do something w/ list here
}
protected void optionalDoSomething() {}
}
public class DerivedClass : BaseClass
{
protected void defineList()
{
base.defineList();
list.Add("something");
}
public DerivedClass() : base() { }
}
public class SecondDerivedClass : DerivedClass
{
protected void defineList()
{
base.defineList();
list.Add("somethingElse");
}
protected void optionalDoSomething()
{
// do something special
}
public SecondDerivedClass() : base() { }
}
这将使所有派生的 classes 不必重新创建相同的初始化逻辑,并且每个派生的 class 只需要 "overwrite" 中使用的必要字段和方法创建进程(可能在 class 的其他地方)。
问题:
我无法将
BaseClass
' 方法标记为virtual
,因为您不能在基础构造函数中调用virtual
方法(无论如何,我不想使用virtual
方法,因为,例如,我不希望DerivedClass
使用SecondDerivedClass
'defineList
方法)。我可以将它们标记为
abstract
,但那样我就无法将 "default implementations" 放入BaseClass
并且每个派生的 class 都会有replicate/implement 这些默认值。此外,SecondDerived
class 仍然需要一种方法来 "override"DerivedClass
的实现。简单地使用
new
关键字"hide" less derived class'方法是行不通的。
获得这个图案的正确方法是什么?
TLDR:根据我在下面的评论:
如果 BaseClass
是使用方法 A
的 abstract
class,并且 DerivedClass
是从 BaseClass
派生的 class(不一定是BaseClass
的直接子代),然后在 BaseClass
中调用 A
' 构造函数应该在继承层次结构中的每个 class 中调用 A()
,直到并包括 DerivedClass
(但没有进一步)。我们可以假设 A
(强制)定义在每个中间 class 上。
实现您想要的方法的一种方法是向基 class 添加显式 Initialize
方法并在那里执行初始化逻辑,例如:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
}
public void Initialize()
{
defineList();
optionalDoSomething();
doSomething();
}
}
试试这个解决方案,实现是用受保护的虚拟方法实现的,所以它从外部不可见,在派生中也不需要 类:
public abstract class BaseClass
{
public List<String> List { get; protected set; }
protected BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
// default implementation here
List = new List<String>();
internalDefineList();
}
protected void doSomething()
{
// default implementation here
internalDoSomething();
}
protected void optionalDoSomething()
{
// default implementation here
internalOptionalSomething();
}
protected virtual void internalDefineList()
{
}
protected virtual void internalDoSomething()
{
}
protected virtual void internalOptionalSomething()
{
}
}
public class DerivedClass : BaseClass
{
protected override void internalDefineList()
{
var list = List;
}
protected override void internalDoSomething()
{
}
// this method is not required
/*
protected override void internalOptionalSomething()
{
}
*/
}
我认为你应该参考template-method-design-pattern
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
你可以尝试类似的东西
abstract class AbstractClass
{
public List<String> list;
public abstract void PrimitiveOperation1();
public void TemplateMethod()
{
//initialize code that each class should perform
PrimitiveOperation1();
}
}
class DerivedClass: AbstractClass
{
public override void PrimitiveOperation1()
{
list.Add("something");
}
}
用法
AbstractClass abstractClass1 = new DerivedClass();
abstractClass1.TemplateMethod();