Java中Super的用法详解
Java中的super
关键字,就如字面意思,代表的就是超类(父类)。与之相对应的关键字就是this
,就就是当前类。应用到操作的对象来说,分别代表的就是父类对象和当前类对象。
一、Super在方法和属性中的应用:
当父类,子类同时出现相同属性名却带有不同修饰符的属性时,this
,super
就能很好的区分对象要调用的是哪个对象的属性。如:
父类,子类中都有属性name,this,super就把调用很好的区分开来
//父类:
public String name = "动物";
//子类:
private String name = "小鸟";
//子类对象中调用结果:
this.name ==> 小鸟
super.name ==> 动物
1. 实例:
三文件,Application.java,Animal.java(父类),Bird.java(子类)
//Application.java
package com.zctou.oop;
import com.zctou.oop.demo05.Bird;
public class Application {
public static void main(String[] args) {
Bird bird = new Bird();
bird.fly("麻雀");
bird.eat("cat");
}
}
//Animal.java
package com.zctou.oop.demo05;
public class Animal {
public String name = "动物"; //animal's name
Boolean hasLegs = true; // true or false
protected String bodySize = "normal"; //huge, normal or small
private int eyesNum = 2; // exist eyes
protected void eat() {
System.out.println(name + "开吃了!");
}
}
//Bird.java
package com.zctou.oop.demo05;
public class Bird extends Animal{
public String name = "小鸟"; //与父类同属性名,同修饰符
private String bodySize = "small";
public void fly(String name) {
System.out.println(name);
System.out.println(this.name);
System.out.println("调用父类方法: " + super.name + "起飞了!");
}
public void eat(String name) {
System.out.print("利用super关键字调用父类方法:");
super.eat(); //父对象 eat()方法的修饰符为 protected
System.out.print("不带super关键字调用父类方法:");
eat();
}
}
输出:
麻雀
小鸟
调用父类方法: 动物起飞了!
2. 总结:
- 父类的非私有方法和属性都可以被继承。使用在子对象中用
super关键字
都能调用。私有方法和属性都无法被子类调用。- 子类与父类可以有相同的属性名和方法名,且同修饰符。
- 便于区分及代码的可读性,用
this
和super
区分不同对象的属性及方法。
二、 Super在构造器中的应用 :
前面已经了解【过this关键字
在构造器中的应用】,这里再扩展一下super
关键字在构造器中的用法。
生成子类对象时,先调用父类无参构造,后调用子类无参构造。
//Application.java package com.zctou.oop; import com.zctou.oop.demo05.Fish; public class Application { public static void main(String[] args) { Fish fish = new Fish(); } } // Animal.java package com.zctou.oop.demo05; public class Animal { public Animal() { System.out.println("Animal类(父类)无参构造被调用!"); } } //Fish.java package com.zctou.oop.demo05; public class Fish extends Animal { public Fish() { System.out.println("Fish类(子类)无参构造被调用!"); } private String name = "大鱼"; } //输出: Animal类(父类)无参构造被调用! Fish类(子类)无参构造被调用!
可以看到new Fish()的时候,先调用的是父类Animal的无参构造,再调用子类Fish的无参构造。
如果没有显式定义,在子类无参构造中,系统也会默认加上
super()
调用父类无参构造:如在
Fish.java
的无参构造中加入显式定义:package com.zctou.oop.demo05; public class Fish extends Animal { public Fish() { super(); //加入显式定义: System.out.println("Fish类(子类)无参构造被调用!"); } } //输出: Animal类(父类)无参构造被调用! Fish类(子类)无参构造被调用!
手动加显示定义
super()
的输出结果跟没加上super()
的样,因为系统默认就加上父类的无参构造调用语句super()
;与
this
一样,super同样要放在第一行,且构造中this()
与super()
不能同时存在。如在Fish.java
中同时加入this与super:package com.zctou.oop.demo05; public class Fish extends Animal { public Fish() { this(); //this(),super()同时存在 super(); System.out.println("Fish类(子类)无参构造被调用!"); } } //输出: java: 对super的调用必须是构造器中的第一个语句
可以看到,运行结果报错,提示super调用要第一个语句。IDEA编辑时报的错误为 “Call to 'super()' must be first statement in constructor body”。
父类定义了有参构造而没有显式定义无参时,子类同样无法定义无参构造,也无法调用父类无参。如Animal.java中只定义有参构造,子类定义无参时会报错。
// Animal.java 只定义无参,没有显式定义无参构造 package com.zctou.oop.demo05; public class Animal { public Animal(String s) { System.out.println("Animal类(父类)无参构造被调用!"); } }
报错信息:
父类中无法找到默认的构造器
。子类调用父类无参
super()
同样的错误提示:
三、小结
Super 与 This 的几个主要区别:
super 与 this 指代的对象:
super 指向的是子对象对父类对象的引用,而this批向的是自己(即调用的这个对象)。
使用条件的区别:
this不需要继承关系,super只能出现在继承关系的子类中。
在构造方法中的区别:
this是本类构造,super是父类构造。
都不显式定义的情况下,子类默认调用父类无参构造super()。- 在构造方法中,super和this都要写第一行,因此两者只能同时在于一个。