157 suggestions for writing high-quality code to improve C # programs-recommendation 94: Treat override and new differently,
Suggestion 94: Treat override and new differently
Override and new enable the type system to present polymorphism for inheritance. Polymorphism requires that subclass has a method with the same name as the base class. The functions of override and new are:
- If the method in the subclass contains the new Keyword, the method is defined as a method independent of the base class.
- If the method in the subclass contains the override keyword, The subclass object will call this method. Instead of calling the method of the base class.
Let's look at an inheritance system:
public class Shape { public virtual void MethodVirtual() { Console.WriteLine("base MethodVirtual call"); } public void Method() { Console.WriteLine("base Method call"); } } class Circle : Shape { public override void MethodVirtual() { Console.WriteLine("circle override MethodVirtual"); } } class Rectangle : Shape { } class Triangle : Shape { public new void MethodVirtual() { Console.WriteLine("triangle new MethodVirtual"); } public new void Method() { Console.WriteLine("triangle new Method"); } } class Diamond : Shape { public void MethodVirtual() { Console.WriteLine("Diamond default MethodVirtual"); } public void Method() { Console.WriteLine("Diamond default Method"); } }
Shape is the base class of all subclasses.
The MethodVirtual of the parent class override of the Circle class, so even if the subclass is transformed to Shape, the subclass method is called:
Shape s = new Circle(); s.MethodVirtual(); s.Method();
Output:
Circle override MethodVirtual
Base Method call
Circle s = new Circle(); s.MethodVirtual(); s.Method();
The output is also:
Circle override MethodVirtual
Base Method call
Type Rectangle does not perform any processing on the base class. Therefore, no matter whether it is transformed to Shape or not, the base class Shape method is called.
The Triangle type adds the virtual and non-virtual Methods of the base class Shape, so the first method is:
Shape s = new Triangle(); s.MethodVirtual(); s.Method();
Because the subclass method should pass the new parent class method, the subclass method and the base class method have no relationship at all. As long as s is transformed to Shape, it is the parent class method for s calls.
Triangle triangle = new Triangle(); triangle.MethodVirtual(); triangle.Method();
All sub-class methods are called, and the output is:
Triangle new MethodVirtual
Triangle new Method
Type Diamond contains two methods identical to the base class without any additional modifiers. This provides warnings in the compiler. However, if you choose to ignore these warnings, the program can still run.
Shape s=new Diamond(); s.MethodVirtual(); s.Method();
The compiler defaults to new, so the output and display are the same when it is set to new.
Output:
Base MethodVirtual call
Base Method call
Diamond s = new Diamond(); s.MethodVirtual(); s.Method();
Output:
Diamond default MethodVirtual
Diamond default Method
Finally, a comprehensive example is provided:
static void Main(string[] args) { TestShape(); TestDerive(); TestDerive2(); } private static void TestShape() { Console.WriteLine("TestShape\tStart"); List<Shape> shapes = new List<Shape>(); shapes.Add(new Circle()); shapes.Add(new Rectangle()); shapes.Add(new Triangle()); shapes.Add(new Diamond()); foreach (Shape s in shapes) { s.MethodVirtual(); s.Method(); } Console.WriteLine("TestShape\tEnd\n"); } private static void TestDerive() { Console.WriteLine("TestDerive\tStart"); Circle circle = new Circle(); Rectangle rectangle = new Rectangle(); Triangle triangel = new Triangle(); Diamond diamond = new Diamond(); circle.MethodVirtual(); circle.Method(); rectangle.MethodVirtual(); rectangle.Method(); triangel.MethodVirtual(); triangel.Method(); diamond.MethodVirtual(); diamond.Method(); Console.WriteLine("TestShape\tEnd\n"); } private static void TestDerive2() { Console.WriteLine("TestDerive2\tStart"); Circle circle = new Circle(); PrintShape(circle); Rectangle rectangle = new Rectangle(); PrintShape(rectangle); Triangle triangel = new Triangle(); PrintShape(triangel); Diamond diamond = new Diamond(); PrintShape(diamond); Console.WriteLine("TestDerive2\tEnd\n"); } static void PrintShape(Shape sharpe) { sharpe.MethodVirtual(); sharpe.Method(); }
Output:
TestShape Start
Circle override MethodVirtual
Base Method call
Base MethodVirtual call
Base Method call
Base MethodVirtual call
Base Method call
Base MethodVirtual call
Base Method call
TestShape End
TestDerive Start
Circle override MethodVirtual
Base Method call
Base MethodVirtual call
Base Method call
Triangle new MethodVirtual
Triangle new Method
Diamond default MethodVirtual
Diamond default Method
TestShape End
TestDerive2 Start
Circle override MethodVirtual
Base Method call
Base MethodVirtual call
Base Method call
Base MethodVirtual call
Base Method call
Base MethodVirtual call
Base Method call
TestDerive2 End