1.构造方法中的应用:
在Java中,子类的构造过程中,必须调用其父类的构造函数,是因为有继承关系存在时,子类要把父类的内容继承下来。
当你new一个子类对象的时候,必须首先要new一个父类的对象出来,这个父类对象位于子类对象的内部,所以说,子类对象比父类对象大,子类对象里面包含了一个父类的对象,这是内存中真实的情况.构造方法是new一个对象的时候,必须要调的方法,这是规定,要new父类对象出来,那么肯定要调用其构造方法,所以:
第一个规则:子类的构造过程中,必须调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法,所谓默认的构造方法,就是没有参数的构造方法,但是如果你自己写了构造方法,那么编译器就不会给你添加了,所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是在子类构造方法中我们并没有显式的调用父类的构造方法,就是没写super(); 虽然并没有这样写,但是编译器会调用父类没有参数的构造方法,如果父类中没有没有参数的构造方法就会出错。
第二个规则:如果子类的构造方法中没有显式的调用父类构造方法,则系统默认调用父类无参数的构造方法。注意:如果子类的构造方法中既没有显式的调用父类构造方法,而父类中又没有默认无参的构造方法,则编译出错,所以,通常我们需要显式的用super(参数列表),来调用父类有参数的构造函数。
//当你没有使用父类默认的构造方法时,此时在子类的构造方法中就需要显示的调用父类定义的构造方法。
class Animal{
private String name;
//如果你定义一个新的构造方法
public Animal(String name) {
this.name = name;
}
}
public Dog extends Animal{
//这时你就要显式的调用父类的构造方法,因为子类默认调用的是父类的
//无参构造方法Animal(),但父类中没有该构造方法,如果不显式调用有参构造就会出错。
public Dog(){
super("小狗"); //显式调用父类的有参构造方法
.... //子类的构造方法处理
}
}
//当然,如果你在父类里面把无参的构造方法,显式的写出来了,比如:
class Animal{
private String name;
//无参的构造方法
public Animal() {
..... //处理
}
//有参构造方法
public Animal(String name) {
this.name = name;
}
如果你在父类中显式地定义一个无参构造方法,那么在子类的构造方法中,就可以不用显示的调用父类的构造方法了,因为
子类会在构造方法中自动调用父类已经定义的无参构造方法。
*/
}
/*
* }
}
总结:不过一般的,在父类中使用了构造方法的重载,如写了几个有参构造而没有写无参构造,在子类中就要根据需要,显式地使用super关键字来调用相应的父类构造方法。
2. 在一般方法中子类调用父类的方法时,可以用super.父类方法名(参数),来调用父类的方法。
通常情况下,子类默认继承父类的方法,所以这个super是可以省略的。例如在Animal类中有方法,
public void printName(String s){
system.out.println(s);
}
子类Dog类中有方法需要调用到Animal中的方法时,可以省略super。
public void getParrentName(){
system.out.println( "PP的名字是:" + super.printName("藏獒") );
system.out.println( "PP的名字是:" + printName("藏獒") );//省略super,因为子类可以继承父类的方法,相当于子类本身就有该方法,不用显式地写出super.
}
但如果子类重写了父类的方法,如,在Dog类中有方法:
public void pringName(String s){
system.out.print("子类的方法:" + s);
}
那么getParrentName()方法中,不省略super的话,就调用父类的方法super.printName("藏獒");返回“PP的名字是:藏獒”。而没有super的话,会打印出“PP的名字是:子类的方法:藏獒”。但要注意如果在父类中的方法是个递归方法,那么如果子类重写了该方法,并且子类在其他方法中调用了该递归方法,那么此时,父类的递归方法只会被传入的参数调用最外面的一层,而里层的递归,因为子类重写了该方法而调用子类的方法返回f(n-1)的结果。不会递归调用父类方法中的f(n-1).