• Java三大特性篇之——继承篇(超详解的好吧!)


    😍😍😍欢迎欢迎欢迎欢迎,我的朋友,答应我,看完好吗?🥴

    前言:何为继承?

    在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物,具体如下图所示。
    在这里插入图片描述
    当然在猫之后也会有波斯猫、狸花猫等等可以继承猫类;同时也有二哈,卷毛等继承狗类,这些动物之间会形成一个继承体系,这就是我们今天要说的继承问题!
    继承是面向对象语法的三大特征之一。继承可以降低代码编写的冗余度,提高编程的效率。通过继承,子类获得了父类的成员变量和方法。那么一个子类如何继承父类的属性和方法呢?我们又该如何修改继承过来的方法呢。更符合我们的需求呢?接下来我们开始学习有关Java继承的相关知识。

    不谈钱的继承实现!

    在Java中,类的继承是指程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。子类会自动拥有父类所有可继承的属性和方法。在程序中,如果想声明一个类继承另一个类,需要使用extends关键字。

    通过 extends 关键字让类与类之间产生继承关系。

    多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。

    说明事项:

    • 子类可以直接访问父类中的非私有的属性和行为。
    • 子类无法直接使用父类中私有的内容。
    • 父类是共性的抽取

    eg:

    class teacher{             //声明一个teacher类为父类
        String name;      	   //定义父类的成员变量name、age
        int age;
        void show(){           //定义父类成员方法,将成员变量输出
            System.out.println(name);
            System.out.println(age);
        }
    }
    class Student extends teacher {
        //声明一个Student类为子类并继承父类
    }
    class show {
        public static void main(String[] args) {
            System.out.println("学生");
            Student student=new Student();     //声明一个Student类的实例对象student
            student.name="Tom";                //子类调用父类的成员变量name并赋值
            student.age=19;                    //子类调用父类的成员变量age并赋值
            student.show();                    //子类调用父类的成员方法show
        }
    }
    
    
    public class text1 {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    效果如下:
    在这里插入图片描述

    在Java中,注意事项如下:

    • Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;
    • 可以多层继承,即子类也可以作为父类。
    • 子类不能选择性继承父类。
    • 构造方法不会被子类继承,但可以从子类中调用父类的构造方法。

    嘘:偷偷访问父类的私密成员!

    我们这时候是肯定不能直接访问的,我们需要声明一个公有方法,来帮我们偷偷摸摸的实现(‾◡◝):

    class Af{                     //父类A
        private int secret=10;    //声明一个私有变量sevret并赋值为10
        public int getsecret() {  //声明一个公有成员方法getvalue,返回value
            return secret;
        }
    }
    class Bs extends Af{           //A的子类B
    }
    class Cc {
        public static void main(String[] args) {
            Bs b=new Bs();           //创建子类B的一个实例对象
            System.out.println("子类通过父类提供的公共接口访问A中的私有字段secret:"+b.getsecret());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    大功告成:
    在这里插入图片描述

    这是:方法的重写&super关键字!

    子类继承了父类中的所有成员及方法,但在某种情况下,子类中该方法所表示的行为与其父类中该方法所表示的行为不完全相同,例如,在父类语言中定义了说话这个方法,而在子类中说话的方法是不同的:外国人说英文,中国人说中文,这时我们就需要重写父类的该方法
    eg:

    class A{
        public void sayHello() {                      //输出英文欢迎
            System.out.println("Hello,Welcome to Java!!!");
        } 
    }
    
    class B extends A {
        public void sayHello() {                      //输出中文欢迎  
            System.out.println("大家好,欢迎学习Java!!!");
        }
    }
    
    class People {
        public static void main(String[] args) {
            B b=new B();                                //创建子类B的一个实例对象,使用默认构造方法
            b.sayHello();                               //调用子类中重写的方法
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    注意事项

    • 重写的方法具有与其所重写的方法相同的名称、参数数量、类型和返回值。
    • 被重写的方法,其访问权限大于等于被其重写的方法

    当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。但同时由于因场景需要或者是其他的一些原因,子类如果要在子类方法中访问父类同名成员时,该如何操作?Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。
    具体使用如下:

    class A{
        public void sayHello() {                      //输出英文欢迎
            System.out.println("Hello,Welcome to Java!!!");
        }
    
    }
    class B extends A {
        public void sayHello() {//输出中文欢迎
            super.sayHello();                        // 调用父类中被重写的方法
            System.out.println("大家好,欢迎学习Java!!!");
        }
    }
    class People {
        public static void main(String[] args) {
            B b=new B();                                //创建子类B的一个实例对象,使用默认构造方法
            b.sayHello();                               //调用子类中重写的方法
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    当然,我们的super可不止这一个功能,super相比于this可谓神似,所以也可以使用super来调用父类的构造函数

    class C{
        int age ;
        String name;
    
        public C() {
            System.out.println("这是c的构造方法!");
        }
    }
    
    class D extends C{
    
    }
    
    public interface text {
        public static void main(String[] args) {
            D d=new D();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    结果如下:
    在这里插入图片描述

    隐藏起来的小坏蛋——构造函数!

    我们前面说过,子类不能继承父类的构造函数,然而:子类继承了父类,获取到了父类中属性与方法,所以在使用子类之前,要先看父类是如何对自己的内容进行初始化的。换言之,我们要在使用子类的构造函数之前调用父类的构造函数
    如下:

    class C{
        int age ;
        String name;
    
        public C(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }
    
    class D extends C{
        //报错!
    }
    
    public interface text {
        public static void main(String[] args) {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这段代码是无法编译的!!!

    用来强大的java会自动给我们的子类生成一个代码段:

    public D() {
            super();
        }
    
    • 1
    • 2
    • 3

    可见生成的是父类与子类的无参数构造方法,而我们在父类中定义了一段有参数的构造方法,我们在类和对象中知道,当我们写了构造方法时,就不会再生成一个无参的构造方法!所以这里我们的super()找不到对于方法,只能报错!因此,我们可以如下修改:

    class C{
        int age ;
        String name;
    
        public C(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }
    
    class D extends C{
        public D(int age, String name) {
            super(age, name);                         //不在报错!
        }
    }
    
    public interface text {
        public static void main(String[] args) {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意事项:

    • 当父类中没有空参数的构造函数时,子类的构造函数必须通过super语句指定要访问的构造函数。

    • 子类构造函数中如果使用this调用了本类构造函数,那么默认的super();就没有了,因为super和this都只能定义在第一行,所以只能有一个。但是可以保证的是,子类中肯定会有其他的构造函数访问父类的构造函数。

    • super语句必须要定义在子类构造函数的第一行!因为父类的初始化动作要先完成。

    final关键字&&貌似结束了

    inal关键字可用于修饰类、变量和方法,它有“**无法改变”或者“最终”**的含义,因此被final修饰的类、变量和方法将具有以下特性:

    • final修饰的类不可以被继承

    • final修饰的方法不可以被覆盖

    • final修饰的变量是一个常量,只能被赋值一次且必须直接赋值

    那么 为什么要用final修饰变量?其实,在程序中如果一个数据是固定的。那么直接使用这个数据就可以了,但是这种阅读性差,所以应该给数据起个名称。而且这个变量名称的值不能变化,所以加上final固定!

    final int a = 10;
    a = 20; // 编译出错
    
    final public class Animal {
    ...
    }
    public class Bird extends Animal {
    ...
    }
    // 编译出错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    最后:博主想说啥?

    好了,有关Java继承的知识讲到这里了,谢谢观看!!!如果文章有问题,还请大家指出,我们一起进步!

    我们下篇文章再见!!!

    博主相信:成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。 朋友们,我们顶峰相见!

  • 相关阅读:
    【深度学习】实验6布置:图像自然语言描述生成(让计算机“看图说话”)
    创建Django项目_first_Django
    cesium 实现三维无人机航拍过程实景效果
    scala集合的partition方法使用
    nrm的安装以及使用
    安装Docker(Linux:CentOS)
    【TS】泛型以及多个泛型参数
    RPM 与 DPKG 使用
    华为云大咖说:开发者应用AI大模型的“道、法、术”
    【C++进阶】:C++11
  • 原文地址:https://blog.csdn.net/m0_65038072/article/details/127891519