The "Virtual Method" mechanism for the dynamic binding process of running is a key technique for achieving polymorphism. C , Java, and C # (in accordance with the birthday month, the same, the same below) As the three mainstream support for the programming language of the face-to-face object, it naturally provides this dynamic method binding mechanism, on this issue Brothers don't have anyone who is vague. But when "virtual" and "private" are touched together, these languages are different, and the story of this article is from a small program:
Let's take a short C program below.
// Test.cpp
#include
Using namespace std;
Class base {
PUBLIC:
Void f () {
g ();
}
Private:
Virtual void g () {
Cout << "Hi, Morningstar! I am g () of base !." << endl;
}
}
Class Derived: public base {
Private:
Virtual void g () {
Cout << "Hi, Morningstar! I am g () of derived." << endl;
}
}
Int main () {
Base * pb = new deerived ();
Pb-> f ();
Delete PB;
Return 0;
}
The program is very simple. In the base class "base", the virtual private method G is called through the public method F, and inherits the private method G of the Override override.
Do you have any questions about other words first? No; can it pass? can. What is the result of the run? Since compiling can pass, then the result can guess, it should be:
Hi, Morningstar! I am g () of derived.
That's right, VC6.0, VC.Net 2003 and GCC are all this. From the results, the call to the private method G is bind to the actual type (Derived) method, which is in line with the semantics of the virtual function.
We know, in Java, there is no "Virtual" such a keyword, the default is Virtual, and the keyword "final" needs to be added without overwritten. In Java, if you have written methods, if you want to call your parent class, you need to call through a special keyword "super". Ok, don't say Java grammar, let's see a similar Java program below:
//Derived.java
Class base {
Public void f () {
g ();
}
Private void g () {
System.out.println ("Hi, Morningstar! I am g () of base.");
}
}
Public class deived extends base {
Private void g () {
System.out.println ("Hi, Morningstar! I am g () of derived.");
}
Public static void main (String [] args) {
Base b = new derived ();
B.f ();
}
}
Use the command line
Javac Derived.java
Compiled, then
Java Derived
Operation, there should be no problem (even in the eclipse, running directly: P). The result is:
Hi, Morningstar !, I am g () of base.
Although the procedure is similar, the results produced in these two in different languages are not the same.
Turning the related chapters of the C 98 standard (ISO / IEC 14882), no special descriptions about this situation, only Section 11.6 involving virtual functions Access: Access To Virtual Functions, not this Case. It can be seen that the C language only specifies the access control issues of public, protected and private, and dynamic binding issues of the Virtual method. For their combination, there is no limit, in other words, there are two Non-related mechanism, access control is responsible for accessing the issue, regardless of the method is not a virtual; and the virtual only delays the problem, regardless of public, protection or private. Thus, the result of the previous C program output is not surprising.
However, from the object-oriented perspective, the private things in the base class are unasible for the outside world, and the inheritance class should not know any private things in the base class, so inheritance, overwriting should also be discussed. It's just right, even if the method is renamed, it should only be seen as a coincidence, Java is doing this.
In Java, Private is natural, I think the Java designer has at least the above consideration: since it is private, it is not visible, see can't see it, what to overwrite? So, in Java, we discuss inheritance and polymorphisms are for external interfaces, including the puclic method, protected method, and default Friendly method, and private is not included, from a sense, Java The Private method is purely the method, and it is a more clear and easier maintenance means of organizational code.
However, if only the syntax language is considered, not from the object-oriented theory, maybe C thicker - Since there is no limit, then private can also be Virtual, you can enjoy the Virtual level. That should be enjoyed. And Java has no Virtual not Virtual, no syntax traces stuffy: public / protected / friendly is like this, and private is that.
Finally, let's take a look at the new favorite in the era, how did C # do? We use Visual Studio.net 2003 to create a new Console application, add a C # source file, and then write similar code:
//Test.cs
Using system;
Namespace test {
Class base {
Public void f () {
g ();
}
Private Virtual Void g () {
Console.Writeline ("Hi, Morningstar! I am g () of base.");
}
}
Class Derived: base {
Private Override Void g () {
Console.Writeline ("Hi, Morningstar! I am g () of derived.");}
Public static void main (String [] args) {
Base b = new derived ();
B.f ();
}
}
}
Compile. Finished, compiled!
... / Test.cs (14): "Test.base.g ()": Virtual members or abstract members can't be private
... / Test.cs (22): "Test.derived.g ()": Virtual members or abstract members can't be private
It seems that C # is embarrassed, the grammar refuses to virtual private - then there is no output result to copy it.
C # inherits the "Virtual" key from C , and this is different from Java only in the form, and the non-Virtual method in C # is largely equivalent to the FINAL method in Java. Just Java Final is also used to specify whether the class itself is inherited, C # uses another keyword "Sealed" to do this.
Relatively, it is also the most flexible C , it is not limited to this possible: The base class allows the derivation class to re-implement a method, but does not allow the school to directly call the base class, namely: I can use you directly ( Bind when running), but you can't use it directly - this is different from protect / protected. After all, "rewritten" and "call" are still two yards. Since it is two yards, it is not necessary to say that it is not necessary.
to sum up:
C supports virtual private members that can be overwritten from syntax to semantics;
No traces of java grammar, but there is no private member that can be covered in semantics;
C # Directly reject private methods from grammar into virtual (can be overwritten).