一、继承
1. 继承的概念
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
-
通过extends关键字可以实现类与类的继承
class 子类名 extends 父类名{ }
单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。
有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。
继承中类之间体现的是:"is a"的关系
2.继承的语法
class Fu{
//相同的属性和行为(公共财产)
}
class Zi extends Fu{
//自己的新的行为和属性
}
public class Demo{
}
3.继承案例
class Person{ //人类
String name;
int age;
public void eat(){
System.out.println("吃饭");
}
}
//学生类
class Student2 extends Person{
}
//老师
class Teacher2 extends Person{
}
public class Demo2 {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu.name);
System.out.println(stu.age);
stu.eat();
Teacher teacher = new Teacher();
teacher.name ="doubleyong";
teacher.age = 18;
teacher.eat();
System.out.println(teacher.name);
System.out.println(teacher.age);
}
}
4.继承的优点和缺点
- 继承的优点:
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类产生了关系,是多态的前提
- 继承的缺点(弊端):
- 让类与类产生了关系 (让耦合增强了)
原则 : 高内聚,低耦合
5.继承的特点
java中继承只能单继承,不能多继承
java中继承支持多层继承
6.继承的注意事项
A. 子类只能继承父类所有的非私有的成员(成员属性和成员方法)
B. 子类不能继承父类的构造方法, 但是可以通过 super关键字去访问父类的构造方法
C:不要为了部分功能而继承
class A{
public void show1(){ }
public void show2() {}
}
class B {
public void show2(){ }
public void show3(){}
}
class B extends A{
public void show3(){}
}
//这样其实不好,为什么呢? 因为不光继承了show2, 还继承了show1
我们什么时候才去使用继承呢?
继承中类之间体现的是:"is a"的关系
Person
Student
Teacher
动物
狗
猫
通过假设法,判断是否满足is-a的关系
如果有两个类A,B , 只要符合A是B的一种,或者B是A的一种,这个时候就可以考虑使用继承
7.继承中成员变量的关系
类的组成:
成员属性
构造方法
成员方法
我们应该考虑一下,继承后类的各部分之间的关系
继承中成员变量的关系
A:子类成员变量与父类成员变量名称不一样 很简单,直接使用名称调用
B:子类成员变量与父类成员变量名称一样
子类使用变量,查找的顺序
1. 找子类的局部变量
1. 找子类的成员变量
1. 找父类的成员变量
1. 如果还找不到, 就报错
8.super关键字
- this 与 super 的区别?分别是什么?
this 代表当前类的对象
super 代表父类的对象(super 代表父类存储空间的标识 ), 可以通过super去操作父类的属性和方法
- 怎么用?
1.调用成员
this.成员变量;
super.成员变量; super.成员方法();
2.调用构造函数
this(…) 调用本类的构造方法
super(…) 调用父类名的构造方法
9.继承中构造方法的关系
-
子类中所有的构造方法默认都会访问父类的无参构造方法
为什么?
因为子类会继承父类中的数据,可以还会使用父类的数据
所以,子类初始化之前,一定要先完成父类的数据初始化
注: 子类每个构造方法的第一句默认都是:super()
子类初始化之前,一定要先完成父类的数据初始化
一个类的初始化:
- 默认值初始化
- 显示初始化
- 构造方法初始
继承中构造方法的注意事项
如果父类中没有无参构造方法,会怎么
(报错)
怎么办?
- 给父类加一个无参构造方法
- 子类通过super(…)去调用有参的父类构造方法
- 子类通过this去调用本类的其他构造方法, 其它的构造方法,必须先访问父类构造方法
注意:
this(…), super(…) 都必须放到第一个句中, 不放到可能会父类多初始化
10.继承中成员方法的关系
继承中成员方法的关系
-
子类方法和父类方法,声明不一样, 这个很简单
-
子类方法与父类方法,声明一样, 调用哪一个
通过子类调用方法:
a. 先找子类中有没有这个方法,有就使用
b. 再看父类中有没有这个方法,有就使用
c. 如果都没有就报错
class X {
Y b = new Y();
X() {
System.out.print("X");
}
}
class Y {
Y() {
System.out.print ("Y");
}
}
// Y X Y Z
public class Demo9 extends X {
Y y = new Y();
Demo9() {
//super();
System.out.print("Z");
}
public static void main(String[] args) {
new Demo9();
}
}
二、重写
子类与父类方法相同是,我们应用的是子类,所以可以称 子类 重写 父类的方法, java中这种情况为: 重写
重载( overload ) : 在同一个类中, 方法名相同,参数类型不同,或参数的个数,称为重载 (注: 和返回值没有关系)
重写( override ) : 继承关系中, 子类去重写(复写/覆盖)父类已经有的方法,方法的声明要一致(包括方法名,返回值,参数都要一致)
重写的注意事项
-
父类的私有方法不能重写,因为父类的私有方法根本没有办法进行继承
-
子类在重写父类时 权限不能更低 (最好保持一致)
-
父类静态方法,子类必须是静态方法,通过静态方法重写
权限修饰符:
public
private
default
protected
@Override // 通过它检查是否去重写了父类的方法,可以写也可以不写,如果写了,必须是重写的方法,也就是说它的方法名必须和父类中可以重写的方法名中有一个相同
public void call(){
System.out.println("给张三打电话");
}
一句话: 继承可以多层继承
三、final 关键字
final:最终的意思。常见的是它可以修饰类,方法,变量
final修饰的类: 此类就不能被继承了
final修饰的方法: 方法不能被重写(覆盖/复写)
final修饰的变量: 此就是不能被重新赋值,因为被它修饰变量其实就是常量
常量:
1. 字面量常量
“hello”,6,true
2. 自定义常量(符号常量)
final int 常量名= 值; //常量 ,全大写
final修饰局部变量
局部变量:
基本类型:值不能变
引用类型: 地址值不能变,但地址值指向的堆中存储的数据值可以改变
final只初始化1次;
明天: 多态
测试:
第一题:概念辨析
-
什么叫做类与类的继承,作用是什么?
-
继承后,父类与子类之间,各成员有什么样的影响?
-
子类中,如何调用父类的成员?如何使用本类的成员?
第二题:语法练习
语法点:继承
编写步骤:
-
模拟农学院动物医疗系统信息。
-
定义父类家禽类(Poultry)
-
- 私有成员变量:动物种类(name),症状(symptom),年龄(age), 病因(illness)
- 提供空参和带参构造方法
- 成员方法:
-
-
-
普通方法方法症状(showSymptom)
-
普通方法基本信息(showMsg)
-
提供setXxx和getXxx方法
定义子类鸭子类(Duck) 1. 提供空参和带参构造方法 2. 重写showSymptom方法,打印症状信息。
-
-
第三题:语法练习
语法点:继承 按步骤编写代码
编写步骤
- 模拟汽车网站信息。
- 定义汽车Auto类 1. 属性:品牌,车长,价格
- 定义SUV继承Auto类 1. 属性:小型车车长标准值:4295,中型车车长标准值:5070。 2. 定义判断车型方法 1. 判断小型车:小于小型车车长标准值 2. 判断大型车:大于中型车车长标准值 3. 判断中型车:大于小型车车长标准值并且小于等于中型车车长标准值
- 测试类中,创建若干SUV对象,保存到数组,遍历数组,输出中型SUV。