言成言成啊 | Kit Chen's Blog

关于继承、方法重写、super和this

2019-09-17

继承

在继承的关系中,子类就是父类。也就是说,子类可以被当做父类来对待。

定义父类的格式:

1
2
3
4
5
public class 父类名称 {

//...

}

定义子类的格式:

1
2
3
4
5
public class 子类名称 extends 父类名称 {

//...

}

在父子类的继承中,如果成员变量重名,则创建子类对象时,访问有两种方式:

  1. 直接通过子类对象访问成员变量:
    等号左边是谁,就优先用谁,没有则向上找;
  2. 间接通过成员方法访问成员变量:
    该方法属于谁,就优先用谁,没有则向上找。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Fu {
int num=100;
public void methodFu() {
System.out.println(num);
}
}
class Zi extends Fu {
int num=200;
public void methodZi() {
System.out.println(num);
}
}
public class Demo02ExtendsField {
public static void main(String[] args) {
Fu fu=new Fu();
Zi zi=new Zi();

System.out.println(zi.num);//200

zi.methodZi();//200;
zi.methodFu();//100;
}
}

继承中的方法重写

局部变量:直接输出

本类的成员变量:this

父类的成员变量:super


方法重写
概念:在继承关系当中,方法的名称一样,参数列表也一样。

重写(Override):方法的名称一样,参数列表也一样。覆盖。[发生在继承关系当中]

重载(Overload):方法的名称一样,参数列表不一样。

方法覆盖的特点
创建的是子类对象,则优先使用子类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Fu1 {
int num=10;
public void methodC() {
System.out.println("父类重名方法执行");
}
}
class Zi1 extends Fu1 {
int num=20;
public void method() {
int num=30;
System.out.println(num);//30 局部变量
System.out.println(this.num);//20 该类中的成员变量
System.out.println(super.num);//10 父类中的成员变量
}
public void methodC() {
System.out.println("子类重名方法执行");
}
}
public class Demo03ExtendsField {
public static void main(String[] args) {
Zi1 zi=new Zi1();
zi.method();
zi.methodC();
}

}

方法重写的注意事项

  1. 必须保证父子类之间的方法的名称相同,参数列表也相同
    @Override:写在方法前面,用来检测是不是有效地正确覆盖重写;这个注解只要不写,只要满足要求,也是正确的方法覆盖重写

  2. 子类方法的返回值必须小于等于父类方法的返回值范围
    前提:Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类;Object是最大的范围,String是他的子类,范围要小。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Fulei {
    public Object method() {
    return null;
    }
    }
    class Zilei extends Fulei {
    @Override
    public String method() {
    return null;
    }
    }
  3. 子类方法的权限修饰符必须大于等于父类方法的权限修饰符
    提示:public>protected>(default)>private
    备注:default不是关键字,是不写的情况下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Fulei {
    void method() {//这个默认是default

    }
    }
    class Zilei extends Fulei {
    @Override
    public void method() {//public

    }
    }

方法重写实际案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Phone {
public void call() {
System.out.println("打电话");
}
public void send() {
System.out.println("发短信");
}
public void show() {
System.out.println("显示号码");
}
}
class NewPhone extends Phone {
@Override
public void show() {
// TODO Auto-generated method stub
super.show();
System.out.println("显示姓名");
System.out.println("显示头像");
}
}
public class Demo05Phone {

public static void main(String[] args) {
// TODO Auto-generated method stub
Phone p=new Phone();
p.call();
p.send();
p.show();

NewPhone np=new NewPhone();
np.call();
np.send();
np.show();
}

}

super关键字

继承关系中,父子类构造方法的访问特点:

  • 1.子类构造方法当中有一个默认隐藏的super()调用。所以一定是先调用父类构造方法,后调用子类构造方法

  • 2.子类构造可以通过super调用父类重载构造

  • 3.super的父类构造调用,必须是子类构造方法的第一个语句(第一个super的语句);

  • 总结:

    子类必须调用父类的构造方法,不写则赠送super();写了,则用指定的super(),super只能是第一个。

总结:

  • super关键字的用法有三种:
  • 1.在子类的成员方法中,访问父类的成员变量
  • 2.在子类的成员方法中,访问父类的成员方法
  • 3.在子类的构造方法中,访问父类的构造方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class F {
public F() {
System.out.println("父类无参构造方法");
}
public F(int num) {
System.out.println("父类有参构造方法");
}
}
class Z extends F {
public Z() {
//super();默认有个隐藏的super();
super(20);
System.out.println("子类构造方法");
}
public void method() {
//super();//此处会报错。只有子类构造方法,才能调用父类构造方法。
}
}
public class Demo06Constructor {

public static void main(String[] args) {
// TODO Auto-generated method stub
Z z=new Z();
}

}

this关键字

super关键字用来访问父类内容,而this关键字用来访问本类内容。

三种用法:

  1. 在本类的成员方法中,访问本类的成员变量
  2. 在本类的成员方法中,访问本类的另一个成员方法
  3. 在本类的构造方法中,访问本类的另一个构造方法
    1. this调用跟super调用一样,也必须是构造方法的第一个语句,也必须是唯一一个
    2. super跟this都必须是第一个,并且两者不能同时使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class{
int num=30;
}
classextends{
int num=20;
public void method(){
int num=10;
System.out.println(num);//10
System.out.println(this.num);//20
System.out.println(super.num);//30
}

public void methodA() {
System.out.println("A");
}
public void methodB() {
this.methodA();//A
System.out.println("B");//B
}
}
阅读量