• Java语法之继承


    上次给大家分享了Java的封装,今天小编给大家分享面向对象三大特性的第二大特性,也就是继承,fighting~~

    目录

     🎄一.继承的概念

    🎄1.1为什么需要继承

    🎄1.2继承的概念

    🎄1.3继承的语法

    🎄1.4父类成员的访问

    🎄1.5子类构造方法

    🎄二.继承的关键字

    🎄2.1super和this关键字

    🎄2.2final关键字

    🎄三.继承的特性

    🎄四.总结


    🎉一. 继承的概念

    1.1 为什么需要继承

    生活中的继承:

    兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

    食草动物和食肉动物又是属于动物类。

    所以继承需要符合的关系是:is-a,父类更通用,子类更具体。

    虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。


    为了方便大家理解,我们举个例子,我们定义一个猫和够,他们都有自己的名字和年龄,这是他们所共有的,但是他们表现出不同的行为,比如狗会汪汪叫,猫会喵喵叫,我们就可以把他们共有的特性抽取出去,写成一个父类,看代码:

     

    既然大家有着同样的属性和方法,我们就可以这样改写:

     那么,这里继承的概念就出来了,没错,这就是继承!从这里不难看出,继承实际上就是用来对共性的抽取,实现对代码的复用!


    1.2 继承的概念

    继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类,继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

    继承的格式:

    在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:

    1. class 父类 {
    2. }
    3. class 子类 extends 父类 {
    4. }

    1.3继承的语法

    语法1.2中就给大家介绍完了,我们这里看一下具体的实现吧,代码:

    1. class Animal {
    2. public String name;
    3. public int age;
    4. public void ageShow() {
    5. System.out.println(name + "今年" + age + "岁了");
    6. }
    7. }
    8. class Dog extends Animal {
    9. public void wangwang() {
    10. System.out.println(name + "汪汪叫!");
    11. }
    12. }
    13. class Cat extends Animal {
    14. public void miaomiao() {
    15. System.out.println(name + "喵喵叫!");
    16. }
    17. }
    18. public class Test_2 {
    19. public static void main(String[] args) {
    20. Dog dog = new Dog();// dog类中并没有定义任何成员变量,name和age
    21. dog.name = "旺财";
    22. dog.age = 3;
    23. dog.ageShow();
    24. Cat cat = new Cat();
    25. cat.name = "咪咪";
    26. cat.age = 5;
    27. cat.ageShow();
    28. }
    29. }

     运行结果:

     注意:

    • 1. 子类会将父类中的成员变量或者成员方法继承到子类中了
    • 2. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了

     1.4 父类成员的访问

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

    1)子类和父类不存在同名成员变量

    1. class Demo {
    2. public int a = 1;
    3. public int b = 2;
    4. public int c = 3;
    5. }
    6. class Base extends Demo {
    7. public void func() {
    8. System.out.println(a);
    9. System.out.println(b);
    10. System.out.println(c);
    11. }
    12. }
    13. public class Test_3 {
    14. public static void main(String[] args) {
    15. Base base = new Base();
    16. base.func();
    17. }
    18. }

     2)子类和父类成员变量同名

    1. class Demo {
    2. public int a = 1;
    3. public int b = 2;
    4. public int c = 3;
    5. }
    6. class Base extends Demo {
    7. int a = 10;
    8. int b = 20;
    9. public void func() {
    10. System.out.println(a);
    11. System.out.println(b);
    12. System.out.println(c);
    13. }
    14. }
    15. public class Test_3 {
    16. public static void main(String[] args) {
    17. Base base = new Base();
    18. base.func();
    19. }
    20. }


    从上面俩个例子我们可以得出:

    • 如果访问的成员变量子类中有,优先访问自己的成员变量
    • 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
    • 如果访问的成员变量与父类中成员变量同名,则优先访问自己的

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

    1)当子类和父类中成员方法名字不同

    1. class Demo {
    2. public void Basefun1() {
    3. System.out.println("父类");
    4. }
    5. }
    6. class Base extends Demo {
    7. public void Basefun() {
    8. System.out.println("子类");
    9. }
    10. public void func() {
    11. Basefun();
    12. Basefun1();
    13. }
    14. }
    15. public class Test_3 {
    16. public static void main(String[] args) {
    17. Base base = new Base();
    18. base.func();
    19. }
    20. }

    这里也不难看出,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。

    2)当子类和父类中成员方法名字相同

    1. class Demo {
    2. public void Basefun() {
    3. System.out.println("父类");
    4. }
    5. }
    6. class Base extends Demo {
    7. public void Basefun() {
    8. System.out.println("子类");//优先调用子类自己的方法
    9. }
    10. public void func() {
    11. Basefun();
    12. }
    13. }
    14. public class Test_3 {
    15. public static void main(String[] args) {
    16. Base base = new Base();
    17. base.func();
    18. }
    19. }

    从输出结果我们可以出,通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。


    1.5 子类构造方法

    子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。我们也可通过构造方法给父类中的成员变量赋值:

    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 ageShow() {
    9. System.out.println(name + "今年" + age + "岁了");
    10. }
    11. }
    12. class Dog extends Animal {
    13. public void wangwang() {
    14. System.out.println(name + "汪汪叫!");
    15. }
    16. public Dog(String name,int age){
    17. super(name, age);
    18. }
    19. }
    20. class Cat extends Animal {
    21. public void miaomiao() {
    22. System.out.println(name + "喵喵叫!");
    23. }
    24. public Cat(String name,int age){
    25. super(name, age);
    26. }
    27. }
    28. public class Test_2 {
    29. public static void main(String[] args) {
    30. Dog dog = new Dog("旺财",3);
    31. dog.ageShow();
    32. dog.wangwang();
    33. Cat cat = new Cat("咪咪",5);
    34. cat.ageShow();
    35. cat.miaomiao();
    36. }
    37. }

     

     注意:

    • 1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构
    • 造方法
    • 2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的
    • 父类构造方法调用,否则编译失败。
    • 3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
    • 4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

    🎉二. 继承的关键字

    2.1 super和this关键字

    1)super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

    2)this关键字:指向自己的引用。

    举个例子,这里我们主要介绍super:

    1. class Test1 {
    2. public int a = 1;
    3. public int b = 2;
    4. }
    5. class Test2 extends Test1 {
    6. public int a = 10;
    7. public int b = 20;
    8. void fun() {
    9. System.out.println(a);
    10. System.out.println(super.b);
    11. }
    12. }
    13. public class Test_3 {
    14. public static void main(String[] args) {
    15. Test2 test2 = new Test2();
    16. test2.fun();
    17. }

    如果这里我们要通过子类去访问父类中的成员,就需要在成员变量前面加上super关键字,这里我们就可以访问到上述代码中父类b的值了!


    2.2 final关键字

    final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。

    final 含义为 "最终的"。

    使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:

    1. public class Test_4 {
    2. final int a = 10;
    3. a=20;//被final修饰的变量是被密封的,不允许修改的
    4. }
    1. class one {
    2. }
    3. final class tow extends one {
    4. }
    5. class three extends tow{ //被final修饰的类是不能被继承的,属于密封类
    6. }

     🎉三. 继承的特性

    1)继承的类型

    需要注意的是 Java 不支持多继承,但支持多重继承。

     2)继承的特性

    • 子类拥有父类非 private 的属性、方法。

    • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

    • 子类可以用自己的方式实现父类的方法。

    • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

    • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。


     🎉四. 总结

    继承是java中一个重要的语法,小编也是初学者,如对上文有意见或者有错误,还请大佬们斧正,觉得有帮助的童鞋们,创作不易,蟹蟹三连!

  • 相关阅读:
    力扣刷题笔记
    Mac PS2023/2024储存窗口黑屏不显示 解决方法
    .NET 反向代理-YARP
    线性表01- 数组与简易接口设计
    vue(11)
    JAVA客户端使用账号密码调用influxdb2报错:{“code“:“unauthorized“,“message“:“Unauthorized“}
    高频面试题1,删除有序数组重复元素
    基于分布式 KV 存储引擎的高性能 K8s 元数据存储项目 —— KubeBrain
    前端培训丁鹿学堂:js异步及解决方案简析
    boomYouth
  • 原文地址:https://blog.csdn.net/m0_63635730/article/details/127938058