课件中动手动脑4

(1)继承过程中相关基类构造函数的调用:

在进行对子类的对象进行初始化之前会调用基类的构造函数,并且按照继承顺序依次调用,原因是构造函数的作用就是用来初始化,当对子类的对象进行初始化时一定会需要对其继承的基类的所有字段等进行初始化,又因此,如果在子类的构造函数中需要调用父类的构造函数,该调用语句一定放在第一句否则会报错。

测试代码如下:

public class a {
    public a()
    {
        System.out.println("a的构造方法被调用");
    }
}
public class b extends a{
    public b()
    {
        super();
        System.out.println("b的构造方法被调用");
    }
}
public class c extends b{
    public c()
    {
        System.out.println("c的构造方法被调用");
    }
}
public class m {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        c child=new c();
    }
}

运行结果:

(1)加号的隐式调用:在+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。

public class main {
    /**
     * @param args
     */
    public String toString()
    {
        return "ok";
    }
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        main a=new main();
        System.out.println("a=" + a);
    }
}

(3):

源代码:

public class a {
    public void way()
    {
        System.out.println("父类的way方法被调用");
    }

}
public class b extends a{
    public void way()
    {
        super.way();
        System.out.println("子类的way方法被调用");
    }

}
public class c {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        b k=new b();
        k.way();
    }
}

运行结果:

 

(4):

 

 

源代码:

public class mammal {}
public class dog extends mammal {}
public class cat extends mammal {}
public class m {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        mammal i=null;
        dog j=new dog();
        cat k=new cat();
        i=j;
         j=i;
         j=(dog)i;
         j=k;
         k=(cat)i;
    }
}


第二句与第四句编译时出现错误,第二句原因是子类的对象可以直接赋值给基类变量,但是当基类对象要赋值给子类对象时需要进行强制类型转换,同样第四句中子类对象赋值给另一个子类变量时也需要进行强制类型转换。

5)源代码:

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

class Parent{
    public int myValue=100;
    public void printValue() {
        System.out.println("Parent.printValue(),myValue="+myValue);
    }
}
class Child extends Parent{
    public int myValue=200;
    public void printValue() {
        System.out.println("Child.printValue(),myValue="+myValue);
    }
}

运行结果如图:

创建了一个父类与一个子类,父类与子类中有相同的变量与方法,程序中将子类的对象赋值给了父类的变量,然后调用了该变量的方法,此时调用的是子类的,可知,对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

而在用该变量对类内的变量进行加一时,结果并没有改变,然后利用强制转换的方法再对变量进行加一,结果发生了变化,可知必须借用强制转化这一过程才能对父类变量调用的子类对象中的变量进行各种运算。

所以当子类赋值给父类变量时通过父类变量调用的字段是父类的,要想通过该变量调用子类字段必须通过强制转换的过程来实现。

原文地址:https://www.cnblogs.com/123456www/p/9898286.html