动手动脑-4

package 动手动脑;

public class 基类 {
     public 基类()
         {

                System.out.println("基类 Created.");
        
    }


        public 基类(String string) 
        {

                System.out.println("基类 Created.String:" + string);
        
     }

}
package 动手动脑;

public class 父类 extends 基类 {
    public 父类()
     {

           super("Hello.Grandparent.");

           System.out.println("父类 Created");
    
     //super("Hello.Grandparent.");

      }

}
package 动手动脑;

public class 子类 extends 父类{
    public 子类()
     {
    
       System.out.println("子类 Created");

      }



}
package 动手动脑;

public class 测试 {
    public static void main(String args[])
     {

       子类 c = new 子类();
    
 }


}

当super在父类构造函数上面时,最终的运行结果为:

基类 Created.String:Hello.Grandparent.
父类 Created
子类 Created

先调用基类有参构造函数,输出基类 Created.String:Hello.Grandparent.,然后再依次调用父类和子类构造函数。当super在父类构造函数的下面时,出现错误,程序无法运行。所以得出结论,用super调用基类的构造方法,必须是子类的第一个语句。

 

构造方法用于对基类的初始化。构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。

 

package 动手动脑;

public class 父类2 {
    
public  void sleeping() {
    System.out.println("父亲在睡觉。");
}
}
package 动手动脑;

public class 子类2 extends 父类2{
    
public  void sleeping() {
    super.sleeping();
    System.out.println("孩子在睡觉。");
}
}
package 动手动脑;

public class 测试2 {
public static void main(String[] args) {
    
    子类2 z=new 子类2();
    z.sleeping();
}
}

这个程序的运行结果为:

父亲在睡觉。
孩子在睡觉。

子类把父类的方法覆盖,通过super关键字来调用父类中的方法。

class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}

public class TestCast
{
    public static void main(String args[])
    {
        Mammal m;
        Dog d=new Dog();
        Cat c=new Cat();
        m=d;
        //d=m;
        d=(Dog)m;
        //d=c;
        //c=(Cat)m;

    }
}

通过运行我发现,当放开d=m这一行和d=c这一行的注释之后,编译出现错误,当放开c=(Cat)m这一行的注释之后,运行出现错误。因为m是父类创建的对象,而d是子类创建的对象,所以当d=m时需要进行类型强制转换,而没有转换会使编译出现错误。d=c这一行出现错误的原因是不能让同等地位的对象进行转换。

package 动手动脑;

public class Child extends Parent {

    public int myValue=200;
    public void printValue() {
        System.out.println("Child.printValue(),myValue="+myValue);
    }
}
package 动手动脑;

public class Parent {
    public int myValue=100;
    public void printValue() {
        System.out.println("Parent.printValue(),myValue="+myValue);
    }
}
package 动手动脑;

public class ParentChildTest {
    public static void main(String[] args) {
        Parent parent=new Parent();
        parent.printValue();
        Child c=new Child();
        c.printValue();
        
        parent=c;
        parent.printValue();
        
        parent.myValue++;
        parent.printValue();
        
        ((Child)parent).myValue++;
        parent.printValue();
        
    }
}

这个程序运行之后的结果为:

Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201

前两条结果不用解释,第三条,parent=c; 将子类变量赋给基类变量,这样就是体现了多态性,和Parent parent=new Child();的效果是一样的,此时当对象parent引用方法时,引用的是子类的方法,而当此对象引用变量时,引用的是父类的变量,所以在parent.printValue();时,输出的是子类中方法的输出语句,而parent.myValue++;时,增加的是父类变量myValue的值,而子类中myValue的值不变,所以当此对象再次引用此方法时,输出的仍是子类中此方法中的输出语句,而myValue的值不变,当使用了强制类型转换之后,((Child)parent).myValue++;此时(Child)parent就相当于是子类对象,引用变量myValue时,增加的是子类myValue的值,而调用方法之后,输出子类方法中的输出语句,而myValue得值发生变化。

 

 

原文地址:https://www.cnblogs.com/zhaoxinhui/p/9890529.html