继承概述

继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性方法

继承的格式

  • 格式:public class 子类名 extends 父类名 {}
  • 范例:public class Zi extends Fu {}
  • Fu:是父类,也被称为基类,超类
  • Zi:是子类,也被称为派生类

继承中子类的特点

  • 子类可以有父类的内容
  • 子类还可以有自己特有的内容

继承的好处和弊端

继承好处

  • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
  • 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

继承弊端

  • 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性

什么时候使用继承?

  • 继承体现的关系:is a
  • 假设法:我有两个类A和B,如果他们满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承
  • 举例:苹果和水果,猫和动物,猫和狗

继承中变量的访问特点

在子类方法中访问一个变量

  • 子类局部范围找
  • 子类成员范围找
  • 父类成员范围找
  • 如果都没有就报错(不考虑)

super

super关键字的用法和this关键字的用法相似

  • this:代表本类对象的引用
  • super:代表父类存储空间的标识(可以理解为父类对象引用)
关键字 访问成员变量 标题访问构造方法 访问成员变量
this this.成员变量
访问本类成员变量
this(…)
访问本类构造方法
this.成员方法(…)
访问本类成员方法
super super.成员变量
访问本类成员变量
super(…)
访问本类构造方法
super.成员方法(…)
访问本类成员方法
代码
1
2
3
4
5
6
7

package unit_11jicheng.test1;
//父类
public class Fu {
public int age = 40;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

package unit_11jicheng.test1;
//子类
public class Zi extends Fu {
public int age = 20;

public void show(){
int age = 30;
System.out.println(age);
//要访问本类的成员变量age,怎么办?
System.out.println(this.age);
//要访问父类的成员变量age,怎么办?
System.out.println(super.age);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13

package unit_11jicheng.test1;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.show();
}
}

继承中构造方法的访问特点

子类中所有的构造方法默认都会访问父类中无参的构造方法

  • 因为子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化之前,一定要先完成父类数据的初始化
  • 每一个子类构造方法的第一条语句默认都是:super()

如果父类中没有无参构造方法,只有带参构造方法,怎么办?

  • 通过使用super关键字去显示的调用父类的带参构造方法
  • 在父类中自己提供一个无参构造方法

推荐:自己给出无参构造方法

继承中成员方法的访问特点

通过子类对象访问一个方法

  • 子类成员范围找
  • 父类成员范围找
  • 如果都没有就报错(不考虑父亲的父亲…)

super内存图

方法重写

方法重写描述

  • 子类中出现了和父类中一模一样的方法声明

方法重写的应用

  • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容

@Override

  • 是一个注解
  • 可以帮助我们检查重写方法声明的正确性
代码
1
2
3
4
5
6
7
8
9
10
11

package unit_11jicheng.test2;
/*
手机类
*/
public class Phone {
public void call(String name){
System.out.println("给"+name+"打电话");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

package unit_11jicheng.test2;
/*
新手机类
*/
public class NewPhone extends Phone {

/* public void call(String name){
System.out.println("开启视频");
//System.out.println("给"+name+"打电话");
super.call(name);
}
*/
@Override
public void call(String name) {
System.out.println("开启视频");
//System.out.println("给"+name+"打电话");
super.call(name);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

package unit_11jicheng.test2;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Phone p = new Phone();
p.call("林青霞");
System.out.println("---------------");
NewPhone np = new NewPhone();
np.call("林青霞");
}
}


方法重写注意事项

  • 私有方法不能被重写(父类私有成员子类不能继承的)
  • 子类方法访问权限不能更低(public > 默认 > 私有)

Java中继承的注意事项

  • Java中类只支持单继承,不支持多继承
  • Java中类支持多层继承

案例:老师和学生

需求:定义老师类和学生类,然后写代码测试;最后找到老师类和学生类当中的共性内容,抽取出一个父类,用代码继承的方式改写代码,并进行测试

思路:

  1. 定义老师类(姓名,年龄,教书())
  2. 定义学生类(姓名,年龄,学习())
  3. 定义测试类,写代码测试
  4. 共性抽取父类,定义人类(姓名,年龄)
  5. 定义老师类,继承人类,并给出自己的特有方法:教书()
  6. 定义老师类,继承人类,并给出自己的特有方法:教书()
  7. 定义测试类,写代码测试
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

package unit_11jicheng.test3;
/*老师类*/ /*子类*/
public class Teacher extends Person{

public Teacher(){}

public Teacher(String name,int age) {
// this.name = name;
// this.age = age;
super(name,age);
}

public void teach(){
System.out.println("老师教书");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

package unit_11jicheng.test3;
/*学生类*/ /*子类*/
public class Student extends Person{
public Student(){}

public Student(String name,int age){
super(name,age);
}

public void sutdy(){
System.out.println("学生学习");
}
}

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

package unit_11jicheng.test3;
/*人类*/ /*父类*/
public class Person {
private String name;
private int age;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

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

package unit_11jicheng.test3;
/*测试类*/
public class PersonDemo {
public static void main(String[] args) {
//创建老师类对象并进行测试
Teacher t1 = new Teacher();
t1.setName("老师");
t1.setAge(18);
System.out.println(t1.getName()+","+t1.getAge());
t1.teach();

//带参构造方法
Teacher t2 = new Teacher("王东颖",30);
System.out.println(t2.getName()+","+t2.getAge());
t2.teach();

//创建学生类对象并进行测试
Student s1 = new Student();
s1.setName("学生");
s1.setAge(12);
System.out.println(s1.getName()+","+s1.getAge());
s1.sutdy();

//带参构造方法
Student s2 = new Student("舒鑫",16);
System.out.println(s2.getName()+","+s2.getAge());
s2.sutdy();
}
}