Let's take a look at an example, and if you read Java programming ideas, you should be impressed.
1 PackageCom.test.zj;2 3 Public classpolyconstructors {4 5 Public Static voidMain (string[] args) {6 //TODO auto-generated Method Stub7 NewRoundglyph (5);8 }9 Ten } One A classRoundglyphextendsGlyph { - Private intRADIUS = 1; - the PublicRoundglyph (intr) { - //TODO auto-generated Constructor stub -Radius =R; -System.out.println ("Roundglyph radius==" +radius); + } - + @Override A voidDraw () { at //TODO auto-generated Method Stub -System.out.println ("Roundglyph Draw () radius==" +radius); - } - - } - in classGlyph { - voidDraw () { toSystem.out.println ("Print Glyph.draw ()"); + } - the Glyph () { *System.out.println ("Glyph () before Draw ()"); $ Draw ();Panax NotoginsengSystem.out.println ("Glyph () after draw ()"); - the } + A}
For a general Java-based classmate, here you might think that the output is as follows:
1 Glyph () before draw () 2 roundglyph Draw () radius==13Glyph () after draw ()4 roundglyph radius==5
But when you're done running, you'll see that his output is:
Maybe some people read here or don't quite understand what I'm going to say, so I'll write a simple example. Define a parent class first superclass
1 PackageCom.test.zj;2 3 Public classSuperclass4 {5 Private intSupervalue;6 7 PublicSuperclass ()8 {9Setsupervalue (100);Ten One } A - Public voidSetsupervalue (intx) - { theSupervalue=x; - } - -}
Then we define the subclass of it:
1 //This subclass inherits from the parent class superclass2 Public classSubclassextendsSuperclass3 {4 Private intsubvalue=10;5 6 PublicSubclass ()7 {8 9 }Ten //This method overrides the method of the parent class One Public voidSetsupervalue (intx) A { - //call the method of the parent class first - Super. Setsupervalue (x); the //then assign the value to your own variable -Subvalue=x; - - } + - Public voidPrintsubvalue () + { ASystem.out.println ("Subclass subvalue==" +subvalue); at } - -}
Finally, write a main function to do it.
1 PackageCom.test.zj;2 3 Public classMainClass {4 5 Public Static voidMain (string[] args) {6 //TODO auto-generated Method Stub7Subclass Sc=Newsubclass ();8 Sc.printsubvalue ();9 }Ten One}
Well, now I'm sure a lot of people will think the second example output should be 100.
But in fact there is no egg to use, his actual result is:
So what happened to all two of these examples, we came straight to the byte code, this bytecode is definitely not wrong, bytecode how to write how the JVM executes.
Let's take a look at the first example.
It should be obvious here that our main function begins with the new Roundglyph object. Let's look at the results of this class-C.
You can see the constructor for this class
This is done first:
This means that the glyph constructor is executed first and then the assignment statement is executed when the glyph constructor executes.
Our radius as an int variable is automatically initialized by the JVM before it is executed his value is 0!
So you're supposed to be able to figure out a approximate, first-executed glyph constructor, and then give your own member variable radius assignment.
So let's see what glyph has done:
You see the glyph constructor, in the middle of the 13:invokevirtual #31 here, to execute the draw method, but the subclass we rewrite this draw method
So you see, when you call the draw method of a subclass in the constructor of glyph, the RADIUS assignment statement of the subclass is not executed, so this method of the subclass
The value of the output is of course 0!
When the constructor of the parent class glyph is finished, the assignment statement for our subclass is finally executed. So you should be able to understand the first example here.
So now we can go into the second example, in fact, it is very similar. Let's take a look at the second example of the Manclass and main functions.
You see here the main function is first new to the object of a subclass subclass, right? Then of course we're going to see subclass Init method
In fact, this place is the subclass constructor.
It is clear here that in subclass's constructor we are executing the constructor of the superclass first, and then assigning our subvalue a value of 10.
Then we'll go and see what's been done in superclass. But actually, we've come here to think of whatever you've done in superclass, when you're done.
The value of Subvalue must be 10.
So when your subclass object is constructed, the value of his member variable subvalue is 10, so you can certainly print out the value of this variable at 10.
Of course, in order to be clearer, I still have to say a little bit about what I did in the superclass constructor, although what we did in it wouldn't affect our conclusions, but let's talk about it.
Even if there's no egg to use ...
You see this is a call to setsupervalue this method, right, because the subclass rewrite this method, so we must look at the sub-class
Here's what this method does:
Do you think it is the Setsupervalue method that calls the parent class again, and then you see a iload Putfield
These 2 operations are not to give us the subvalue of the subclass of the assignment, right. All the while up here, the first step of our subclass's object constructor:
Call the constructor of the parent class even if it is gone, it is time to finally execute its own assignment statement:
OK, here are the 2 examples here, even if the analysis is complete.
The final conclusion, in fact, is that of the Java programming idea:
Parent class static member--child class static member--parent class general member initialization and initialization block--parent class constructor Method--subclass normal member initialization and initialization block--subclass constructor method
If you are interested, you can write a slightly more complicated procedure, verify that the above conclusion is set, nonsense .... This conclusion must have been established. But
If you use the JAVAP-C command to see their bytecode, I believe you can understand the deeper!
In the end, when we write the code, we try to avoid the above 2 examples, because the bug is difficult to find. That
Try not to manipulate the member variables of the subclass in the constructor of the parent class. If you must write the initialization is very troublesome, please consider using the initialization block such a clear Method!
Don't ask me why I study this, because TMD has a bug for a long time to find it is this reason Ah! So later you find someone to write this, please write the email to the whole group to complain about him!
A complete anatomy of a polymorphic method inside a Java constructor