C#函数继承与代码复用:消除Draw方法重复实现问题
解决方案
要消除代码重复同时保留多态调用能力,你可以通过抽象基类封装公共逻辑,利用GetType()自动获取实例的真实类型特性来实现需求,无需在子类中重复编写Draw方法。
重构后的代码示例
// 保留原接口(可选,若需要基于接口编程则保留) public interface IShapes { void Draw(); } // 抽象基类封装公共Draw逻辑 public abstract class ShapeBase : IShapes { public void Draw() { // GetType()会返回当前实例的真实子类类型 var className = GetType().FullName?.Substring(GetType().FullName.IndexOf('.') + 1); Console.WriteLine($"{className} - Draw"); } } // 子类仅需继承基类,无需重写Draw public class Square : ShapeBase { } public class Circle : ShapeBase { }
调用代码(与原需求一致)
var shapes = new List<IShapes>(); shapes.Add(new Circle()); shapes.Add(new Square()); shapes.ForEach(s => s.Draw());
执行后将输出:
Circle - Draw Square - Draw
为什么你之前的尝试失败
你使用public new void Draw()的方式是隐藏基类方法,而非重写,这会破坏多态性:当通过基类/接口类型调用时,执行的是基类的方法而非子类的。而这里根本不需要子类重写Draw——基类中的GetType()会自动识别当前实例的真实子类类型,直接复用基类逻辑即可。
扩展场景:子类需要自定义Draw逻辑
如果后续子类需要添加专属逻辑,可以将基类的Draw定义为virtual,子类通过override扩展:
public abstract class ShapeBase : IShapes { public virtual void Draw() { var className = GetType().FullName?.Substring(GetType().FullName.IndexOf('.') + 1); Console.WriteLine($"{className} - Draw"); } } public class Square : ShapeBase { public override void Draw() { // 先执行基类逻辑 base.Draw(); // 添加子类专属逻辑 Console.WriteLine("Square has 4 sides"); } }
内容的提问来源于stack exchange,提问作者John Barber
相关产品推荐
相关产品推荐

