继承
1.1
类和类之间的常见关系。
1
:既然继承是描述类和类之间的关系,就需要先来了解类和类之间的常见关系
1.1.1
现实生活的整体与部分
举例说明
1
:现实生活
1
:学生
是人
2
:狗
是动物
3
:球队
包含
球员
整体与部分的关系,部分可以删除和增加
4
:笔记本包含
cpu
整体与部分的关系,部分不可以删除和增加
5
:航母编队
包含(航母
护卫舰
驱逐舰
舰载机
核潜艇)
1.1.2
java
中的类与类关系
java
中的类关系
1
:
is a
关系
(
学生是人
)
2
:
has a
整体与部分
1.2
继承
1
:描述一个学生类
1
:姓名年龄学号属性,学习的方法
2
:描述一个工人类
1
:姓名年龄工号属性,工作的方法
3
:描述一个人类
1
:姓名年龄属性,说话的方法。
4
:发现学生类和人类天生有着联系,学生和工人都是人。所以人有的属性和行为学生和工人都会有。出现类代码重复
5
:问题
:
1
:如果没有继承
,
出现类和类的关系无法描述
2
:如果没有继承,类和类之间有关系会出现类和类的描述代码的重复。
1.3
继承特点
1
:描述类和类之间的关系
2
:降低类和类之间的重复代码
1
:降低对象和对象之间的代码重复使用静态变量
2
:降低类和类之间的代码重复使用就继承
1.4
extends
关键字
继承使用
extends
关键字实现
1
:发现学生是人,工人是人。显然属于
is a
的关系,
is a
就是继承。
2
:谁继承谁?
学生继承人,发现学生里的成员变量,姓名和年龄,人里边也都进行了定义。有重
复代码将学生类的重复代码注释掉,创建学生类对象,仍然可以获取到注释的成员。这就是因为继承的关系,学生类(子类)继承了人类(父类)的部分
继承细节;
1
:类名的设定,被继承的类称之为父类
(
基类
)
,继承的类称之为子类
2
:子类并不能继承父类中所有的成员
1
:父类定义完整的成员
静态成员,非静态,构造方法。静态变量和静态方
法都可以通过子类名
.
父类静态成员的形式调用成功。
2
:
所有的私有成员不能继承
,private
修饰的成员。
3
:
构造函数不能被继承
3
:如何使用继承
1
:不要为了使用继承而继承。工人和学生都有共性的成员,不要为了节省代
码,让工人继承学生。
1.5
super
关键字
1
:定义
Father(
父类
)
类
1
:成员变量
int x=1;
2
:构造方法无参的和有参的,有输出语句
2
:定义
Son
类
extends Father
类
1
:成员变量
int y=1;
2
:构造方法无参和有参的。有输出语句
1
:
this.y=y+x;
3
:创建
Son
类对象
Son son=new Son(3);
System.out.println(son.y); //4
4
:子类对象为什么可以访问父类的成员。
1
:
this.y=y+x;
有一个隐式的
super super.x
5
:
super
关键字作用
1
:主要存在于子类方法中,用于指向子类对象中父类对象。
2
:访问父类的属性
3
:访问父类的函数
4
:访问父类的构造函数
6
:
super
注意
super关键字调用父类构造方法要注意的事项:
1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。
2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的
第一个语句
。
3. super与this关键字不能同时出现在同一个构造函数中
调用其他的构造函数
。因为两个语句都需要第一个语句。(this.name = name可以)
this
和
super
很像,
this
指向的是当前对象的调用,
super
指向的是当前调用对象的父类。
Demo
类被加载,执行
main
方法,
Son.class
加载,发现有父类
Father
类,于是
Father
类也加载进内存。类加载完毕,创建对象,父类的构造方法会被调用(默认自动无参),然后执行子类相应构造创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部。
this super
只能在有对象的前提下使用,不能在静态上下文使用。
2
:子类的构造函数默认第一行会默认调用父类无参的构造函数,隐式语句
super();
1
:父类无参构造函数不存在,编译报错。
3
:子类显式调用父类构造函数
在子类构造函数第一行通过
super
关键字调用父类任何构造函数。如果显式调用父类构造函数,编译器自动添加的调用父类无参数的构造就消失。构造函数间的调用只能放在第一行,只能调用一次。
super()
和
this()
不能同时存在构造函数第一行。
4
:
super
思考
如果开发者自定义了一个类,没有显示的进行类的继承,那么该类中成员函数是否可以使用
super
关健健字?可以使用,继承了
Object
类,
Object
类是所有类的父类。
5
:继承练习
重写(
Override
)
方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。
什么是时候要使用方法的重写:父类的功能无法满足子类的需求时。
1
:定义
Father
类
1
:姓名,吃饭方法,吃窝窝头。
2
:定义
Son
类,继承
Father
1
:
Son
类中不定义任何成员,子类创建对象,仍然可以调用吃饭的方法。
2
:父类的吃饭的方法,
Son
不愿吃。
Son
自己定义了吃饭的方法。
1
:此时父类中有一个吃饭的方法,子类中有
2
个吃饭的方法,一模一样,只是方法体不一样。
2
:一个类中两个函数一模一样,是不允许的。
1
:编译运行,执行了子类的方法。
2
:使用父类的方法,在子类方法中,使用
super.
父类方法名。
3
:该现象就叫做重写
(
覆盖
override)
1
:
在继承中,子类可以定义和父类相同的名称且参数列表一致的函数,将这种函数
称之为函数的重写
.
4
:前提
1
:必须要有继承关系
5
:特点
1
:当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数。
可以通过
super
关键字进行父类的重写函数的调用。
2
:
继承可以使得子类增强父类的方法
6
:细节
1
:
函数名必须相同
2
:参数列表必须相同
3
:
子类重写父类的函数的时候,函数的访问权限必须大于等于父类的函数的访
问权限否则编译报错
4
:子类重写父类的函数的时候,返回值类型必须是父类函数的返回值类型或该返回值类型的子类。不能返回比父类更大的数据类型:
如子类函数返回值类型是
Object
1
:定义
A B C
类
B extends A
2
:
Father
类中定义
A getA();
3
:
Son
类中重写
getA();
方法,尝试将返回值修改为
B
,
C ,Object
1
:
B
编译通过
2
:
C
编译失败
,
没有继承关系
3
:
Object
编译失败
,
比父类的返回值类型更大
7
:子类对象查找属性或方法时的顺序:
1
:原则:就近原则。
如果子类的对象调用方法,默认先使用
this
进行查找,如果当前对象没有找到属性或方法,找当前对象中维护的
super
关键字指向的对象,如果还没有找到编译报错,找到直接调用。
8
:
重载和重写的不同
方法重写要注意的事项:
1.方法重写时, 方法名与形参列表必须一致。
2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。
3.方法重写时,子类的返回值类型必须要小于或者 等于父类的返回值类型。
4.方法重写时, 子类抛出的异常类型要小于或者等于父类抛出的异常类型。
Exception(最坏)
RuntimeException(小坏)
方法的重载:在一个类中 存在两个或者两个 以上的同名函数,称作为方法重载。
方法重载的要求
1. 函数名要一致。
2. 形参列表不一致(形参的个数或形参 的类型不一致)
3. 与返回值类型无关。
9
:重写练习
描述不同的动物不同的叫法
1
:定义动物类
有名字,有吃和叫的方法
2
:定义狗继承动物重写父类吃和叫的方法
3
:定义猫继承动物重写父类吃和叫的方法