java继承中对构造函数是不继承的,只是调用(隐式或显式)。

以下是例子:

@父类

class father{
  public father(){
  System.out.println(100);
  }

  public father(int a){
  System.out.println(200);
  }
}

@子类继承父类 

public class SonClass extends FatherClass{ 

  public SonClass() {
  }

  public SonClass(int c) {
  System.out.println(1234);
  }

  public static void main(String[] args) {   //main主函数

  SonClass s = new SonClass(66);

  }
}

 

分析:

      SonClass s = new SonClass(66);

     执行这句时,调用

     public SonClass(int c) {
     System.out.println(1234); //系统会自动先调用父类的无参构造函数(super())

    }

 

-----------------------等价于--------------------

 

    public SonClass(int c) {

    super(); //必须是构造函数的第1行,否则不能编译
    System.out.println(1234);
    }

 

结果是 100
        1234

 

如果子类构造函数这样写

    public SonClass(int c) {

    super(22);   //super语句必须是子类构造函数的第1行,否则不能编译,显式调用了super后,系统就不再调用无参的super()了;
    System.out.println(1234);
    }

 

结果是 22
        1234

 

总结:

1、在创建子类的对象时,Java虚拟机首先执行父类的构造方法,然后再执行子类的构造方法

    在多级继承的情况下,将从继承树的最上层的父类开始,依次执行各个类的构造方法,这可以保证子类对象从所有直接或间接父类中继承的实例变量都被正确地初始化。

 

2、当父类定义无参和有参构造函数, 则不硬性规定必须在子类构造函数中写super调用父类;若没有使用super调用父类构造函数,无论子类是否为无参传入,统一默认运行父类    的无参构造函数super()。

    当父类没有无参构造函数,但定义有参构造函数,则子类的构造函数必须调用父类构造函数,super(int)(很容易理解,不用硬性记忆。无论是有参函数还是无参构造函数都是定义出来的,而当父类有构造函数的时候就给子类默配一个super(),所以当父类只有有参构造函数的时候,就要给子类写有效的构造函数),super语句必须写在子类构造函数的第一行。

 

3、父类变量引用子类对象

    father f1 = new son()

   父类有(ABC方法),子类有(CDF方法),f1接收子类对象,子类中的D、F方法被屏蔽,f1拥有A、B、(子类中的)C方法

   C方法属于重写override,因此属于动态多态。另外,若要调用D、F方法,只要将f1对象强制转换类型即可:

 son s1 = (son)f1;

   s1可以代替f1就可以调用d,f方法。(儿子穿上父亲的伪装之后只能用父亲的方法,才不会露馅;但是当卸下伪装当回自己的时候,就能   用属于自己的东西---类型转换)

 

4、内存分析父类和子类的强制转换

 

现在有一个父类Father,用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存.
现在通过代码来看看内存的分配情况:
Father f = new Father();//系统将分配1M内存.
Son s = new Son();//系统将分配1.5M内存.因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用父类的方法.

 

Son s1 = s;    //s1指向那1.5M的内存.
Father f1 = (Father)s;   //这时f1会指向那1.5M内存中的1M内存,即是说,f1只是指向了s中实例的父类实例对象,但是隐藏了其中的0.5内存
Son s2 = (Son)f;      //这句代码运行时会报ClassCastException.因为f中只有1M内存,而子类的引用都必须要有1.5M的内存,所以无法转换.
Son s3 = (Son)f1;   //这句可以通过运行,这时s3指向那1.5M的内存.由于f1是由s转换过来的,所以它是有1.5M的内存的,只是它指向的只有1M内存.

必须内存大的才能被强制转化为小的,即为子类转化为父类引用,才能有得指向。

 

 

5、super关键字的用法

① 显示调用父类构造函数

  super(参数)的是用来调用父类中具有相同形式的构造函数,this(参数)则用来调用当前具有相同参数的构造函数;

 

②当子类的成员变量或者方法与父类的成员变量或者方法同名的情况下,需要调用父类的成员变量和方法

子类中的成员变量或方法名优先级高,所以子类中的同名成员变量或方法就隐藏了父类的成员变量或方法,但是我们如果想要使用父类中的这个成员变量或方法,就需要用到super.

 

 

 

 

 

posted on 2013-04-27 21:51  Cat Liang  阅读(178)  评论(0)    收藏  举报