当前位置:   article > 正文

【Java】面向对象编程--继承

【Java】面向对象编程--继承

目录

概述

使用细节

本质


概述

  1. 继承是面向对象编程中的一种机制,它允许一个类(子类)从另一个类(超类或父类)继承属性和方法
  2. 当多个类存在相同属性(变量)和方法时,可以从中抽象出父类,父类中定义这些相同的属性和方法,通过extends 继承父类,就可以使用其中的属性和方法

使用细节

  • 子类继承了父类所有的属性和方法,非私有的属性和方法可以在子类直接访问, 私有属性和方法要通过父类提供公共的方法去访问
  1. /**
  2. * 子类继承了父类所有的属性和方法,非私有的属性和方法可以在子类直接访问, 私有属性和方法要通过父类提供公共的方法去访问
  3. */
  4. public class Extends02 {
  5. public static void main(String[] args) {
  6. Sub sub1 = new Sub();
  7. sub1.sayOk();
  8. }
  9. }
  10. class Base {//父类
  11. public int b1 = 11;//公开属性
  12. protected int b2 = 22;//保护属性
  13. int b3 = 33;//默认属性
  14. private int b4 = 44;//私有属性
  15. public int getB4() {//公共方法返回 b4 因为b4 是private
  16. return b4;
  17. }
  18. public void Test111() {//公开方法
  19. System.out.println("方法 test111");
  20. }
  21. protected void Test222() {//保护方法
  22. System.out.println("方法 test222");
  23. }
  24. void Test333() {//默认方法
  25. System.out.println("方法 test333");
  26. }
  27. private void Test444() {//私有方法
  28. System.out.println("方法 test444");
  29. }
  30. public void getTest444() {//公共方法 因为Test444() 是private
  31. Test444();//调用Test444()
  32. }
  33. }
  34. class Sub extends Base {//子类
  35. public void sayOk() {//子类方法
  36. //非私有的属性和方法可以在子类直接访问
  37. //但是私有属性和方法不能在子类直接访问
  38. System.out.println("b1=" + b1 + " b2=" + b2 + " b3=" + b3);
  39. //b4 是private 通过公共方法获取b4
  40. System.out.println("b4=" + getB4());
  41. Test111();
  42. Test222();
  43. Test333();
  44. //Test444();;错误
  45. //要通过父类提供公共的方法去访问
  46. getTest444();
  47. }
  48. }
  • 子类调用自己的构造器时必须先调用父类的构造器, 完成父类的初始化
  1. /**
  2. * 子类调用自己的构造器时必须先调用父类的构造器, 完成父类的初始化
  3. */
  4. public class Extends02 {
  5. public static void main(String[] args) {
  6. Sub sub1 = new Sub();
  7. }
  8. }
  9. class Base {//父类
  10. public Base() {//无参构造器
  11. System.out.println("父类 Base() 无参构造器被调用");
  12. }
  13. }
  14. class Sub extends Base {//子类
  15. public Sub() {//无参构造器
  16. //super(); //编译器默认放置 默认调用父类的无参构造器
  17. System.out.println("子类 Sub() 无参构造器被调用");
  18. }
  19. }
  20. 输出:
  21. 父类 Base() 无参构造器被调用
  22. 子类 Sub() 无参构造器被调用
  • 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
  1. /**
  2. * 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器
  3. * 如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器
  4. * 完成对父类的初始化工作,否则,编译不会通过
  5. */
  6. public class Extends02 {
  7. public static void main(String[] args) {
  8. Sub sub1 = new Sub("少爷");
  9. }
  10. }
  11. class Base {//父类
  12. public Base() {//无参构造器
  13. System.out.println("父类 Base() 无参构造器被调用");
  14. }
  15. public Base(String name) {
  16. System.out.println("父类 Base(String name) 构造器被调用");
  17. }
  18. }
  19. class Sub extends Base {//子类
  20. //当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器
  21. public Sub(String name) {
  22. // 默认情况下会调用父类的无参构造器
  23. // super()指定调用父类的Base(String name, int age)构造器
  24. super("aaa");
  25. System.out.println("子类 Sub(String name)构造器被调用");
  26. }
  27. }
  28. 输出:
  29. 父类 Base(String name) 构造器被调用
  30. 子类 Sub(String name)构造器被调用
  • 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
  1. /**
  2. * 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
  3. */
  4. public class Extends02 {
  5. public static void main(String[] args) {
  6. Sub sub1 = new Sub();
  7. }
  8. }
  9. class Base {//父类
  10. public Base() {//无参构造器
  11. System.out.println("父类 Base() 无参构造器被调用");
  12. }
  13. public Base(String name) {
  14. System.out.println("父类 Base(String name) 构造器被调用");
  15. }
  16. public Base(String name, int age) {
  17. System.out.println("父类 Base(String name ,int age) 构造器被调用");
  18. }
  19. }
  20. class Sub extends Base {//子类
  21. public Sub() {
  22. //1. 调用父类无参构造器
  23. super();//父类的无参构造器
  24. //2. 调用父类 Base(String name) 构造器
  25. super("少爷");
  26. //3. 调用父类 Base(String name, int age) 构造器
  27. super("龙部", 22);
  28. }
  29. }
  1. super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
  2. super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
  3. java 所有类都是 Object 类的子类, Object 是所有类的基类.
  4. 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object (顶级父类)
  5. 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。
  6. 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系

本质

  • 当子类对象建立完后,建立查找关系
  1. **
  2. * 1.方法区加载类 先加载顶级类 后父子 然后子类
  3. * 2.堆里分配空间 先分配顶级类 后父子 然后子类 整个空间还是子类对象
  4. * 当属性为私有时 内存中也会有
  5. */
  6. public class Extends03 {
  7. public static void main(String[] args) {
  8. Son son = new Son();
  9. //要按照查找关系来返回信息
  10. //(1) 首先看子类是否有该属性
  11. //(2) 如果子类有这个属性,并且可以访问,则返回信息
  12. //(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
  13. //(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object 顶级父类
  14. System.out.println(son.name);//输出 孙子
  15. System.out.println(son.age);//输出 40
  16. System.out.println(son.address);//输出 12栋
  17. //当属性为不可访问时
  18. //调用公共方法返回 私有属性
  19. System.out.println(son.getHobby());//输出 跑步
  20. //当爷爷类中 含有hobby 属性 父亲类中也含有hobby 属性时
  21. //因为继承是查找关系
  22. //从孙子类开始查找hobby 属性 当找到父亲类中发现后不管是什么访问权限 都不会再到爷爷类中查找
  23. }
  24. }
  25. class GrandPa {
  26. String name = "爷爷";
  27. String address = "12栋";
  28. String hobby = "盘串";
  29. }
  30. class Father extends GrandPa {
  31. String name = "爸爸";
  32. int age = 40;
  33. private String hobby = "跑步";
  34. public String getHobby() {//公共方法返回 私有属性
  35. return hobby;
  36. }
  37. }
  38. class Son extends Father {
  39. String name = "孙子";
  40. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/301448?site
推荐阅读
相关标签
  

闽ICP备14008679号