Inheritance and polymorphism after-school hands-on brain summary problem

A succession

1, title

Run TestInherits.java example, observing the output, call summary note the relationship between a parent class constructor for the subclasses modify the code construction method of the Parent, an explicit call to another constructor GrandParent,

Note whether the calling code is the phrase of the first sentence, a major impact!

code show as below:

 1 class Grandparent {
 2     public Grandparent(){
 3           System.out.println("GrandParent Created.");    
 4 }
 5     public Grandparent(String string) {
 6             System.out.println("GrandParent Created.String:" + string);    
 7  }
 8 }
 9 class Parent2 extends Grandparent{
10     public Parent2(){
11             super("Hello.Grandparent.");
12             System.out.println("Parent Created");
13        // super("Hello.Grandparent.");
14       }
15 }
16 class Child2 extends Parent2 {
17     public Child2()  {
18         System.out.println("Child Created");
19       }
20 }
21 
22 public class TestInherits {
23     public static void main(String args[]) {
24             Child2 c = new Child2();
25   }
26 }

 

2, run shot

 

 

 

 

3. Conclusion:

1, the constructor of a subclass prior to execution, you must first call the parent class constructor

2, by calling the parent class constructor super, super must be the first statement in the subclass constructor written

3, super itself is to call the parent class constructor, and can run a parent is hidden member variables and member of the parent class overridden method

 

4, thinking: Why constructor in subclass before you run, you must call the constructor of the parent class? Can you turn? Why not turn?

5. Answer: No, the child class has member variables and member methods of the parent class, if you do not call the constructor of the parent class, class members inherited from a parent variants

The amount and method members can not be initialized. The reason can not turn to call, because the parent does not know what subclass member variables and member methods

And in doing so subclasses can not complete the inherited member variable initialization in the parent class help, leading member variables could not be initialized, the program will error,

Can not be performed.

 

Second, to explore the mysteries of technology: see ExplorationJDKSource.java example and run got a strange run results: Test1.A@8efb846 Why?

1, Code

 1 package Test1;
 2 
 3 
 4 public class test1 {
 5 
 6     /**
 7      * @param args
 8      */
 9     public static void main(String[] args) {
10         System.out.println(new A());
11     }
12 
13 }
14 
15 class A{}

 

 

 

 

2、使用javap –c命令反汇编ExplorationJDKSource.class;

 

 

 

3、查看字节码指令,搞清楚到底为什么输出了Test1.A@8efb846?

前面程序中,main方法实际上调用的是: public void println(Object x),这一方法内部调用了String类的valueOf方法。

valueOf方法的内部又调用Object.toString方法

而Object.toString方法的代码是:

public String toString(){

return getClass().getName() +"@" + Integer.toHexString(hashCode());

}

hashCode方法是本地方法,是JVM的设计者实现的: public native int hashCode();

 

三、神奇的“+”号

1、代码

 1 public class Fruit
 2 {
 3         
 4     public String toString()
 5     {
 6         return "Fruit toString.";
 7     }
 8 
 9     public static void main(String args[])
10     {
11         Fruit f=new Fruit();
12         System.out.println("f="+f);
13     //    System.out.println("f="+f.toString());
14     }
15 }

 

2、运行结

 

 

 

3、结论

1、首先,Fruit类的toString方法覆盖了Object类的toString方法。

2、在“+”运算中,当任何一个对象与一个String对象进行连接时,会隐式地调用String对象的toString()方法,

默认情况下,toString方法返回“类名 @ + hashCode”。即Test1.A@8efb846这种形式,为了返回有意

义的信息,子类可以重写并覆盖toString()方法。

 

四、请自行编写代码测试以下特性(动手动脑):

1、问题:在子类中,若要调用父类中被覆盖的方法,可以使用super关键字

2、代码

 1 class test{
 2     void play() {
 3         System.out.println("我是父类test父");
 4     }
 5 }
 6 
 7 class test11 extends test{
 8     void play() {
 9         super.play();
10     }
11 }
12 public class test1
13 {
14     public static void main(String[] args) {
15         test11 t=new test11();
16         t.play();
17     }
18         
19 }

 

3、运行结果

 

 

五、多态

1、在实践中理解把握复杂的知识-1

(1)代码如下

 1 public class ParentChildTest {
 2     public static void main(String[] args) {
 3         Parent parent=new Parent();
 4         parent.printValue();
 5         Child child=new Child();
 6         child.printValue();
 7         
 8         parent=child;
 9         parent.printValue();
10         
11         parent.myValue++;
12         parent.printValue();
13         
14         ((Child)parent).myValue++;
15         parent.printValue();
16         
17     }
18 }
19 
20 class Parent{
21     public int myValue=100;
22     public void printValue() {
23         System.out.println("Parent.printValue(),myValue="+myValue);
24     }
25 }
26 class Child extends Parent{
27     public int myValue=200;
28     public void printValue() {
29         System.out.println("Child.printValue(),myValue="+myValue);
30     }
31 }

 

(2)测试结果

 

 

2、你如何解释会得到这样的输出?

(1)原因:

前两行正常输出,父类对象调用父类的方法,子类对象调用子类的方法

第三行,当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定

第四行,当parent=child;仅仅是将parent中有的方法用child的方法代替,所以parent.myValue++;而输出的是child的printValue()

printValue()方法中输出的是child.myValue,所以输出的是child.myValue

第五行,强制类型转换,++作用在child的myValue,所以输出的也是child的myValue,而不是parent的myValue

 

3、计算机是不会出错的,之所以得 到这样的运行结果也是有原因的, 那么从这些运行结果中,你能总 结出Java的哪些语法特性?

(1)当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

(2)这个特性实际上就是面向对象“多态”特性的具体表现。

(3)如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。

(4)如果子类被当作父类使用,则通过子类访问的字段是父类的!

 

Guess you like

Origin www.cnblogs.com/yang2000/p/11723462.html