Note: You should understand Java inheritance before reading this article. This article is positioned as having inherited the Basics.
One: trying to override private methods
First on the code
1 public classFather {2 3 Private voidprint () {4System.out.println ("private print");5 }6 7 public Static voidmain (string[] Args) {8Father Father =NewSon ();9 Father.print ();Ten } one a}
1 public class extends Father {23 public void print () {4 System.out.println ("public print"); 5 }6 }
Running father's main method, We expect the output to be public print, but because the private method defaults to the final method, and the derived subclass is masked, in this case, the print in the subclass is a new method in the subclass, is not a print method that overrides the parent class, and the @override annotation cannot be added to the print method of the Subclass.
Conclusion: Private methods cannot be overridden by Overrides.
Two: a dynamic binding method that calls the object being constructed inside a constructor
As we all know, the Constructor's call starts from the highest-level parent class, and then repeats itself recursively. What happens if you call the constructor output variable of a subclass in the constructor of the parent class?
1 public classFather {2 3 public voidDraw () {4System.out.println ("father draw");5 }6 7 publicFather () {8System.out.println ("father:before draw");9 Draw ();TenSystem.out.println ("father:after draw"); one } a -}
1 public classSonextendsFather {2 3 Private intNumber = 1;4 5 publicSon (intnumber ) {6 this. Number =number ;7System.out.println ("init number:" + this. number);8 }9 Ten @Override one public voidDraw () { aSystem.out.println ("son Draw number:" + this. number); - } -}
public class extends object{ publicstaticvoid main (string[] Args) { New Son (5); } }
Console printing:
Father:before Draw
Son draw number:0
Father:after Draw
Init number:5
In the test, we have a new son and a 5 in, according to the constructor of the call, we know that when constructing son to call father's construction method, and in the Father constructor, there is a call draw Method. In the subclass, the Draw method prints the number in son, with a default value of 1, and in the draw call we expect the output to be 1, but the actual output is 0.
The key to solving this problem is the process of Initialization. Before anything else happens, the storage allocated to the object is initialized to the binary 0 (you can assume that number has a default value of 1, but there is a default value of 0 before this default), and then the constructor of the parent class starts calling, and then recursively calls the constructor of the Subclass. The member variables are then initialized in the order in which they are declared. Before this initialization step, all variables are 0, or Null.
Third: call the subclass override of the parent class static Method.
1 public classFather {2 3 public StaticString staticget () {4 return"father Static get";5 }6 7 publicString dynaminget () {8 return"father dynamin get";9 }Ten}
1 public classSonextendsFather {2 3 public StaticString staticget () {4 return"son Static get";5 }6 7 publicString dynaminget () {8 return"son dynamin get";9 }Ten}
public class extends object{ publicstaticvoid main (string[] Args) { New Son (); System.out.println (f.staticget ()); System.out.println (f.dynaminget ()); } }
Console Output:
Father Static Get
Son dynamin get
We expect the output to be the son method rather than the father method, but the static method is called father instead of Son. This is because if a method is static, its behavior is not polymorphic, and the static method is bound to the class, not to a single object. Subclasses cannot overwrite static methods of the parent class, and in fact cannot add @override annotations on the Staticget method in Son.
Four: the domain of the subclass can overwrite the domain of the parent class
1 public class Father {23 public int number = 3; 4 5 public int getnumber () {6 return number ; 7 }8 }
1 public classSonextendsFather {2 3 public intNumber = 2;4 5 public intgetnumber () {6 returnnumber ;7 }8 9 public intgetsupernumber () {Ten return Super. number; one } a}
public class extends object{ publicstaticvoid main (string[] Args) { New Son (); System.out.println (s.getnumber ()); System.out.println (s.getsupernumber ()); } }
Console Output:
2
3
If number in Son is overwritten with Father number, then the output of the two number should be 2, in fact, the number of father from son is 3, which means that the number in son does not overwrite the number in Father. In this example, son.number and Father.number are assigned to different storage Spaces. In other words, in son, there are actually two variables named Number: its own and inherited from the Father. however, The default domain generated by number in Son is not the number field in Father. therefore, in order to get the number in father, you must explicitly indicate SUPER.FIELD.