继承的概述

面向对象的三大特征:封装性、继承性、多态性
继承是多态的前提,如果没有继承,就没有多态

继承主要解决的问题是:共性提取

继承当中的特点:

  • 子类可以拥有父类的“内容”
  • 子类还可以拥有自己专有的内容

image.png

继承的格式

  1. package com.Demo07;
  2. import com.Demo05.Student;
  3. /*
  4. 在继承的关系中,“子类就是一个父类”,也就是说,子类可以被当作父类看待
  5. 列入父类时员工,子类时讲师,那么“讲师就是一个员工”,关系:is-a
  6. 定义父类的格式:(一个普通的类定义)
  7. public class 父类名称{
  8. //...
  9. }
  10. 定义子类的格式:
  11. public class 子类名称 extends 父类名称{
  12. //...
  13. }
  14. */
  15. public class Demo01Extends {
  16. public static void main(String[] args) {
  17. //创建一个子类对象
  18. Teacher obj = new Teacher();
  19. //Teacher类当中虽然什么都没有写,但是会继承来自父类的method方法
  20. obj.method();
  21. //创建另一个子类助教的方法
  22. Assistant obj1=new Assistant();
  23. obj1.methodZi(); //子类自己专有的方法
  24. }
  25. }
  26. ===============================================================================================
  27. package com.Demo07;
  28. public class Employee {
  29. public void method(){
  30. System.out.println("父类构造方法执行!");
  31. }
  32. }
  33. ===============================================================================================
  34. package com.Demo07;
  35. public class Teacher extends Employee{
  36. }
  37. ================================================================================================
  38. package com.Demo07;
  39. public class Assistant extends Employee{
  40. public void methodZi(){
  41. System.out.println("子类构造方法执行!");
  42. }
  43. }

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

  1. package com.Demo07;
  2. /*
  3. 在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式。
  4. 直接通过子类对象访问成员变量:
  5. 等号左边是谁,就优先用谁,没有则往上找
  6. 见解通过成员方法访问成员变量:
  7. 该方法属于谁,就优先用谁,没有则往上找
  8. 在父子类的继承关系中,创建子类对象,访问成员方法的规则:
  9. 创建的对象是谁,就优先用谁,没有就向上找
  10. 【注意事项】
  11. 不论是成员变量还是成员方法,如果没有都是往上找父类,绝对不会往下找子类。
  12. */
  13. public class Demo02ExtendsField {
  14. public static void main(String[] args) {
  15. Fu fu = new Fu(); //创建父类对象
  16. System.out.println(fu.numFu); //只能使用父类的东西,没有任何子类的东西
  17. System.out.println("========================");
  18. Zi zi = new Zi();
  19. System.out.println(zi.numFu); //10
  20. System.out.println(zi.numZi); //20
  21. System.out.println("=======================");
  22. //等号左边是谁就优先用谁
  23. System.out.println(zi.num);
  24. // System.out.println(zi.ab); //导出都没有编译报错
  25. System.out.println("==================");
  26. //这个方法是子类的,优先用子类,没有再往上找
  27. zi.methodZi();
  28. //这个方法是在父类中定义的
  29. zi.methodFu();
  30. //创建的是new了子类对象,所以优先用子类方法
  31. zi.method(); //
  32. }
  33. }

image.png

区分子类方法中重名的三种

  1. package com.Demo07;
  2. /*
  3. 局部变量: 直接写成员变量名
  4. 本类的成员变量: this.成员变量名
  5. 父类的成员变量: super.成员变量名
  6. */
  7. public class Demo02ExtendsField {
  8. public static void main(String[] args) {
  9. Zi zi = new Zi();
  10. zi.method();
  11. }
  12. }
  13. =================================================================================================
  14. package com.Demo07;
  15. public class Fu {
  16. int num=10;
  17. public void method(){
  18. System.out.println("父类 重名方法method");
  19. }
  20. }
  21. =================================================================================================
  22. package com.Demo07;
  23. public class Zi extends Fu{
  24. int num=20;
  25. public void method(){
  26. int num=30;
  27. System.out.println("子类 重名方法method");
  28. System.out.println(num); //30 局部变量
  29. System.out.println(this.num); //20 本类中的成员变量
  30. System.out.println(super.num); //10 父类的成员变量
  31. }
  32. }

继承中方法的覆盖重写

  1. package com.Demo07;
  2. /*
  3. 重写(override)
  4. 概念:在继承关系中,方法名称一样,参数列表也一样
  5. 重写(override):方法名称一样,参数列表【也一样】。 覆盖、覆写
  6. 重载(overload):方法名称一样,参数列表【不一样】
  7. 方法的覆盖重写特点:创建的是子类对象,则优先用子类方法
  8. 方法覆盖重写的注意事项:
  9. 1.必须保证父子类之间方法名称相同,参数列表也相同。
  10. @override:写在方法前面,用力啊检测是不是有效的正确覆盖重写
  11. 这个注释就算是不写,只要满足要求,也是正确的方法覆盖重写
  12. 2.子类方法的返回值必须【小于等于】父类方法的返回值范围
  13. 小扩展提示:java.lang.Object类是所有类的公过最高父类(祖宗类),java.lang.String就是Object类的子类
  14. 3.子类方法的权限必须【大于等于】父类方法的权限修饰符
  15. 小扩展提示:public>protected>(default)>private
  16. 备注:(default)不是关键字default,而是什么都不写,留空
  17. */
  18. public class Demo02ExtendsField {
  19. public static void main(String[] args) {
  20. Zi zi = new Zi();
  21. zi.method();
  22. }
  23. }
  24. ================================================================================================
  25. package com.Demo07;
  26. public class Fu {
  27. int num=10;
  28. public void method(){
  29. System.out.println("父类 重名方法method");
  30. }
  31. }
  32. ================================================================================================
  33. package com.Demo07;
  34. public class Zi extends Fu{
  35. int num=20;
  36. @Override
  37. public void method(){
  38. int num=30;
  39. super.method(); //把父类的method方法拿来重复利用
  40. System.out.println("子类 重名方法method");
  41. }
  42. }

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

  1. package com.Demo07;
  2. /*
  3. 继承关系中,父类的构造方法的访问特点:
  4. 1.子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造
  5. 2.父类构造可以通过supper关键字来调用重载构造
  6. 3.supper的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次supper构造
  7. 总结:
  8. 子类必须调用父类构造方法,不写则赠送supper(),写了则用写的指定的supper调用,supper只能有一个,还必须是第一个
  9. */
  10. public class Demo02ExtendsField {
  11. public static void main(String[] args) {
  12. Zi zi = new Zi();
  13. }
  14. }
  15. =================================================================================================
  16. package com.Demo07;
  17. public class Fu {
  18. public Fu(){
  19. System.out.println("父类无参构造方法");
  20. }
  21. public Fu(int num){
  22. System.out.println("父类全参构造方法");
  23. }
  24. }
  25. =================================================================================================
  26. package com.Demo07;
  27. public class Zi extends Fu{
  28. public Zi(){
  29. // super(); //在调用父类无参构造方法 默认赠送 可不写
  30. super(12); //在调用父类全参构造方法
  31. System.out.println("子类构造方法!");
  32. }
  33. }

image.png

supper关键字的三种用法

  1. package com.Demo07;
  2. public class Demo02ExtendsField {
  3. public static void main(String[] args) {
  4. Zi zi = new Zi();
  5. zi.method();
  6. zi.methodZi();
  7. }
  8. }
  9. =================================================================================================
  10. package com.Demo07;
  11. public class Fu {
  12. int num=30;
  13. public Fu(){
  14. System.out.println("父类无参构造方法");
  15. }
  16. public Fu(int num){
  17. System.out.println("父类全参构造方法");
  18. }
  19. public void method(){
  20. System.out.println("父类的method方法");
  21. }
  22. }
  23. =================================================================================================
  24. package com.Demo07;
  25. /*
  26. supper关键字的三种用法:
  27. 1.在子类的成员方法中,访问父类的成员变量
  28. 2.在子类的成员方法中,访问父类的成员方法
  29. 3.在子类的构造方法中,访问父类的构造方法
  30. */
  31. public class Zi extends Fu{
  32. int num=20;
  33. public Zi(){
  34. // super(); //在调用父类无参构造方法 默认赠送 可不写
  35. super(12); //在调用父类全参构造方法
  36. System.out.println("子类构造方法!");
  37. }
  38. public void methodZi(){
  39. System.out.println(super.num); //父类的 num
  40. }
  41. public void method(){
  42. super.method(); //访问父类的method方法
  43. System.out.println("子类的method方法");
  44. }
  45. }

this关键字的三种用法

  1. package com.Demo07;
  2. /*
  3. supper关键字用来访问父类内容,而this关键字用力啊访问本类内容,用法也有三种:
  4. 1.在本类的成员方法中,访问本类的成员变量
  5. 2.在本类的成员方法中,访问本类的另一个成员方法
  6. 3.在本类的构造方法中,访问本类的另一个构造方法
  7. 在第三个方法要注意:
  8. A:this(...)调用也必须试构造方法的第一个语句
  9. B:super和this两种构造调用不能同时使用
  10. */
  11. public class Zi extends Fu{
  12. int num=20;
  13. public Zi(){
  14. // super(); //不再赠送
  15. this(12); //本类的无参构造调用本类的有参构造
  16. // this(); //错误写法!!
  17. }
  18. public Zi(int num1){
  19. System.out.println("子类的有参构造");
  20. }
  21. public void method(){
  22. int num=30;
  23. System.out.println(num); //成员变量
  24. System.out.println(this.num); //本类中的成员变量
  25. System.out.println(super.num); //父类中的成员变量
  26. }
  27. public void methodA(){
  28. System.out.println("AAA");
  29. }
  30. public void methodB(){
  31. this.methodA();
  32. System.out.println("BBB");
  33. }
  34. }
  35. ================================================================================================
  36. package com.Demo07;
  37. public class Fu {
  38. int num=10;
  39. public Fu(){
  40. System.out.println("父类无参构造方法");
  41. }
  42. }
  43. ================================================================================================
  44. package com.Demo07;
  45. public class Demo02ExtendsField {
  46. public static void main(String[] args) {
  47. Zi zi = new Zi(1);
  48. zi.methodB();
  49. }
  50. }

super和this关键字图解

image.png

Java继承的三个特点

  • java语言是单继承的
  • java语言可以多级继承
  • 一个子类的直接父类是唯一的,但是一个父类可以拥有很多个子类,可以拥有很多个兄弟姐妹

image.png