C# 面向对象设计之谜
假设您有一个从其他类X继承的抽象基类A 类重写方法foo1 其他的A1、A2、A3类混凝土类很少 所有具体类都继承方法foo1 方法foo1几乎类似于一般算法,应该适用于所有具体类。 这几乎是因为算法中有一个异常,即存在一个if条件,一些类(比如说只有A1、A3)需要在foo的开始处打乱一些其他方法foo2 对于A2,我们不需要启动foo2 问题是,如果我在类A中实现foo2,那么它的所有子级也将继承此函数,这不是很好的设计吗 我曾想过将foo2排除在一个接口之外,该接口将由具体类->实现,但这并不好,因为调用foo2的foo1位于基类上 有没有办法用一种合适的方式解决这个问题C# 面向对象设计之谜,c#,oop,object-oriented-analysis,C#,Oop,Object Oriented Analysis,假设您有一个从其他类X继承的抽象基类A 类重写方法foo1 其他的A1、A2、A3类混凝土类很少 所有具体类都继承方法foo1 方法foo1几乎类似于一般算法,应该适用于所有具体类。 这几乎是因为算法中有一个异常,即存在一个if条件,一些类(比如说只有A1、A3)需要在foo的开始处打乱一些其他方法foo2 对于A2,我们不需要启动foo2 问题是,如果我在类A中实现foo2,那么它的所有子级也将继承此函数,这不是很好的设计吗 我曾想过将foo2排除在一个接口之外,该接口将由具体类->实现,但这
谢谢在基类中创建一个属性,子类可以在需要调用foo2时设置该属性:
public class BaseClass {
protected bool RunFoo2 { get; set; }
public BaseClass() {
// Not really needed, since booleans default to false
RunFoo2 = false;
}
public virtual void foo1() {
if (RunFoo2)
foo2();
// Default code here
}
public virtual void foo2() {
// Whatever
}
}
public class A : BaseClass {
public A() : base() {
RunFoo2 = true;
}
}
在基类中创建一个属性,子类可以在需要调用foo2时设置该属性:
public class BaseClass {
protected bool RunFoo2 { get; set; }
public BaseClass() {
// Not really needed, since booleans default to false
RunFoo2 = false;
}
public virtual void foo1() {
if (RunFoo2)
foo2();
// Default code here
}
public virtual void foo2() {
// Whatever
}
}
public class A : BaseClass {
public A() : base() {
RunFoo2 = true;
}
}
您可以在子类中重写某种内部Foo1初始值设定项
public abstract class A {
internal virtual void Foo1Init() {
Console.WriteLine("Foo1Init");
}
public void Foo1() {
Foo1Init();
Console.WriteLine("Foo1");
}
}
public class A1 : A {
internal override void Foo1Init() {
Console.WriteLine("A1 Foo1Init Override");
}
}
public class A2 : A {
}
public class A3 : A {
internal override void Foo1Init() {
Console.WriteLine("A3 Foo1Init Override");
}
}
class Program {
static void Main(string[] args) {
var a1 = new A1();
a1.Foo1();
var a2 = new A2();
a2.Foo1();
var a3 = new A3();
a3.Foo1();
Console.ReadKey();
}
}
输出:
您可以在子类中重写某种内部Foo1初始值设定项
public abstract class A {
internal virtual void Foo1Init() {
Console.WriteLine("Foo1Init");
}
public void Foo1() {
Foo1Init();
Console.WriteLine("Foo1");
}
}
public class A1 : A {
internal override void Foo1Init() {
Console.WriteLine("A1 Foo1Init Override");
}
}
public class A2 : A {
}
public class A3 : A {
internal override void Foo1Init() {
Console.WriteLine("A3 Foo1Init Override");
}
}
class Program {
static void Main(string[] args) {
var a1 = new A1();
a1.Foo1();
var a2 = new A2();
a2.Foo1();
var a3 = new A3();
a3.Foo1();
Console.ReadKey();
}
}
输出:
在这种情况下,我将使用的解决方案是生成另一层抽象类,而需要特殊Foo2的类则从中派生
abstract class A : X
{
public virtual void Foo()
{
//Foo logic
}
}
abstract class B : A
{
protected virtual void Foo2()
{
//Foo2
}
override void Foo()
{
Foo2();
base.Foo();
}
}
public A1 : B
{
}
public A2 : A
{
}
public A3 : B
{
}
在这种情况下,我将使用的解决方案是生成另一层抽象类,而需要特殊Foo2的类则从中派生
abstract class A : X
{
public virtual void Foo()
{
//Foo logic
}
}
abstract class B : A
{
protected virtual void Foo2()
{
//Foo2
}
override void Foo()
{
Foo2();
base.Foo();
}
}
public A1 : B
{
}
public A2 : A
{
}
public A3 : B
{
}
您可以在中将foo2设置为私有,并添加一个受保护的虚拟属性,子类可以覆盖该虚拟属性,并且A使用该虚拟属性来确定子类是否要在foo1的开头调用foo2。我想我理解并看到了一个解决方案,但我认为,如果您在问题中添加一些过于简单的代码,比如抽象类MyShape,那就更好了{….我不确定我是否遵循了,但这将有助于您在中使foo2私有化,并改为添加一个受保护的虚拟属性,子类可以覆盖该虚拟属性,并且A使用该虚拟属性来确定子类是否要在foo1的开头调用foo2。我想我理解并看到了一个解决方案,但我认为如果您添加一些simp会更好问题的列表代码ala抽象类MyShape{…..我不确定我是否遵循,但这将有助于您根据具体需要将foo2设置为私有、非虚拟或两者兼而有之。根据具体需要,您也可以将foo2设置为私有、非虚拟或两者兼而有之。此实现的唯一缺点是它添加了另一个具有特殊性的基类n从类名上看,这可能不明显。@lukegravitt在现实世界中,我希望有更多的描述性名称,如X=Shape、A=Polygon、B=Quadralateral、A1=parallelgoma、A2=Triangle和A3=梯形。此实现的唯一缺点是它添加了另一个基类,与其他基类的区别可能不明显类名。@lukegravitt在现实世界中,我希望有更多的描述性名称,如X=形状、A=多边形、B=四边形、A1=平行四边形、A2=三角形和A3=梯形