C#基类方法复用:子类实现还是基类用if-else判断?
绝对不要用基类的if-else分支!用多态才是正确姿势
首先,你的问题刚好戳中了面向对象设计里的典型反模式——类型检查分支。咱们先掰扯清楚你当前代码的问题:
- 违反开闭原则:以后要是加个
ClassD,你得跑去修改基类的ReuseMethod,加新的if判断。改老代码永远是风险最高的操作,很可能不小心把原有ClassA/B/C的逻辑搞坏。 - 代码臃肿难维护:所有子类的特殊逻辑都堆在基类里,时间长了
ReuseMethod会变成几百行的大杂烩,谁看谁头大。 - 脆弱的类型判断:靠字符串
className区分类型太容易翻车——比如拼写错成"a",或者某个子类不小心改了className的值,直接导致逻辑失效,而且这种bug还不容易排查。
那正确的做法是什么?用多态,让每个子类负责实现自己的特殊逻辑,基类只管通用流程。
方案一:拆分特殊逻辑为虚方法
把每个子类独有的逻辑抽成基类里的虚方法,默认空实现,需要的子类重写就行:
public class BaseClass { public BaseClass() { } // 通用流程固定在基类 public void ReuseMethod() { commonLogic1(); SpecificLogicForA(); // 只有ClassA会实现这个 commonLogic3(); SpecificLogicForB(); // 只有ClassB会实现这个 commonLogic5(); SpecificLogicForC(); // 只有ClassC会实现这个 } // 虚方法,默认空实现 protected virtual void SpecificLogicForA() { } protected virtual void SpecificLogicForB() { } protected virtual void SpecificLogicForC() { } // 通用逻辑方法 private void commonLogic1() { /* 你的通用代码 */ } private void commonLogic3() { /* 你的通用代码 */ } private void commonLogic5() { /* 你的通用代码 */ } } public class ClassA : BaseClass { // 只重写自己需要的方法 protected override void SpecificLogicForA() { commonLogic2(); // ClassA专属逻辑 } private void commonLogic2() { /* 你的代码 */ } } public class ClassB : BaseClass { protected override void SpecificLogicForB() { commonLogic4(); // ClassB专属逻辑 } private void commonLogic4() { /* 你的代码 */ } } public class ClassC : BaseClass { protected override void SpecificLogicForC() { commonLogic6(); // ClassC专属逻辑 } private void commonLogic6() { /* 你的代码 */ } }
方案二:抽象出可变步骤
如果每个子类的差异集中在某个固定步骤里,也可以把整个可变部分做成抽象方法,强制子类实现:
public abstract class BaseClass { // 改成抽象类 public BaseClass() { } public void ReuseMethod() { commonLogic1(); ExecuteSpecificLogic(); // 子类各自实现这个方法 commonLogic3(); commonLogic5(); } // 抽象方法,子类必须实现 protected abstract void ExecuteSpecificLogic(); // 通用逻辑方法 private void commonLogic1() { /* 你的通用代码 */ } private void commonLogic3() { /* 你的通用代码 */ } private void commonLogic5() { /* 你的通用代码 */ } } public class ClassA : BaseClass { protected override void ExecuteSpecificLogic() { commonLogic2(); } private void commonLogic2() { /* 你的代码 */ } } public class ClassB : BaseClass { protected override void ExecuteSpecificLogic() { commonLogic4(); } private void commonLogic4() { /* 你的代码 */ } } public class ClassC : BaseClass { protected override void ExecuteSpecificLogic() { commonLogic6(); } private void commonLogic6() { /* 你的代码 */ } }
为啥这么做更好?
- 开闭原则友好:以后加新子类,只需要继承基类并重写对应的方法,完全不用碰基类的代码,风险直接降为0。
- 职责清晰:基类管通用流程,子类管自己的特殊逻辑,每个类的代码都干净整洁。
- 可扩展性强:要是以后某个子类需要修改自己的逻辑,直接改子类就行,不会影响其他类。
总之,把类型判断的分支换成多态,才是面向对象设计该有的样子,别让基类变成堆满各种分支的大垃圾桶。
内容的提问来源于stack exchange,提问作者Josh Tseng
相关产品推荐
相关产品推荐

