8.1继承概述

class Student{String name;int age;void study(){System.out.println("Study...");}
}
class Worker{String name;int age;void work(){System.out.println("work...");}
}

以上可以看到的是,多个事物之间由共同的属性或行为,这种代码复用性很差,怎么办?可以将多个事物之间重复性的属性或者行为进行抽取,抽取出来之后放在另一个单独的类里面即可

class Student{void study(){System.out.println("Study...");}
}
class Worker{void work(){System.out.println("work...");}
}
class Teacher{void teach(){System.out.println("teach...");}
}
class Person{String name;int age;
}

虽然我们将Person类抽取出来,但是目前Worker和Student和Teacher与Person有无关系?没有。 如何让类之间产生这种父(Person)子(Worker Student Teacher)的关系,用extends关键字

class Student extends Person{void study(){System.out.println("Study...");}
}
class Worker extends Person{void work(){System.out.println("work...");}
}
class Teacher extends Person{void teach(){System.out.println("teach...");}
}
class Person{String name;int age;
}

总结一句:把多个事物重重复性的内容进行抽取,并生成另一个类,该类就是其他类的父亲,其他类之为子类,子类与父类之间用extends关键字来标明
继承的好处

  • 继承的出现提高了代码的复用性
  • 继承的出现让类与类之间产生关系,也为我们后面多态提供了前提
    单继承与多继承
  • 在现实生活中,父与子一对多关系,子与父一对一
  • 使用继承时,除了要考虑类与类之间重复的内容之外,更重要的是取考虑关系,必须是一种 is a 关系
  • 即XXX是YYY的一种!苹果是水果的一种,狗是动物的一种
  • Java 中类与类之间只能支持单继承,接口与接口之间可以支持多继承
class Demo extends Demo1{}
class Demo extends Demo1.Demo2{}//Error

继承体系
既然有了单继承,也有了父子关系,爷孙关系,曾祖父-重孙,继承出现了层级,继承体系

class A{}
class B extends A{}
class C extends A{}
class D extends A{}
......

需要注意的一些问题

  • 继承和传统稍微理解有一些不同的,子类并不是或是父类的一个子集!实际上,一个子类通常比它的父类包含更多的信息和方法。(子类更多的是父类的一种升级和延申)
  • 父类中的一些私有内容,子类是获取不到的。如果父类对其自身的私有内容设置的公共的访问器和修改器的话,子类可以通过访问该访问器和修改器来获取父类的私有内容。
  • 不要为了获取某一个特殊的属性或行为,而去乱认爸爸
  • 说来说去,总之就是想表达一个观点,在设计类和其继承关系时,一定要符合社会常识认知伦
    理问题
class Bird{void fly(){}
}
class Person extends Bird{}//不合适,不符合现实逻辑关系

子父类中,成员变量的关系

public class Sample{public static void main(String[] args){Zi zi = new Zi();System.out.println(zi.num);}
}
class Fu{int num = 10;
}
class Zi extends Fu{}

子类没有,父类有且非私有,子类对象能获取num

public class Sample{public static void main(String[] args){Zi zi = new Zi();System.out.println(zi.num);}
}
private class Fu{private int num = 10;
}
class Zi extends Fu{}

子类没有,父类有且私有,子类对象不能获取num

public class Sample{public static void main(String[] args){Zi zi = new Zi();System.out.println(zi.num);}
}
class Fu{int num = 10;
}
class Zi extends Fu{int num = 20;
}

子类有,父类有且非私有,子类对象获取的是子类的num 不存在重写的概念

public class Sample{public static void main(String[] args){Zi zi = new Zi();System.out.println(zi.num);}
}
class Fu{}
class Zi extends Fu{int num = 20;
}

子类有,父类没有, 子类对象获取的是子类的num

public class Sample{public static void main(String[] args){Zi zi = new Zi();System.out.println(zi.num);}
}
class Fu{int num = 10;
}
//父类 超类 基类
class Zi extends Fu{int num = 20;void show(){int num = 30;System.out.println(num + "," + this.num + "," + super.num);}
}
运行结果: 30  20  10

如果子类中,成员变量 和 父类变量和 局部变量 重名时,以上就行,这里有一个特殊的super

  • this 表示的是当前对象,存的是当前对象在堆内存中的地址
  • super不表示父类的对象,因为再次我们并没有创建父类的对象!super仅仅表示父类的空间,并没有创建父类的对象!

子父类中,构造函数的特点
public class Sample{
public static void main(String[] args){
Zi zi = new zi();
}
}
class Fu{
fu(){
System.out.println(“Fu show…”);
}
}
class Zi extends Fu{
Zi(){
System.out.println(“Zi show…”);
}
}
可以看到的是,当创建子类对象时,在子类的构造函数执行之前,父类的构造函数先执行,虽然父
类的构造函数执行但不代表父类对象的创建.

  • 每一个类中的构造函数第一句如果不是 this() 调用本类中其他构造函数的话,默认第一句是隐藏的 super()
  • 是因为在创建子类对象的时候,需要父类为继承给子类的一些数据进行初始化。
public class Sample{public static void main(String[] args){Zi zi = new zi();}
}
class Fu{int num;Fu(){System.out.ptintln("Fu show..." + num);num = 4;}
}
class Zi extends Fu{Zi(){super();//调用父类的无参构造函数 默认是隐藏的//父类的构造函数一旦执行完毕,紧接着执行子类成员变量的显示初始化System.out.println("Zi show..." + num);}
}

this() 与super()是否冲突

public class Sample{public static void main(String[] args){Zi zi1 = new Zi();Zi zi2 = new Zi(1);Zi zi3 = new Zi(1,2);}
}
class Fu{int num;Fu(){System.out.println("Fu show..." );}
}
class Zi extends Fu{Zi(){System.out.println("Zi show...0");}Zi(int a){System.out.println("Zi show...1");}Zi(int a ,int b){System.out.println("Zi show...2");}
}

如果子类的构造函数们之间没有调用关系,则每一个子类的构造函数第一句都是 super()

public class Sample{public static void main(String[] args){Zi zi1 = new Zi();Zi zi2 = new Zi(1);Zi zi3 = new Zi(1,2);}
}
class Fu{int num;Fu(){System.out.println("Fu show..." );}
}
class Zi extends Fu{Zi(){this(1);System.out.println("Zi show...0");}Zi(int a){this(1,2);System.out.println("Zi show...1");}Zi(int a ,int b){super();System.out.println("Zi show...2");}
}
/*运行结果Fu show...
Zi show...2
Zi show...1
Zi show...0
Fu show...
Zi show...2
Zi show...1
Fu show...
Zi show...2
*/

在上一段代码中,Fu show的执行,在每一个构造函数中的第一句super()执行
在这一段代码中,Fu show的执行,在Zi(int,int)调用执行的

在构造函数中,第一句要么是this(),要么是super()
有没有可能每一个构造函数第一句都是this()?没有,否则递归调用
有没有可能每一个构造函数第一句都是super()?有,构造函数之间不调用
this()与super()本身不冲突的,如果构造函数之间有调用关系,那么最后一个被调用的构造函
数就不能再回调,那么其第一句就不能是this(),只能是super()

public class Sample{public static void main(String[] args){Zi zi1 = new Zi();Zi zi2 = new Zi(1);Zi zi3 = new Zi(1,2);}
}
class Fu{int num;Fu(int a){System.out.println("Fu show..." );}
}
class Zi extends Fu{Zi(){this(1);System.out.println("Zi show...0");}Zi(int a){this(1,2);System.out.println("Zi show...1");}Zi(int a ,int b){super(1);System.out.println("Zi show...2");}
}

如果父类中,没有无参构造函数的存在,只有有参数的构造函数的话,那么子类中默认的
super() 就调用不到父类无参构造函数!引发错误!

建议每一个类 都把它的 无参构造函数 写出来!

public class Sample{public static void main(String[] args){Zi zi1 = new Zi();Zi zi2 = new Zi(3);Zi zi3 = new Zi(5,6);}
}
class Fu{int num;Fu(){System.out.println("Fu constructor...0 "+ "num = " + num);num = 10;}Fu(int a){System.out.println("Fu constructor...1 "+ "num = " + num);num = a;}
}
class Zi extends Fu{int num = 10;Zi(){System.out.println("Zi constructor...0"+ "num = " + num+"fu num = "+ super.num);}Zi(int a){this(a,0);System.out.println("Zi constructor... 1 " + "num = " + num + " fu num = " + super.num); System.out.println("Zi show...1");}Zi(int a ,int b){super(a+b);num = a+b;System.out.println("Zi constructor... 2 " + "num = " + num + " fu num = " + super.num);}
}
/*
Fu constructor...0 num = 0
Zi constructor...0num = 10fu num = 10
Fu constructor...1 num = 0
Zi constructor... 2 num = 3 fu num = 3
Zi constructor... 1 num = 3 fu num = 3
Zi show...1
Fu constructor...1 num = 0
Zi constructor... 2 num = 11 fu num = 11
*/

子父类中,成员函数的特点

public class Sample{public static void main(String[] args){Zi zi = new Zi();zi.showA();zi.showB();zi.showC();zi.showD(); }
}
class Fu{void showA(){System.out.println("Fu showA...");}void showC(){System.out.println("Fu showC...");}private void showD(){System.out.println("Fu showD...");}
}
class Zi extends Fu{void showB(){System.out.println("Zi showB...");}@Overridevoid showC(){System.out.println("Zi shwoC...");}void showD(){System.out.println("Zi showD...");}
}
  • 如果父类有,子类没有,调用的是父类的
  • 如果父类没有,子类有,调用的是子类的
  • 如果父类有,子类也有,调用的是子类的
  • 如果父类有,但是为私有,则子类继承不到,除非子类自己写一个
  • 上述第三个情况,我们称之为是函数的重写/覆盖/Override
    重写有什么用?严格意义上而言,子类并非是父类的一个子集。子类的内容很大程度上,很多情况
    下,都是父类的一种扩展或增量,重写仅仅去保留了父类的功能声明,但是具体的功能内容由子类来决
class 郭德纲{void 说相声(){System.out.println("传统相声...");}
}
class 郭麒麟 extends 郭德纲{void 说相声(){System.out.println("传统相声...");System.out.println("现在相声...");}
}
public class Sample{public static void main(String[] args){IPhoneX ix = new IPhoneX();ix.call();}
}
class IPhone1{void call(){System.out.println("电话拨号打电话...");}
}
class IPhone4s extends IPhone1{void call(){super.call();System.out.println("多人同时通话...");}
}
class IPhoneX extends IPhone4s{void call(){super.call();System.out.println("facetime视频通话...");}void hava5G(){System.out.println("具有5G功能");}
}

如果子父类中有同名函数且参数列表相同(私有例外),编译器就认为是重写关系!
重写的时候,子类的权限必须大于等于父类的权限
重写的时候,返回值不能更改

public class Sample{public static void main(String[] args){Zi zi = new Zi();zi.showC(10);zi.showC(10,20);}
}
//public > 默认 > protected > private
class Fu{public void show(){System.out.println("Fu show...");}public int showB(){return -1;}public void showC(int a){System.out.println("Fu showC...");}
}
class Zi extends Fu{void show(){System.out.println("Zi show...");}public void showB(){}public void showC(int a, int b){System.out.println("Zi showC...");}
}
/*正在尝试分配更低的访问权限; 以前为public
Sample.java:24: 错误: Zi中的showB()无法覆盖Fu中的showB()public void showB(){^返回类型void与int不兼容
2 个错误
*/

子父类中,静态成员的特点
静态变量的特点与成员变量是一致的
静态函数的特点与成员函数是一致的

public class Sample{public static void main(String[] args){Zi zi = new Zi();System.out.println(zi.num);zi.show();}
}
class Fu{public static int num = 10;public static void show(){System.out.println("Fu static show...");}
}
class Zi extends Fu{public static int num = 100;public static void show(){System.out.println("Zi static show...");}
}

综合案例

待续。。。

8.2final关键字

8.3抽象类

8.4接口

8.5多态

8.6内部类

8.7 包与权限

8.8枚举类型

java笔记_继承(八)相关推荐

  1. JAVA入门_继承与重载_饲养员喂养动物

    JAVA入门_继承与重载_饲养员喂养动物 实验要求 Tiger类 Feeder类 MainClass 运行结果 实验要求 本实验要求:本实验以饲养员喂养老虎为业务背景,体验"函数重载&quo ...

  2. Java学习笔记_继承

    继承的格式 在继承关系中,"子类就是一个父类".也就是说,子类可以被当作父类看待 例如父类是员工,子类是讲师,那么"讲师就是一个员工" 定义父类的格式:(一个普 ...

  3. Core Java笔记 2.继承

    本章重点: 继承 多态与动态绑定 Object类 对象包装器&自动打包 继承 涉及到的概念: 超类(superclass).子类(subclass) extends关键字 super关键字 多 ...

  4. 【java笔记】继承

    继承:基于已有的类创建新的类,使新的类复用或已有类的字段和方法,并增加或覆盖一些新的方法(字段). 父类/基类/超类:已有的类 子类:继承的类 定义:extends public class B ex ...

  5. 达内java笔记_达内java笔记

    J2EE所有的知识点都详细的记录在里面了,浓缩的才是精华,放在手机里随时记一记背一背,这是精挑细选后的成果,在这里0积分奉献给大家. 达内笔记 ├─01. Unix note.txt    101.0 ...

  6. [转载] JAVA笔记_(Day04,Day05)函数数组

    参考链接: 了解Java中的数组IndexOutofbounds异常 文章目录 函数定义练习误区重载(overload)重载选择题练习函数的内存调用问题 数组定义数组的内存图解数组的常见问题应用求和最 ...

  7. 【java笔记】继承与多态

    多态性的前提:extends继承或者implements实现 继承与多态: 定义:同一个操作被不同类型对象调用时可能产生不同 的行为 解释:如果一个类有很多子类,并且这些子类都重写了父类中的某个方法, ...

  8. java instanceof 继承_继承_instanceOf的使用

    本阶段是进入"程序员"的门槛,需要学习编程8yt基本的知识:变量.数据类型.控制 语句.面向对象.我们通过实际的案例,让大家一开始就通过游戏项目进入学习状态,寓教 于乐,引起大家的 ...

  9. java面向对象编程_包_继承_多态_重载和重写_抽象类_接口_this和super

    目录点击跳转 包 包的命名方法 导入包中的类 系统包的介绍 **注意事项** 继承 基础知识 构造方法 **基础语法** `protected`修饰符 组合 `this`和`super`关键字 `th ...

最新文章

  1. Python中的数据结构
  2. 内存对齐与sizeof
  3. 远去的高考,消逝的大一……
  4. 项目总结--基于Cortex-A9平台的米兰花智能培育系统
  5. 【iOS XMPP】使用XMPPFramewok(二):用户登录
  6. python argument list too long_[已解决]Argument list too long如何处理?
  7. SH760模态分析-多种解析与数字计算方法
  8. Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.
  9. 那英、那狗、那年、那事
  10. delphi 判断两个时间差是否在一个指定范围内
  11. VC++显示文件或文件夹属性
  12. TK mybatis 逆向工程
  13. php mpm_winnt,Windows下Apache模块配置 mpm_winnt_module
  14. html 屏幕旋转,屏幕旋转与Transform
  15. Python制作牛奶冻
  16. EasyExcel的使用
  17. Python数据分析高薪实战第一天 python基础与项目环境搭建
  18. 小程序---365笔记第5天---常用方法
  19. Google Earth Engine 教程——栅格矢量数据转化和导出
  20. javascript通用方法封装

热门文章

  1. 【bzoj5018】[Snoi2017]英雄联盟
  2. python爬取网页原理_Python:爬虫原理和网页构造
  3. 数组方法中,会改变原数组、不会改变原数组的方法有哪些?
  4. 小程序开发中的onLoad()和onShow()有什么区别?
  5. asp IsNull 函数
  6. 福州php前景,重磅!福州市未来三年棚改计划出炉!看看都拆哪?
  7. ICEY攻略 论如何获得所有奖杯达成成就(没错,我就是拿CSDN写了游戏攻略)
  8. Matlab R2016b安装后打开报错:License Manager Error-95
  9. 字符串反转的四种方法
  10. PHP如何实现字符串反转_php反转字符串方法