• 继承和多态的深度剖析


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

    文章目录

    1.继承的使用

    2.重写

    3.多态


    1.继承的使用:当不同类当中存在相同的成员变量和成员方法时我们往往把他们单独拿出来,形成一个类,我们把这个类叫做父类,其他类可以去继承这个类我们把这个类称之为子类

    2.继承使用关键字extends

    1. class Animal
    2. {
    3. public int age = 2;
    4. public String name = "wang";
    5. public void eat()
    6. {
    7. System.out.println(name + "正在吃饭");
    8. }
    9. }
    10. class Dog extends Animal
    11. {
    12. public String silly;
    13. public void bark()
    14. {
    15. System.out.println(name + "正在叫");
    16. }
    17. }
    18. class Cat extends Animal
    19. {
    20. public void cath()
    21. {
    22. System.out.println(name + "正在抓老鼠");
    23. }
    24. }

    在这里面Animal就是父类,Dog和Cat分别是子类然后分别继承了Animal这个父类。

    当父类被final修饰时此时的话就不能被继承

     如图所示,此时继承Animal会被报错

    4.父类的成员访问

    1.当子类和父类的成员变量不同时,可以直接访问父类的变量属性:

    1. class Animal
    2. {
    3. public int age=3;
    4. public String name="wang";
    5. //public String name;
    6. }
    7. class Dog extends Animal
    8. {
    9. public String silly;
    10. public Dog()
    11. {
    12. this.silly = "笨";
    13. }
    14. }
    15. public class text {
    16. public static void main(String[] args) {
    17. Dog dog = new Dog();
    18. System.out.println(dog.age);
    19. System.out.println(dog.name);
    20. }

     2.当在子类方法中访问的成员变量子类和父类相同时,优先访问子类的

    1. class Animal
    2. {
    3. public int age=3;
    4. public String name="wang";
    5. //public String name;
    6. }
    7. class Dog extends Animal
    8. {
    9. public int age=4;
    10. public String silly;
    11. public void dayin()
    12. {
    13. System.out.println(dog.age);
    14. }
    15. public Dog()
    16. {
    17. this.silly = "笨";
    18. }
    19. }
    20. public class text {
    21. public static void main(String[] args) {
    22. Dog dog=new Dog();
    23. dog.dayin();
    24. }
    25. }

    大家可以猜一下打印的age的是几?因为优先访问子类的,所以结果肯定是4.

     那如果非要在子类方法中访问父类的那么需要用到关键字super  改成super.age,

    1. class Animal
    2. {
    3. public int age=3;
    4. public String name="wang";
    5. //public String name;
    6. }
    7. class Dog extends Animal
    8. {
    9. public int age=4;
    10. public String silly;
    11. public void dayin()
    12. {
    13. System.out.println(super.age); //在这里用super关键字修饰age就可以访问到父类的age
    14. }
    15. public Dog()
    16. {
    17. this.silly = "笨";
    18. }
    19. }
    20. public class text {
    21. public static void main(String[] args) {
    22. Dog dog=new Dog();
    23. dog.dayin();
    24. }
    25. }

     当父类和子类的成员变量相同时如果非要访问的父类的,我们要使用super这个关键字,但是注意super关键字只能在非静态的方法当中使用

    3.当去访问成员变量时优先 访问自己的,没有再去父类找

    四.子类构造方法:

    子类构造对象时先调用父类的构造方法,然后执行子类的构造方法。

    1.无参构造

    1. class Animal
    2. {
    3. public int age;
    4. //public String name="wang";
    5. public String name;
    6. public Animal()
    7. {
    8. System.out.println("给父类初始化");
    9. }
    10. public void eat()
    11. {
    12. System.out.println(name + "正在吃饭");
    13. }
    14. public void dance()
    15. {
    16. System.out.println("狗在跳舞");
    17. }
    18. }
    19. class Dog extends Animal
    20. {
    21. public String silly;
    22. public Dog()
    23. {
    24. super();//默认调用父类的无参构造方法,且必须放在第一行,
    25. //this.silly = "聪明";
    26. System.out.println("给子类初始化");
    27. }
    28. //public String name;
    29. public void bark()
    30. {
    31. super.dance();
    32. System.out.println(name + "正在叫");
    33. }
    34. }
    35. public class text{
    36. public static void main(String[] args) {
    37. Dog dog = new Dog();
    38. System.out.println(dog.age);
    39. System.out.println(dog.name);
    40. }
    41. }

     2.有参的构造方法:

    1. public class text {
    2. public static void main(String[] args) {
    3. Dog dog = new Dog();
    4. //System.out.println(dog.silly);
    5. System.out.println(dog.age);
    6. System.out.println(dog.name);
    7. }
    8. package text;
    9. class Animal
    10. {
    11. public int age;
    12. //public String name="wang";
    13. public String name;
    14. public Animal(String name, int age)
    15. {
    16. this.name = name;
    17. this.age = age;
    18. System.out.println("给父类初始化");
    19. }
    20. public void eat()
    21. {
    22. System.out.println(name + "正在吃饭");
    23. }
    24. public void dance()
    25. {
    26. System.out.println("狗在跳舞");
    27. }
    28. }
    29. class Dog extends Animal
    30. {
    31. public String silly;
    32. public Dog(String name, int age)
    33. {
    34. super(name, age);
    35. this.silly = "聪明";
    36. System.out.println("给子类初始化");
    37. }
    38. //public String name;
    39. public void bark()
    40. {
    41. super.dance();
    42. System.out.println(name + "正在叫");
    43. }
    44. }
    45. public class text {
    46. public static void main(String[] args) {
    47. Dog dog = new Dog("xiao", 3);
    48. System.out.println(dog.silly);
    49. System.out.println(dog.age);
    50. System.out.println(dog.name);
    51. }
    52. }

    五.继承关系上的先后顺序:

    先执行父类的静态代码块、子类的静态代码块、父类的实例代码块、构造方法,然后是子类的实例代码块、构造方法,且静态代码块只能被执行一次。

    1. package text;
    2. class Animal
    3. {
    4. public int age;
    5. //public String name="wang";
    6. public String name;
    7. static
    8. {
    9. int month;
    10. System.out.println("静态代码块2");
    11. }
    12. {
    13. System.out.println("实例代码块2");
    14. }
    15. public Animal(String name, int age)
    16. {
    17. this.name = name;
    18. this.age = age;
    19. System.out.println("构造方法2");
    20. }
    21. public void eat()
    22. {
    23. System.out.println(name + "正在吃饭");
    24. }
    25. public void dance()
    26. {
    27. System.out.println("狗在跳舞");
    28. }
    29. }
    30. class Dog extends Animal
    31. {
    32. public String silly;
    33. static
    34. {
    35. System.out.println("静态代码块1");
    36. }
    37. {
    38. System.out.println("实例代码块1");
    39. }
    40. public Dog()
    41. {
    42. super("hao", 7);
    43. this.silly = "聪明";
    44. System.out.println("构造方法1");
    45. }
    46. public void eat()
    47. {
    48. System.out.println(name + "跳着吃饭");
    49. }
    50. public class text {
    51. public static void main(String[] args) {
    52. Dog dog1 = new Dog();
    53. Dog dog2 = new Dog();
    54. }

    二.多态

    1.什么是多态

    多态是指当引用的对象不同时,同一个方法会出现不同的效果

    多态实现的条件:

    1.必须在继承条件下

    2.子类必须对父类的方法进行重写

    3.通过父类的引用调用重写的方法

    2.什么是重写

    重写是指将父类的方法写到子类中,其参数列表、函数名、返回值必须相等,实现内容不同

    当父类被static、private修饰的方法、构造方法都不能被重写

    3.向上转型:是指将子类对象赋给父类,由父类对象引用子类。

    1. public static void main2(String[] args) {
    2. Dog dog=new Dog("wang",7);
    3. Animal ainmal=dog;
    4. 也可以写成这样:
    5. Animal ainmal=new Dog("wang",7);
    6. }

    4.向下转型是指当实行向上转型性,通过父类没法引用子类的特有的方法,此时我们需要再将父类强转成子类对象,这个过程就是向下转型。

    5.

    1. class Animal
    2. {
    3. int age;
    4. String name;
    5. public Animal(String name,int age)
    6. {
    7. this.name=name;
    8. this.age=age;
    9. }
    10. public void eat()
    11. {
    12. System.out.println(name+"吃饭");
    13. }
    14. }
    15. class Dog extends Animal
    16. {
    17. String name="li";
    18. int age=8;
    19. String silly="笨小狗";
    20. public Dog(String name,int age)
    21. {
    22. super(name,age);
    23. }
    24. /*public void eat()
    25. {
    26. System.out.println(name+"吃狗粮");
    27. }
    28. */
    29. }
    30. public class text {
    31. public static void main(String[] args) {
    32. Dog dog = new Dog("wang", 7);
    33. Animal animal = dog;
    34. System.out.println(animal.name);
    35. System.out.println(animal.age);
    36. animal.eat();
    37. }
    38. }

     通过结果我们知道aimal  引用的是父类的age和name,而不是子类的,当eat方法只有一个时调用的也是父类的,那么当我们在子类再重写这样一个方法时,那么调用的是谁呢?父类的还是子类的呢?

    1. class Animal
    2. {
    3. int age;
    4. String name;
    5. public Animal(String name,int age)
    6. {
    7. this.name=name;
    8. this.age=age;
    9. }
    10. public void eat()
    11. {
    12. System.out.println(name+"吃饭");
    13. }
    14. }
    15. class Dog extends Animal
    16. {
    17. String name="li";
    18. int age=8;
    19. String silly="笨小狗";
    20. public Dog(String name,int age)
    21. {
    22. super(name,age);
    23. }
    24. public void eat()
    25. {
    26. System.out.println(name+"吃狗粮");
    27. }
    28. }
    29. public class text {
    30. public static void main(String[] args) {
    31. Dog dog = new Dog("wang", 7);
    32. Animal animal = dog;
    33. System.out.println(animal.name);
    34. System.out.println(animal.age);
    35. animal.eat();
    36. }
    37. }

    通过结果我们看到eat方法和方法中的name都是子类的,由此可以得知当父子和子类方法相同时,我们调用的是子类的

    3.我们知道向上转型的过程中,如果我们想访问子类中的成员属性,我们是办不到的,

     如图当我们访问子类的silly时就会报错,那这种情况下怎么办呢?这时我们应用一下向下转型

    1. public class text {
    2. public static void main(String[] args) {
    3. Dog dog = new Dog("wang", 7);
    4. Animal animal = dog;
    5. dog=(Dog) animal;//向下转型将animal转为dog型这时就可以访问了
    6. System.out.println(dog.silly);
    7. System.out.println(dog.name);
    8. System.out.println(dog.age);
    9. // animal.eat();
    10. }

     在这时因为向下转型的安全性不高,此时我们会加上这句话

    1. public static void main(String[] args) {
    2. Dog dog = new Dog("wang", 7);
    3. Animal animal = dog;
    4. if(animal instanceof Dog)//判断animal是否引用了 Dog对象
    5. {
    6. dog=(Dog) animal;
    7. }
    8. //向下转型将animal转为dog型这时就可以访问了
    9. System.out.println(dog.silly);
    10. System.out.println(dog.name);
    11. System.out.println(dog.age);
    12. // animal.eat();

    多态的具体体现:引用不同的对象来调用同一个函数,表现出不同的效果

    1. class Animal
    2. {
    3. int age;
    4. String name;
    5. public Animal(String name,int age)
    6. {
    7. this.name=name;
    8. this.age=age;
    9. }
    10. public void eat()
    11. {
    12. System.out.println(name+"吃饭");
    13. }
    14. }
    15. class Dog extends Animal
    16. {
    17. String name;
    18. int age;
    19. String silly;
    20. public Dog(String name,int age)
    21. {
    22. super(name,age);
    23. this.silly="笨";
    24. this.name=name;
    25. }
    26. public void eat()
    27. {
    28. System.out.println(name+"吃狗粮");
    29. }
    30. }
    31. class Bird extends Animal
    32. {
    33. String name;
    34. int age;
    35. public Bird(String name,int age)
    36. {
    37. super(name,age);
    38. this.name=name;
    39. }
    40. //String name;
    41. public void fly()
    42. {
    43. System.out.println(name+"正在飞");
    44. }
    45. public void eat()
    46. {
    47. System.out.println(name+"正在吃鸟粮");
    48. }
    49. }
    50. public class text {
    51. public static void animaleat(Animal animal)
    52. {
    53. animal.eat();
    54. }
    55. public static void main(String[] args) {
    56. Dog dog=new Dog("bi",4);
    57. animaleat(dog);
    58. animaleat(new Bird("be",9));
    59. }
    60. }

    如图中我们分别调用函数animaleat,打印出来的结果却不同

     

  • 相关阅读:
    Win11启动修复无效怎么办
    SpringCloudAlibaba+Vue2.0搭建博客项目
    鸿蒙Harmony应用开发—ArkTS声明式开发(鼠标事件)
    收集产品需求的9个渠道
    java-net-php-python-Java奖助学金评审管理系统计算机毕业设计程序
    静态ip和动态ip区别在哪?
    基于JAVA的高校宿管理系统
    《docker基础篇:8.Docker常规安装简介》包括:docker常规安装总体步骤、安装tomcat、安装mysql、安装redis
    MySQL8.0-分组函数ROLLUP的基本用法(GROUPING)
    QT判断平台和生成版本设置输入目录
  • 原文地址:https://blog.csdn.net/m0_70386582/article/details/126268015