super和this很类似,可以对比着学习
1、先复习一下this关键字的使用
- this指向的是当前对象自己
- this能出现在实例方法和构造方法中;
- this的语法是“this.”和“this()”;
- this不能出现在静态方法中;
- this大部分情况下是可以省略的;
- this.什么时候不能省略呢?
在区分局部变量和实例变量时不能省略 this()只能出现在构造方法的第一行
,通过当前的构造方法去调用“本类”中的对应的构造方法,目的是:代码复用。
Public void setName(String name){
this.name = name;
}
2、super关键字:
- super指向的是当前对象自己的父类型特征(也就是继承过来的那些东西)
- super能出现在实例方法和构造方法中。
- super的语法是“super.”和“super()”。
- super不能出现在静态方法中。
- super大部分情况下是可以省略的。
- super.什么时候不能省略呢?
当子类中重写覆盖了父类一样的属性或者方法,此时,你要想去调用父类的那个属性或者方法,此时“super.”不能省略。 super()只能出现在构造方法的第一行
,通过当前的构造方法去调用“父类”中的对应的构造方法,目的是:创建子类对象时,先初始化父类型特征
注意:
因为“this()”和“super()”都只能出现在构造方法的第一行,所以构造方法中“this()”和“super()”不能同时出现
super() 的用法
俗话讲,要想有儿子,得先有父亲
以下代码,Cat继承Animal
public class Test{
public static void main(String[] args){
Cat c1 = new Cat();
}
}
//父类,Animal类
class Animal {
//构造函数
public Animal() {
System.out.println("Animal类的无参数构造函数执行");
}
}
//子类,Cat类
class Cat extends Animal{
//构造函数
public Cat() {
System.out.println("Cat类的无参数构造函数执行");
}
}
执行结果:
- Animal类的无参数构造函数执行
Cat类的无参数构造函数执行
执行子类的无参构造的时候,会先执行父类的无参构造器
所以不管你创建什么对象,Object对象的无参数构造方法一定会先执行,因为Object是所有类的根类
当子类的构造方法内第一行没有出现super()
时,系统会默认给它加上无参数的super()
方法。就像定义类的时候,若没有手写有参构造器,会先默认加上无参构造器
public class Test {
public static void main(String[] args) {
new C();
new C("草莓");
new C("x",10,"d");
}
}
class B{
private int i;
private String s;
//构造方法
public B(){
System.out.println("B的无参");
}
public B(int i,String s){
System.out.println(i+","+s);
}
//set、get方法
public void setI(int i){
this.i = i;
}
public int getI(){
return i;
}
public void setS(String s){
this.s = s;
}
public String getS(){
return s;
}
}
class C extends B{
private String name;
//构造方法
public C(){
System.out.println("C的无参");
}
public C(String name){
System.out.println(name);
}
public C(String name,int i,String s){
super(i,s);
System.out.println(name);
}
//set、get方法
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
执行结果:
不管是子类的有参构造器还是无参构造器,只要没有定义super(实参);
,就会默认在第一行给一个无参的super();
当子类构造方法执行有参数的super(参数列表)
方法,你得确保父类中也有对应的有参数构造方法,不然会编译报错
当子类构造方法的第一行执行super()
无参数方法,那么父类中一定要有无参数构造方法。注意手动补上无参数的构造方法
//错误代码
public class Person {
public Person(String name) {
}
}
public class Student extends Person {}
以上代码会发现Student类出现编译错误,提示必须显示定义构造方法
之所以会报错,是因为默认给Student类加了一个无参构造方法,同时默认加上无参数的super()
方法,但是Person类中并不存在无参数构造方法
以下为示例: 声明父类 Person,类中定义两个构造方法
public class Person {
public Person(String name, int age) {}
public Person(String name, int age, String sex) {}
}
子类Student继承了Person类,使用super语句来了定义Student类的构造方法
public class Student extends Person {
//若是调用这个构造方法,那么输出 name 和 age 是父类中的数据
public Student(String name, int age, String birth) {
// 调用父类中含有2个参数的构造方法
super(name, age);
}
public Student(String name,int age,String sex,String birth) {
// 调用父类中含有3个参数的构造方法
super(name, age, sex);
}
}
super()到底什么时候使用?来看下面代码:
public class MyTest {
public static void main(String[] args) {
Cat c1 = new Cat(3);
System.out.println("名字:" + c1.getName() + ",年龄:" + c1.getAge());
}
}
//父类,Animal类
class Animal {
//私有属性:名字
private String name;
//此处省略setter and getter
//构造函数
public Animal() {}
public Animal(String name) {
this.name = name;
}
}
//子类,Cat类
class Cat extends Animal{
//私有字段:年龄
private int age;
//此处省略setter and getter
//构造函数
public Cat() {}
public Cat(int age) {
this.age = age;
}
}
执行结果:
- 名字:null
年龄:3
因为此处并没有给父类中的name
定义数据,所以我们给Cat加一个构造方法,给name和age都赋值
//错误代码
public Cat(String name, int age) {
this.name = name; //报错
this.age = age
}
显然这样做是会报错的,因为name已经被父类封装成private的了,不能直接访问
public Cat(String name, int age) {
setName(name);
this.age = age;
}
使用super()方法
public Cat(String name, int age) {
super(name);
this.age = age;
}
super. 的用法
1、调用父类成员属性
当子类的成员变量或方法与父类同名时,可以使用 super 关键字来访问父类的成员变量或方法
使用 super 访问父类中的成员与 this 关键字的使用相似,只不过它引用的是子类的父类
父类和子类都有一个成员变量 age
。我们可以使用 super
关键字访问父类中的 age
变量
class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.display();
}
}
class Person {
int age = 12;
}
class Student extends Person {
int age = 18;
public void display() {
System.out.println("学生年龄:" + super.age);
}
}
执行结果:
- 学生年龄:12
2、调用父类成员方法
可以看到如果只调用方法 message( )
,是当前的类message( )
被调用,使用super
关键字时,是父类的message( )
被调用
class Test {
public static void main(String args[]) {
Student s = new Student();
s.display();
}
}
class Person {
public void message() {
System.out.println("父类 person class");
}
}
class Student extends Person {
public void message() {
System.out.println("子类 student class");
}
public void display() {
message();
super.message();
}
}
执行结果:
- 子类 student class
父类 person class
复习this() 和 super()代码
下面给道例题练习一下this()和super()方法:
public class MyTest {
public static void main(String[] args) {
new Cat();
}
}
class Animal {
public Animal() {
super();
System.out.println("1:Animal类的无参数构造函数执行");
}
public Animal(int i) {
super();
System.out.println("2:Animal类的有int参数构造函数执行");
}
}
class Cat extends Animal{
public Cat() {
this("");
System.out.println("3:Cat类的无参数构造函数执行");
}
public Cat(String str) {
super(5);
System.out.println("4:Cat类的有String参数构造函数执行");
}
}
执行结果:
- 2:Animal类的有int参数构造函数执行
4:Cat类的有String参数构造函数执行
3:Cat类的无参数构造函数执行
小结
- this和super一样,都是对象内部的引用变量,只能出现在对象内部;
- this指向当前对象自己,super指向当前对象的父类型特征,故this的东西比super多,也就是super是this的一部分;
- this()和super()都只能出现在构造方法的第一行,故this()和super()方法不能共存,当一个类的构造方法第一行中没有this(),也没有super(),系统默认有super()方法;
- this()是构造方法中调用本类其他的构造方法,super()是当前对象构造方法中去调用自己父类的构造方法