Java基础——super关键字_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java基础——super关键字

Java基础——super关键字

 2014/6/9 12:27:49  排排坐吃果果  程序员俱乐部  我要评论(0)
  • 摘要:调用超类的构造器子类和普通的类一样,可以利用关键字new来创建它的实例。如果没有在子类中显示编写一个构造器,编译器就会隐式添加一个无参(no-arg)构造器当通过调用子类的某个构造器来将它实例化时,构造器的第一个动作就是调用直接父类的无参构造器。在父类中,构造器也调用其直接父类的构造器。这个过程会不断重复,直到到达java.lang.Object类的构造器为止。换句话说,当创建一个子类时,他所有的父类也就实例化了。下面以Base和Sub类为例演示了这个过程。classBase
  • 标签:Java 关键字

调用超类的构造器

? ? ? ?子类和普通的类一样,可以利用关键字new来创建它的实例。如果没有在子类中显示编写一个构造器,编译器就会隐式添加一个无参(no-arg)构造器

? ? ? ?当通过调用子类的某个构造器来将它实例化时,构造器的第一个动作就是调用直接父类的无参构造器。在父类中,构造器也调用其直接父类的构造器。这个过程会不断重复,直到到达java.lang.Object类的构造器为止。换句话说,当创建一个子类时,他所有的父类也就实例化了。

? ? ? ?下面以BaseSub类为例演示了这个过程。

class="java">class Base {  
    public Base() {  
        System.out.println("Base");  
    }  
    public Base(String s) {  
        System.out.println("Base." + s);  
    }  
}  
  
public class Sub extends Base {  
    public Sub(String s) {  
        System.out.println(s);  
    }  
    public static void main(String[] args) {  
        Sub sub = new Sub("Start");  
    }  
}  

? ? ? ?如果运行Sub类,就会在控制台看到以下结果:

? ? ? ?Base

? ? ? ?Start

? ? ? ?这表明,Sub类的构造器的第一个动作就是调用Base类的无参构造器。Java编译器已经悄悄地将Sub的构造器改成下面的样子,但是,这一修改并没有真正保存到源文件中。

public Sub(String s) {  
    super();  
    System.out.println(s);  
}  

?? ? ? ? 关键字super表示当前对象的直接超类的一个实例。由于super是从Sub的一个实例中调用的,因此super表示其直接超类Base的一个实例。

? ? ? ?通过使用关键字super,可以从子类的构造器显示调用父类的构造器,但super必须是构造器的第一条语句,如果你想调用超类中的另一个构造器的话,使用关键字super是很方便的。例如,可以将Sub中的构造器修改成下面这样:

public Sub(String s) {  
    super(s);  
    System.out.println(s);  
}  

? ? ? ?这个构造器利用super(s),调用父类的单参数构造器。结果,当运行这个类时,就会在控制台中看到以下内容:

? ? ? ?Base.Start

? ? ? ?Start

? ? ? ?那么,如果超类没有无参构造器,并且也没有从子类显示调用另一个构造器,会怎么样呢?以下代码以Parent类和Child类为例做了展示。

class Parent {  
    public Parent (String s) {  
    System.out.println("Parent (String)");  
    }  
}  
  
public class Child extends Parent {  
    public Child() {  
    }  
}  

? ? ? ?这样将会产生一个编译错误,因为编译器添加了一个对Parent中无参构造器的隐式调用,而Parent类只有一个带有String的构造器。只要从Child类的构造器中显示调用父类的构造器,就可以纠正这种问题:

public Child() {  
    super(null);  
}  

? ? ? ?提示对于一个子类而言,能够从它自己的构造器调用其父类的构造器,这是很有意义的事情,因为子类的 实例必须始终配有其每个父类的实例。因此,对子类中未覆盖的方法的调用,将被传递给其父类,直到在该继承层次结构中找到第一个方法为止。

?

调用超类的隐藏成员

? ? ? ?关键字super的存在还有另一个使命。它可以用来调用超类中隐藏的成员,或者覆盖的方法。由于super表示直接父类的一个实例,因此,super.memberName将返回父类中的指定成员。可以访问到超类中能通过子类看到的任何成员。例如,以下代码展示了两个具有父子关系的类:ToolPencil

Class Tool {
    public String toString() {
        return "Generic tool";
    }
}

public class Pencil extends Tools {
    public String toString() {
        return "I am a Pencil";
    }

    public void write() {
        System.out.println(super.toString);
        System.out.println(toString());
    }

    public static void main(String[] args) {
        Pencil pencil = new Pencil();
        Pencil.write;
    }
}

? ? ? ?Pencil类覆盖Tool中的toString方法。如果运行Pencil类,就会在控制台中看到以下结果:

? ? ? ?Generic tool

? ? ? ?I am a pencil

? ? ? ?与调用父类的构造器不同,调用父类的成员的语句不需要放在调用方法中的第一行。

发表评论
用户名: 匿名