• Java面向对象三大特征 <2> -【继承】_ Java SE


    目录

    1.理解继承

    2.继承的语法格式

    3.子类对父类的访问

    3.1子类中访问父类的成员变量

    子类和父类没有同名的成员变量(直接访问)

    子类和父类有同名的成员变量(super关键字)

    3.2子类中访问父类的成员方法

    子类和父类成员方法名不同(直接调用)

    成员方法名相同子类和父类(super关键字)

    4.super关键字

    5.super和this的异同点

    6.子类对象的构造方法

    7.在继承中代码块的执行顺序

    8.访问限定符protected(受保护的)

    9.继承类型

    10.关键字final

    11.继承和组合的选择


    1.理解继承

    什么是继承呐?我们先看一下图片:

    图片反映了教师和学生都属于人这一类,他们也有自己的共性。

    任课教师和教辅人员都属于教师,也同时都属于人这一类;

    本科生和研究生都属于学生,也同时都属于人这一类。

    就好比教师是任课教师和教辅人员的父类学生是本科生和研究生的父类。而教师和学生属于人的子类。

    父类通用,子类具体。子类具有父类的一般特征也具有自身特性。

    强调:共性抽取,实现代码复用,这就是继承的目的

    2.继承的语法格式

    关键字extends   继承的语法格式也很简单:

    修饰符 class 子类(派生类) extends 父类(基类/超类){

    //

    }

    下面我们来实现一下 共性抽取,写出派生类。

    1. /**
    2. * @author Sun
    3. * @version 2021.2
    4. * @date 2022/5/19 11:20
    5. */
    6. class Person {
    7. public String name;
    8. public int age;
    9. public void school() {
    10. System.out.println(name+"正在学校!");
    11. }
    12. }
    13. class Student extends Person {
    14. public int studentid;
    15. public void study() {
    16. System.out.println("我是学生,我在学习!");
    17. }
    18. }
    19. class Teacher extends Person {
    20. public int workid;
    21. public void teach() {
    22. System.out.println("我是老师,我在备课!");
    23. }
    24. }

    强调: 

    (1)子类继承父类,会将父类的成员方法或成员变量都继承到自己身上;

    (2)子类继承父类,子类必须新添加自己特有的成员,体现出和父类的相同,不然子类和父类相同了,那要继承就没有意义。

    3.子类对父类的访问

    问题:

    🐲(1)在子类中,如何访问父类的成员变量

    🐲(2)在子类中,如何访问父类的成员方法

    3.1子类中访问父类的成员变量

    子类和父类没有同名的成员变量(直接访问)

    这种访问,非常简单:

    1. package 继承;
    2. /**
    3. * @author Sun
    4. * @version 2021.2
    5. * @date 2022/5/19 11:37
    6. */
    7. class Father {
    8. public int a=1;
    9. public int b=2;
    10. }
    11. class child extends Father {
    12. public int c=3;
    13. public int d=4;
    14. public void test() {
    15. System.out.println(this.a);
    16. System.out.println(this.b);
    17. System.out.println(this.c);
    18. System.out.println(this.d);
    19. }
    20. }
    21. public class Test {
    22. public static void main(String[] args) {
    23. child child = new child();
    24. child.test();
    25. }
    26. }

    this.成员变量

    子类和父类有同名的成员变量(super关键字)

     

    相信大家也已经看明白了,如果子类非要访问父类同名成员,那就得使用super关键字

    super关键字表示子类从父类中继承的这一部分成员的地址 

    总结: 子类访问父类成员变量

    🟥(1)如果子类中有,优先访问自己的成员变量

    🟩(2)如果子类中没有,就从父类中继承下来,如果父类中也没有,那就报错了

    🟧(3)如果有成员变量同名,那就优先访问子类自己的

    一句话,那就是:

    🟪成员变量访问遵循就近原则,先访问自己,如果没有,找父类
     

    3.2子类中访问父类的成员方法

    子类和父类成员方法名不同(直接调用)

    1. class Base{
    2. public int a=1;
    3. public int b=2;
    4. public void methodA() {
    5. System.out.println("Base::methodA()");
    6. }
    7. }
    8. class Derived extends Base {
    9. public int a=3;
    10. public int d=4;
    11. public void methodB() {
    12. System.out.println("Derived::methodB()");
    13. }
    14. public void test(){
    15. methodA();//访问父类继承的methodA()
    16. methodB();//访问字类自己的methodB()
    17. }
    18. }
    19. public class Test02 {
    20. public static void main(String[] args) {
    21. Derived derived = new Derived();
    22. derived.test();
    23. }
    24. }

    成员方法名相同子类和父类(super关键字)

    1. package 继承;
    2. /**
    3. * @author Sun
    4. * @version 2021.2
    5. * @date 2022/5/19 11:53
    6. */
    7. class Base{
    8. public int a=1;
    9. public int b=2;
    10. public void methodA() {
    11. System.out.println("Base::methodA()");
    12. }
    13. public void methodB() {
    14. System.out.println("Base::methodB()");
    15. }
    16. }
    17. class Derived extends Base {
    18. public int a=3;
    19. public int d=4;
    20. public void methodA(int val) {
    21. System.out.println("Derived::methodA(int)"+val);
    22. }
    23. public void methodB() {
    24. System.out.println("Derived::methodB()");
    25. }
    26. public void test(){
    27. methodA();//Base::methodA()
    28. methodA(100);//Derived::methodA(int)
    29. methodB();//Derived::methodB(int)
    30. }
    31. }
    32. public class TestDemo {
    33. public static void main(String[] args) {
    34. Derived derived = new Derived();
    35. derived.test();
    36. }
    37. }

    通过代码,我们可以看出:

    如果子类和父类的同名方法中,构成了重载,也就是同名但参数列表不同时,就可以根据自己的参数用合适的方法进行访问

    如果子类方法和父类同名方法中,没有构成重载,那就是重写。就还是优先访问子类自己的方法。

    如果非要访问父类的同名成员方法, super.同名方法 就可以实现了。

    1. package 继承;
    2. /**
    3. * @author Sun
    4. * @version 2021.2
    5. * @date 2022/5/19 11:53
    6. */
    7. class Base{
    8. public int a=1;
    9. public int b=2;
    10. public void methodA() {
    11. System.out.println("Base::methodA()");
    12. }
    13. public void methodB() {
    14. System.out.println("Base::methodB()");
    15. }
    16. }
    17. class Derived extends Base {
    18. public int a=3;
    19. public int d=4;
    20. public void methodA(int val) {
    21. System.out.println("Derived::methodA(int)"+val);
    22. }
    23. public void methodB() {
    24. System.out.println("Derived::methodB()");
    25. }
    26. public void test(){
    27. methodA();//Base::methodA()
    28. methodA(100);//Derived::methodA(int)
    29. super.methodB();//Base::methodB()
    30. }
    31. }
    32. public class TestDemo {
    33. public static void main(String[] args) {
    34. Derived derived = new Derived();
    35. derived.test();
    36. }
    37. }

    总结:

    (1) 如果自雷中有,优先访问自己的成员方法

    (2)如果子类中没有,就从父类中继承;如果父类中也没有,那就报错

    (3) 如果有成员方法同名,并构成重载,就可以根据自己的参数,选择合适的方法访问

    (4) 如果有成员方法同名,但没有构成重载,如果直接访问成员方法就会访问子类自己的

    (5) 如果有成员方法同名,但有没构成重载,那就直接  super.同名方法 ,才可以访问父类成员方法 

    成员变量访问原则 : 先自己,自己没有,找父类。

    4.super关键字

    前面我们已经使用了super关键字了,下面我们来了解一下super的其他作用:

    作用:在子类方法中访问父类的成员

    super关键字只能在非静态的方法中使用:

    Because : 静态方法 不依赖对象

                         super 从父类中访问成员对象

    两个矛盾,不能同时存在。

    super() 调用父类的构造方法

    来初始化子类继承过来父类的属性。

    5.super和this的异同点

    相同点

    (1)在构造方法中调用,必须是构造方法中的的语句,并且super和this不能同时存在

    (2)只能在静态方法中使用,两个都需要对象

    (3)都是关键字

    不同点

    (1)this是当前对象的引用,super是子类对象从父类继承下来的成员的引用

    (2)在构造方法中一定会存在super()的调用,不管写不写都有,this()是如果不写就没有

    (3) this()用于调用自己类的构造方法

              super()用于调用父类的构造方法,两个不能同时使用

    (4) 在静态的成员方法中,this是用来访问本类的方法和属性,super用来访问从父类继承下来的属性

    6.子类对象的构造方法

    子类对象的构造方法就是由父类继承下来的构造方法+子类构造方法中添加的部分组成。

    写一个子类对象的构造方法:

    1. class Animal{
    2. public String name;
    3. public int age;
    4. public Animal(String name, int age) {
    5. this.name = name;
    6. this.age = age;
    7. }
    8. public void eat() {
    9. System.out.println(name+"正在吃饭!");
    10. }
    11. }
    12. class Dog extends Animal {
    13. public float weight;
    14. public Dog(String name,int age,float weight) {
    15. super(name, age);
    16. //调用父类的构造函数,来初始化此时子类继承过来父类的属性
    17. this.weight = weight;
    18. }
    19. public void bark() {
    20. System.out.println(name+"正在狗叫");
    21. }
    22. @Override
    23. public String toString() {
    24. return "Dog{" +
    25. "name='" + name + '\'' +
    26. ", age=" + age +
    27. ", weight=" + weight +
    28. '}';
    29. }
    30. }
    31. }

    🟧子类对象构造时,需要先调用父类构造方法,将从父类继承下来的成员构造完整,

          然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。

    ⚜️提几点注意

    🤠(1)如果父类执行默认的构造方法,那么在子类构造方法的第一行默认含有super()的调用

    🤠(2)如果父类构造方法是带有参数的,此时编译器给子类不会执行默认的构造方法,

    这就要程序员自己给子类定义构造方法了

    🤠(3)在子类构造方法中,super()调用父类构造时,必须是子类构造方法中第一条语句。

    🤠(4)super()只能在子类构造方法中出现一次,并且不能和this同时出现

    7.在继承中代码块的执行顺序(重点:静态优先,由父及子)

    1. class Animal{
    2. public String name;
    3. public int age;
    4. static {
    5. System.out.println("Animal的静态代码块!");
    6. }
    7. {
    8. System.out.println("Animal的实例代码块!");
    9. }
    10. public Animal() {
    11. System.out.println("Animal不带参数的构造方法!");
    12. }
    13. public Animal(String name, int age) {
    14. this.name = name;
    15. this.age = age;
    16. }
    17. public void eat() {
    18. System.out.println(name+"正在吃饭!");
    19. }
    20. }
    21. class Dog extends Animal {
    22. public float weight;
    23. static {
    24. System.out.println("Dog的静态代码块!");
    25. }
    26. {
    27. System.out.println("Dog的实例代码块!");
    28. }
    29. public Dog() {
    30. System.out.println("Dog的不带参数的构造方法!");
    31. }
    32. public Dog(String name, int age, float weight) {
    33. super(name, age);
    34. this.weight = weight;
    35. }
    36. public void bark() {
    37. System.out.println(name+"正在狗叫");
    38. }
    39. @Override
    40. public String toString() {
    41. return "Dog{" +
    42. "name='" + name + '\'' +
    43. ", age=" + age +
    44. ", weight=" + weight +
    45. '}';
    46. }
    47. }
    48. }
    49. public class Test01 {
    50. public static void main(String[] args) {
    51. Dog dog = new Dog();
    52. }
    53. }

    大家可以看看执行后的结果:

     

     是不是验证了 ——静态优先,由父及子

    父类和子类对的静态方法——父类的实例和构造方法——子类的实例和构造方法

    而且需要注意的是 静态代码块只执行一次。

    8.访问限定符protected(受保护的)

    范围

    private

    私有

    default

    默认

    protected

    继承

    public

    公开

    同一包中的同一类
    同一包中的不同类
    不同包中的子类
    不同包中的非子类

    我们可以清楚的看到,protected的访问范围。 

    9.继承类型

    继承类型可以分为以下几个:

    (1)单继承

    Java中只支持单继承。 

    (2)多级继承

    一层一层的来继承。 

    (3)分层继承(不同类继承同一个类)

     

    10.关键字final

    (1)final修饰成员变量时,变量就不能在修改并且属于常量。

    (2)final修饰类时,此类不能被继承。

    (3)final修饰方法是,此方法不能被重写。

    11.继承和组合的选择

    继承组合

    继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,而且可以增加它自己的新功能的能力,直接点讲就是

    🟪共性抽取,实现代码复用

    🟦它的关系就是 is-a

    🟩组合是通过对现有对象进行拼装即组合产生新的具有更复杂的功能。 

    🟦组合体现的是整体与部分,所拥有的关系,也就是has-a的关系

    🟪也把这种方式的代码复用叫黑盒式代码复用

    拓展:

    😁复用性是面向对象的语言好处之一,

    😁而这个复用性在java代码中,有三个表现形式:继承,组合,代理。

    在两种都可行的情况下,优先使用组合,原因是组合比继承更加灵活,也更有助于代码维护。

  • 相关阅读:
    【C++】C++ 引用详解 ⑦ ( 指针的引用 )
    动动嘴即可搜视频 抖音与Siri达成合作
    关于图像的读取及处理等
    初识猿如意开发工具
    TX Text Control.NET For WPF 32.0 Crack
    MySql相关时间处理的函数
    c++模板显式实例化可以访问私有成员
    贪心算法之最优装载
    ElasticSearch - () Python操作es
    Spring5学习笔记05--BeanFactory后处理器
  • 原文地址:https://blog.csdn.net/weixin_53939785/article/details/124857948