See http://www.cnblogs.com/birdshome/archive/2005/02/25/108866.html for more information
Birdshome references a test I gave him in the original article.CodeBut the original purpose of the test code is to call base in the foo of the derived class. for foo, the bar of derived is called because of the polymorphism, while the interface design of the base class is problematic.
"In fact, this is indeed a design conflict in object-oriented systems. It is equivalent to imposing Semantic Rules for no reason.ProgramPersonnel, and it is quite concealed ."
In OOD and OOP, the most important thing is thinking in object. The Object-Oriented function provided by the language is more of a semantic expression, it represents a feature of an object. In C #, virtual not only indicates that a method is a virtual function, but more importantly, it adds the polymorphism capability to the object method, this means that the class designer wants this class to be derived and can overload this method in the derived class. The Semantic Rules reflect the characteristics of the objects designed by the programmer, rather than implementation-related. The first step of OOD is abstraction. If the characteristics of Objects represented by classes are not abstracted, abstract With incorrect semantics will be generated because of incorrect use of language functions.
Looking back at the base class interface design, the original code is as follows: Public Class Base
{
Public Virtual Void Foo ()
{
Console. writeline ("Base: foo");
This. Bar ();
}
Public Virtual Void Bar ()
{
Console. writeline ("Base: bar");
}
} ;
From the perspective of object-oriented semantics and object interface design, there are many problems with the base class interface design.
First, foo acts as a public interface, but calls another public bar method. In terms of interface design, it is overlapping functions and does not meet the minimum interface requirements in object-oriented design.
Secondly, foo is a virtual method, which means that the implementation of Foo will be reloaded by the derived class. In the implementation of Foo, the method bar is called. The derived class is not responsible for calling the bar method in the foo overload, which means that the logic of the base class is not passed.
Third, foo itself is a virtual method, and the bar it calls is also a virtual method, which leads to a strong overload ability of the derived class, which often causes logical conflicts.
Therefore, the interface of the base class needs to be re-designed. You can refer to the template method mode and refactor it as follows: Public Class Base
{
Public Void Foo ()
{
This. Dofoo ();
This. Dobar ();
}
Public Void Bar ()
{
This. Dobar;
}
Protected Virtual Void Dofoo ()
{
}
Protected Virtual Void Dobar ()
{
}
} ;
Of course, the applicable interface design should be based on the Application Scenario. It cannot be simply described by a sample code.
The problem with the original text is that if (OBJ! = NULL), because bar is also a public method and can be called by other methods. From the interface design of the derived class, there is no semantics of Foo before the bar call, and this judgment is necessary.