十一.继承
一.概述及格式
继承主要解决的问题就是:共性抽取
继承当中的特点:
- 子类可以拥有父类的“内容”。
- 子类还可以拥有自己专有的内容。
* 在继承的关系中:“子类就是一个父类”,也就是说,子类可以被当做父类对待。
*
* 定义父类的格式:(一个普通类定义)
* public class 父类名称{
* //...
* }
*
* 定义格式:public class 子类名称 extends 父类名称{
* //...
* }
Assistant.java
package Day09.Demo01;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月27日 18:37
*/
//定义来一个员工的子类:助教
public class Assistant extends Employee{
}
Teacher.java
package Day09.Demo01;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月27日 18:07
*/
//定义来一个员工的子类:讲师
public class Teacher extends Employee{
}
Employee.java
package Day09.Demo01;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月27日 18:06
*/
//定义一个父类:员工
public class Employee {
public void method(){
System.out.println("方法执行!");
}
}
Demo01Extends.java
package Day09.Demo01;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月27日 17:52
*/
public class Demo01Extends {
public static void main(String[] args) {
//创建了一个子类对象
Teacher teacher = new Teacher();
//teacher类当中虽然什么都没写,但是会继承来自父类的method方法。
teacher.method();
//创建了另一个子类对象
Assistant assistant = new Assistant();
assistant.method();
}
}
二.继承中成员变量的访问
* 在父子类的继承关系中,如果成员变量重名,则创建了子类对象时,访问有两种方法:
*
* 直接访问子类对象访问成员变量
* 等号左边是谁 就优先使用 没有则向上找
* 间接通过成员方法访问成员变量
* 该方法属于谁,就优先使用谁,没有则向上找
Father.java
package Day09.Demo02;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 10:20
*/
public class Father {
int numFu = 10;
int number = 100;
public void methodFather(){
System.out.println(number);//使用本类当中的,不会去子类中查找
}
}
Son.java
package Day09.Demo02;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 10:21
*/
public class Son extends Father{
int numSon = 20;
int number = 200;
public void methodSon(){
System.out.println(number);//本类当中有number,所以使用的是本类当中的number
}
}
Demo01Extends.java
package Day09.Demo02;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 10:21
*/
public class Demo01Extends {
public static void main(String[] args) {
Father father = new Father();//创建父类对象
System.out.println(father.numFu);//只能使用父类的东西,没有任何子类内容
System.out.println("================");
Son son = new Son();
System.out.println(son.numFu);
System.out.println(son.numSon);
System.out.println("================");
//等号左边是谁,就先使用谁
System.out.println(son.number);//优先子类
//各处均没有的情况下,编译报错
// System.out.println(son.abc);
System.out.println("================");
son.methodSon();//子类的方法,优先使用子类的,没有的话向上找
son.methodFather();//这个方法是父类的,定义位置是父类,可以继承使用
}
}
三.区分子类方法中的重名问题
* 局部变量: 直接写成员变量名
* 本类的局部变量: this.成员变量名
* 父类的成员变量: super.成员变量名
Father.java
package Day09.Demo03;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 10:56
*/
public class Father {
int num = 10;
}
Son.java
package Day09.Demo03;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 10:56
*/
public class Son extends Father{
int num = 20;
public void method(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
Demo01Extends.java
package Day09.Demo03;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 10:56
*/
public class Demo01Extends {
public static void main(String[] args) {
Son son = new Son();
son.method();
}
}
四.继承中成员方法访问特点
* 在父子类的继承关系当中,创建子类对象,访问成员方法的规则
* 创建的对象是谁 ,就优先使用谁,如果没有,则向上找
*
*注意事项:
* 无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类得到
Father.java
package Day09.Demo04;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 11:05
*/
public class Father {
public void methodFather(){
System.out.println("父类方法执行!");
}
public void method(){
System.out.println("父类重名方法执行!");
}
}
Son.java
package Day09.Demo04;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 11:06
*/
public class Son extends Father{
public void methodSon(){
System.out.println("子类方法执行!");
}
public void method(){
System.out.println("子类重名方法执行!");
}
}
Demo01Extends.java
package Day09.Demo04;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 11:07
*/
public class Demo01Extends {
public static void main(String[] args) {
Son son = new Son();
son.methodFather();
son.methodSon();
//创建的是new子类的对象,所以优先使用子类方法
son.method();
}
}
五.继承中方法的覆盖重写
重写(Override):
概念:在继承关系当中,方法的名称一样,参数列表也一样;
重写(Override)和重载(Overload)的区别:
重写:方法的名称一样,参数列表【也一样】,覆盖,覆写
重载:方法的名称一样,参数列表【不一样】,
方法的覆盖重写:创建的是子类对象,择优先使用子类方法。
* 方法覆盖重写的注意事项:
* 1.必须保证父子类之间方法的名称相同,参数列表也相同 。
* @Override.写在方法前面,用来检测是不是有效的正确覆盖重写
* 这个注解假设不写,只要满足要求,也是正确的方法覆盖重写
* 2.子类方法的返回值必须小于等于父类返回值的范围。
* 注:Object是一切类的父类
* 3.子类方法的权限必须【大于等于】父类方法的权限修饰符
* 注:public>protected>(default)默认的》private
* 备注:default不是关键字default,而是什么都不写,留空
*
Fu.java
package Day09.Demo05;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 12:51
*/
public class Fu {
public Object method(){
return null;
}
}
Zi.java
package Day09.Demo05;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 12:51
*/
public class Zi extends Fu{
@Override
public String method(){
return null;
}
}
Demo01Overrides.java
package Day09.Demo05;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 12:50
*/
public class Demo01Overrides {
public static void main(String[] args) {
}
}
继承就是这个设计原则的具体体现:对于已经投入使用的类,尽量不要进行修改,推荐定义一个新的类,来重复利用其中共性内容,并且添加改动新内容。
Phone.java
package Day09.Demo06;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 15:46
*/
public class Phone {
public void call(){
System.out.println("打电话。");
}
public void send(){
System.out.println("发短信。");
}
public void show(){
System.out.println("显示号码。");
}
}
NewPhone.java
package Day09.Demo06;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 15:49
*/
public class NewPhone extends Phone{
@Override
public void show() {
super.show();//重复利用父类的方法
//子类添加更多的内容
System.out.println("显示头像。");
System.out.println("显示头像。");
}
}
Demo01Phone.java
package Day09.Demo06;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 15:52
*/
public class Demo01Phone {
public static void main(String[] args) {
Phone phone = new Phone();
phone.call();
phone.send();
phone.show();
System.out.println("==================");
NewPhone newPhone = new NewPhone();
newPhone.call();
newPhone.send();
newPhone.show();
}
}
六.继承中构造方法的访问
/**
* 继承关系中,父子类构造方法的访问特点
* 1.子类构造方法方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造
* 2.子类构造可以通过super关键字来调用父类重载构造。
*
* 3.super父类的构造调用,必须是子类构造方法的第一个语句。不能一个子类构造用多次super构造。
* 总结:
* 子类必须调用父类构造调用方法,不写则赠送super(),写了则用写的指定的的super调用,super只能有一个,而且还必须是第一个语句。
*
* */
Fu.java
package Day09.Demo07;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:18
*/
public class Fu {
public Fu(){
System.out.println("父类构造方法1。");
}
public Fu(int num){
System.out.println("父类构造方法2");
}
}
Zi.java
package Day09.Demo07;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:18
*/
public class Zi extends Fu{
public Zi(){
// super();//在调用父类无参构造方法
super(10); //在调用父类重载的构造方法
System.out.println("子类构造方法。");
}
public void method(){
// super();//错误写法!只有子类构造方法,才能调用父类构造方法
}
}
Demo01Constructor.java
package Day09.Demo07;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:17
*/
public class Demo01Constructor {
public static void main(String[] args) {
Zi zi = new Zi();
}
}
七.super关键字
super关键字的用法有三种:
- 1.在子类的成员方法中,访问父类的成员变量。
- 2.在子类的成员方法中,访问父类的成员方法。
- 3.在子类的构造方法中,访问父类的构造方法。
Fu.java
package Day09.Demo08;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:48
*/
public class Fu {
int num = 10;
public void method(){
System.out.println("父类方法。");
}
}
Zi.java
package Day09.Demo08;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:48
*/
public class Zi extends Fu{
int num = 20;
public Zi(){
super();
}
public void methodZi(){
System.out.println(super.num);
}
public void method(){
super.method();//访问父类的成员方法
System.out.println("子类方法。");
}
}
八.this关键字
super关键字用来访问父类内容,而this关键字用来访问本类内容,用法也有三种
- 1.在本类的成员方法中,访问本类的成员变量。
- 2.在本类的成员方法中,访问本类的另一个成员方法。
- 3.在本类的构造方法中,访问本类的另一个构造方法。
- 在第三种用法当中要注意:
- 1.this(…),调用也必须是构造方法的第一个语句。唯一一个。
- 2.super和this两种构造调用,不能同时使用。
Fu.java
package Day09.Demo09;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:58
*/
public class Fu {
int num = 30;
}
Zi.java
package Day09.Demo09;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 16:58
*/
public class Zi extends Fu{
int num = 20;
public Zi(){
this(132);//本类的无参构造,调用本类的有参构造
}
public Zi(int n){
this(1,2);
}
public Zi(int n1,int n2){
}
public void showNum(){
int num = 10;
System.out.println(num);//局部变量
System.out.println(this.num);//本类中的成员变量
System.out.println(super.num);//父类中的成员变量
}
public void methodA(){
System.out.println("AAA");
}
public void methodB(){
this.methodA();
System.out.println("BBB");
}
}
九.内存图
Fu.java
package Day09.Demo10;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 18:30
*/
public class Fu {
int num = 10;
public void method(){
System.out.println("父类方法。");
}
}
Zi.java
package Day09.Demo10;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 18:32
*/
public class Zi extends Fu {
int num = 20;
@Override
public void method() {
super.method();
System.out.println("子类方法。");
}
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
Demo.java
package Day09.Demo10;
/**
* @author hyhWTX
* @version 1.0
* @date 2022年02月28日 18:47
*/
public class Demo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
zi.method();
}
}
十.与继承有关的特点
- Java语言是单继承的:一个类的直接父类只能有唯一一个。
- Java语言可以多级继承:子类有一个父类,但父类还有一个父类,(祖类是java.lang.Object类)。
- 一个子类的直接父类是唯一的,但是一个父类可以拥有多个子类,可以有很多个兄弟姐妹类。