Java的编程之旅27——继承

news2024/10/7 6:46:25

1.继承的简介

继承是面向对象编程中的一个重要概念,指的是一个类可以继承另一个类的属性和方法。被继承的类称为父类或基类,继承这个父类的类称为子类或派生类。

通过继承,子类可以继承父类的属性和方法,使得子类具有相似的行为和特性。子类可以重写父类的方法,覆盖父类的行为,也可以添加新的属性和方法以扩展父类的功能。

继承提供了代码复用的机制,可以减少代码的冗余,并且使得代码更加可维护和扩展。此外,继承也是实现多态的基础,通过父类的引用可以调用子类的方法,实现不同对象的统一操作。


2.代码中的体现

定义一个名为“Person”的类,作为父类 

public class Person{
    String name;
    int age;
    
    public Person(){}
    
    public Person(String name ,int age){
        this.name = name;
        this.age = age;
    }
        
    public void eat(){
        System.out.println("人会吃~");
    }
    
     public void sleep(){
        System.out.println("人会睡~");
    }

}

这段代码定义了一个名为Person的类。Person类包含了两个属性:name(姓名)和age(年龄)。类中定义了两个构造方法:一个无参构造方法和一个带有参数的构造方法,用于初始化name和age属性。

类中还定义了两个方法:eat(吃)和sleep(睡)。这两个方法是公共的(public),可以被其他类调用。eat方法输出了一个字符串,表示人会吃;sleep方法输出了一个字符串,表示人会睡。

这个Person类是一个基类,其他类可以通过继承这个类来继承其中的属性和方法。通过继承,子类可以使用Person类中定义的属性和方法,并可以根据需要进行扩展和修改。

定义一个名为“Teacher”的子类用来继承“Person”

public class Teacher extends Person{
    int teachAge;

    //构造方法
    public Teacher(){

    }

    public Teacher(int teachAge) {
        TeachAge = teachAge;
    }

    public Teacher(String name,int age,int teachAge){
        super(name, age);
        TeachAge = teachAge;
    }
    
    public void teach(){
        System.out.println("老师会教书");
    }
}

这段代码定义了一个名为Teacher的类,它继承自Person类。Teacher类有一个额外的实例变量teachAge,表示教学年龄。

代码中提供了三个构造方法:

  1. 无参构造方法:没有参数,什么也不做。
  2. 带参构造方法:接受一个int类型的teachAge参数,并将其赋值给Teacher类的实例变量teachAge。
  3. 带参构造方法:接受一个字符串name、一个int类型的age和一个int类型的teachAge参数,并将name和age传递给父类Person的构造方法进行初始化,同时将teachAge赋值给Teacher类的实例变量teachAge。

Teacher类还有一个公共方法teach(),它打印出"老师会教书"的消息。

这段代码实现了一个教师类,继承了人类,具有教学年龄的特征,并能够进行教学操作。

最后定义一个功能测试类

public class Test {
    public static void main(String[] args) {
        Person person = new Person("hh",22);
        System.out.println(person.name+","+person.age);
        person.eat();
        person.sleep();

        Teacher teacher = new Teacher("jj",56,12);
        System.out.println(teacher.name+","+teacher.age+","+teacher.TeachAge);
        teacher.eat();
        teacher.sleep();
        teacher.teach();
    }
}

输出结果: 

这段代码定义了一个名为Test的类,其中有一个main方法作为程序的入口点。

在main方法中,首先创建了一个Person对象,通过调用Person类的带参构造方法,传入字符串"hh"和整数22进行初始化。然后通过person对象访问其实例变量name和age,并将结果打印出来。接着调用person对象的eat()方法和sleep()方法,输出对应的消息。

接下来,创建了一个Teacher对象,通过调用Teacher类的带参构造方法,传入字符串"jj"、整数56和整数12进行初始化。然后通过teacher对象访问其父类Person中的name和age实例变量,以及Teacher类自身的TeachAge实例变量,并将结果打印出来。接着调用teacher对象的eat()方法和sleep()方法,输出对应的消息。最后通过调用teacher对象的teach()方法,输出"老师会教书"的消息。


3.super关键字的用法

1.定义一个名为“Father”的父类

public class Father {
    String name;
    int age;

    public Father() {
    }

    public Father(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(this.age+"岁的"+this.name+"会吃");
    }
}

这段代码定义了一个名为Father的类。Father类有两个实例变量name和age,代表父类成员中的姓名和年龄。

Father类有两个构造方法,一个是无参构造方法,一个是有参构造方法。无参构造方法不进行任何操作,而有参构造方法用于初始化父类成员的姓名和年龄。

Father类还有一个eat()方法,用于输出年龄和姓名,并打印一句话表示吃的动作。

2.定义一个名为“Child”的子类用来继承“Father”父类

public class Child extends Father{
    String name;
    int age;

    public Child() {
    }

    public Child(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Child(String name, int age, String name1, int age1) {
        super(name, age);
        this.name = name1;
        this.age = age1;
    }

    public void eat(){
        //所表达的是子类中的“xx岁的xx会吃”
        System.out.println(this.age+"岁的"+this.name+"会吃");

        //表达父类中的”xx岁的xx会吃“
        System.out.println(super.age+"岁的"+super.name+"会吃");
        //还可以用super关键字直接调用父类中的方法
        //super.eat();
    }
}

这段代码定义了一个名为Child的类,它继承自Father类。Child类也有两个实例变量name和age,但是它们与父类的name和age变量没有任何关系。

Child类有三个构造方法,一个是无参构造方法,一个是有两个参数的构造方法,另一个是有四个参数的构造方法。其中有两个参数的构造方法用于初始化子类自己的name和age变量,四个参数的构造方法不仅会调用父类的有参构造方法来初始化父类的name和age变量,还会初始化子类的name和age变量。

Child类也有一个eat()方法,但是与父类的eat()方法不同的是,它重写了父类的eat()方法。在重写的eat()方法中,首先输出子类自己的年龄和姓名,并打印一句话表示吃的动作。然后使用super关键字调用父类的age和name变量,并打印一句话表示父类的吃的动作。最后还可以使用super关键字直接调用父类的eat()方法。

3.定义一个测试类

public class Test {
    public static void main(String[] args) {
        Father father = new Father("老贺",40);
        father.eat();
        Child child = new Child("小贺",18);
        child.eat();
    }
}

注意:输出结果的后一行有点反常,这是因为只调用了Child类中的public Child(String name, int age)方法,而这是属于子类中的方法,和父类没有关系

 public void eat(){
        //所表达的是子类中的“xx岁的xx会吃”
        System.out.println(this.age+"岁的"+this.name+"会吃");

        //表达父类中的”xx岁的xx会吃“
        System.out.println(super.age+"岁的"+super.name+"会吃");
        //还可以用super关键字直接调用父类中的方法
        //super.eat();
    }

所以eat()方法中后一个语句输出的是父类中所定义的值,要想正常输出,则需要重新new一个child

对象,用来调用public Child(String name, int age, String name1, int age1) 这个构造方法

更改后的主函数: 

public class Test {
    public static void main(String[] args) {
        Father father = new Father("老贺",40);
        father.eat();
        Child child = new Child("小贺",18,"老贺",40);
        child.eat();
    }
}

输出结果


4.继承中的权限

在Java中,继承中的权限是通过访问修饰符来控制的。Java中有四种访问修饰符:public、protected、default和private。

  1. public:被public修饰的成员(字段、方法、构造方法等)可以在任何地方被访问,包括其他类、不同包中的类和子类。

  2. protected:被protected修饰的成员可以被同一个包中的类访问,也可以被不同包中的子类访问,但不能被不同包中的非子类访问。

  3. default:没有修饰符的成员(也称为包级访问)可以被同一个包中的类访问,但不能被不同包中的类访问。

  4. private:被private修饰的成员只能在同一个类中访问,不能被其他类或子类访问。

继承关系中,子类会继承父类的字段和方法。下面是不同访问修饰符下,子类对父类成员的访问权限:

  • public成员:子类可以访问父类的public成员。

  • protected成员:子类可以访问父类的protected成员,即使子类和父类不在同一个包中。

  • default成员:子类可以访问父类的default成员,但是要求子类和父类在同一个包中。

  • private成员:子类无法直接访问父类的private成员,只能通过父类的public/protected/default方法来间接访问。

需要注意的是,子类可以覆盖(重写)父类的方法,但是子类不能降低父类方法的访问权限。也就是说,如果父类的方法是public,那么子类重写该方法时也必须使用public修饰符。同样地,如果父类的方法是protected,子类重写该方法时可以使用protected或public修饰符,但不能使用private修饰符或不使用任何修饰符(default)。

这样设计的目的是为了保护类的封装性和安全性,子类只能通过继承和重写的方式来访问和修改父类的成员。

public class Fu {
    public String varPub = "我是公成员变量";
    private String varPri = "我是私有成员变量";
    protected String varPro = "我是受保护的变量";
    String varDef = "我是默认的变量";
}
public class Zi extends Fu{
    public void method(){
        System.out.println(this.varPub);
        //System.out.println(this.varPri);
        System.out.println(this.varPro);
        System.out.println(this.varDef);
    }
}
public class TS {
    public static void main(String[] args) {
        Fu fu = new Fu();
        System.out.println(fu.varPub);
        System.out.println(fu.varPro);
        System.out.println(fu.varDef);
        //System.out.println(fu.varPri);
        //除了private,其他权限都可在当前包内的其他类中都可访问
        System.out.println("============");
        Zi zi = new Zi();
        zi.method();//同包子类中,除私有权限外都可调用
    }
}

 在另一包内在定义一个子类

public class Zi extends Fu {
    public void method(){
        System.out.println(super.varPub);
        //System.out.println(super.varPri);
        System.out.println(super.varPro);
        //System.out.println(super.varDef);
        //不同包子类,只有公有和受保护变量可以被调用
    }
}
public class Ts {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method();
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1467195.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS实现半边边框(只有边框的部分可见)

CSS实现半边边框&#xff08;只有边框的部分可见&#xff09; <div class"part box"><h1>内容</h1><!-- 绘出下面两个对角边框--><div class"part-footer"></div> </div>主要代码 .box {width: 100px;height:…

博睿数据率先发布HarmonyOS NEXT系统的应用异常观测SDK

近日&#xff0c;博睿数据作为业界领先的厂商&#xff0c;凭借对技术的深刻理解和前瞻性视野&#xff0c;率先发布支持HarmonyOS NEXT&#xff08;"纯血鸿蒙"&#xff09;系统的应用异常观测SDK&#xff0c;实现了应用异常的全面回溯。这一突破性技术将引领行业标准&…

为什么前端开发变得越来越复杂了?这可能是我们的错

前端训练营&#xff1a;1v1私教&#xff0c;终身辅导计划&#xff0c;帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~ Hello&#xff0c;大家好&#xff0c;我是 Sunday。 最近有很多同学来问我&#xff1a;“Sunday 老师&#xff0c;前端学起…

从 0 开始在项目中引入 Element Plus

此前&#xff0c;已经写文章介绍了如何《从 0 开始创建 Vue 项目》&#xff0c;今天我们来说说&#xff0c;怎么在 Vue 项目中引入 Element Plus。 文章目录 一、简介二、准备三、安装 Element Plus四、快速上手五、自动导入总结 一、简介 Element Plus 是一个基于 Vue 3.0 重…

【实战篇】Redis单线程架构的优势与不足

前言 01 Redis中的多线程02 I/O多线程03 Redis中的多进程问题 04 结论 很多人都遇到过这么一道面试题&#xff1a;Redis是单线程还是多线程&#xff1f;这个问题既简单又复杂。说他简单是因为大多数人都知道Redis是单线程&#xff0c;说复杂是因为这个答案其实并不准确。 难道R…

uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

因项目需要&#xff0c;在uniapp中集成使用腾讯地图&#xff0c;为了方便维护&#xff0c;希望通过一套代码实现H5和APP同时可用。H5显示相对简单&#xff0c;APP端比较麻烦&#xff0c;记录下实现过程 一、集成步骤 1.使用 renderjs script标签使用renderjs&#xff0c;因为…

互联网加竞赛 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#x…

[yolov9]使用python部署yolov9的onnx模型

【框架地址】 https://github.com/WongKinYiu/yolov9 【yolov9简介】 在目标检测领域&#xff0c;YOLOv9 实现了一代更比一代强&#xff0c;利用新架构和方法让传统卷积在参数利用率方面胜过了深度卷积。 继 2023 年 1 月 正式发布一年多以后&#xff0c;YOLOv9 终于来了&a…

NXP实战笔记(八):S32K3xx基于RTD-SDK在S32DS上配置LCU实现ABZ解码

目录 1、概述 2、SDK配置 2.1、IO配置 2.2、TRGMUX配置 2.3、LCU配置 2.4、Trgmux配置 2.5、Emios配置 2.6、代码实现 1、概述 碰到光电编码器、磁编码器等,有时候传出来的位置信息为ABZ的方式,在S32K3里面通过TRGMUX、LCU、Emios结合的方式可以实现ABZ解码。 官方…

Linux快速修改ip地址

Linux修改IP配置 一 、查找ip配置文件 ifcfg-ens33二、编辑 vi ifcfg-ens33文件三、重启网络或者重启系统 一 、查找ip配置文件 ifcfg-ens33 cd /etc/sysconfig/network-scripts/ls //查看network-scripts文件夹下面的文件二、编辑 vi ifcfg-ens33文件 vi ifcfg-ens33注意&…

初始化(挂载)Linux数据盘(小于2TB)

本文中的操作系统以Linux CentOS 7.5 64位操作系统为例&#xff0c;采用fdisk分区工具为数据盘设置分区。 前提条件 已成功挂载云硬盘。 创建磁盘分区 如果数据盘对外呈现为一个磁盘&#xff0c;不需要分区&#xff0c;可以跳过此步骤。 1.登录Linux实例。 2.运行如下命令&…

Rust核心:【所有权】相关知识点

rust在内存资源管理上采用了&#xff08;先进优秀&#xff1f;算吗&#xff09;但特立独行的设计思路&#xff1a;所有权。这是rust的核心&#xff0c;贯穿在整个rust语言的方方面面&#xff0c;并以此为基点来重新思考和重构软件开发体系。 涉及到的概念点&#xff1a;借用&am…

【Vuforia+Unity】AR05-实物3D模型识别功能实现(ModelTarget )

不管是什么类型的识别Vuforia的步骤基本都是: 把被识别的物体转成图、立体图、柱形图,3D模型、环境模型,然后模型生成Vuforia数据库-导入Unity-参考模型位置开始摆放数字内容,然后参考模型自动隐藏-发布APP-识别生活中实物-数字内容叠加上去! 对于3D物体的识别,可以是虚…

鸿蒙原生应用再添一批新丁!看看新闻、 随申办、浙里办、得物、新零售事业群等入局鸿蒙

鸿蒙原生应用再添一批新丁&#xff01;看看新闻、 随申办、浙里办、得物、新零售事业群等入局鸿蒙 来自 HarmonyOS 微博2月22日消息&#xff0c;#鸿蒙千帆起#上海广播电视台旗下 看看新闻KNEWS 宣布启动鸿蒙原生应用开发&#xff0c;上海广播电视台也成为了全国首家推行鸿蒙原…

Linux运维-Web服务器的配置与管理(PHP)

Web服务器的配置与管理(PHP) 项目场景 某企业在CentOS上搭建Web服务系统&#xff0c;以PHP作为网页开发环境&#xff0c;以MySQL为后台数据库。 基础知识 PHP PHP原始为Personal Home Page的缩写&#xff0c;已经正式更名为 “PHP: Hypertext Preprocessor”&#xff08;超…

Jetson Xavier NX 与笔记本网线连接 ,网络共享,ssh连接到vscode

Jetson Xavier NX 与笔记本网线连接 &#xff0c;网络共享&#xff0c;ssh连接到vscode Jetson Xavier NX桌面版需要连接显示屏、鼠标和键盘&#xff0c;操作起来并不方便&#xff0c;因此常常需要ssh远程连接到本地笔记本电脑&#xff0c;这里介绍一种连接方式&#xff0c;通过…

Cartographer 多分辨率地图和分支定界算法

多分辨率地图 函数调用 PrecomputationGridStack2D 这个图直接让我想起了图像处理中的膨胀操作。膨胀就是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。 滑窗操作会导致地图变大。 假设原始栅格地图尺寸为[h,…

第一个 Angular 项目 - 添加服务

第一个 Angular 项目 - 添加服务 这里主要用到的内容就是 [Angular 基础] - service 服务 提到的 前置项目在 第一个 Angular 项目 - 动态页面 这里查看 想要实现的功能是简化 shopping-list 和 recipe 之间的跨组件交流 回顾一下项目的结构&#xff1a; ❯ tree src/app/…

第3部分 原理篇2去中心化数字身份标识符(DID)(3)

3.2.2.4. DID文档 (DID Document) 本聪老师&#xff1a;DID标识符和DID URL还都只是ID&#xff0c;必须为它附加一个基本属性才可以证明是该主体独有的。这个就是我们下面介绍的DID文档。 本聪老师&#xff1a;每个DID标识符都唯一对应一个DID文档&#xff0c;也可以说&#x…

什么是负载均衡集群?

目录 1、集群是什么&#xff1f; 2、负载均衡集群技术 3、负载均衡集群技术的实现 4、实现效果如图 5、负载均衡分类 6、四层负载均衡&#xff08;基于IP端口的负载均衡&#xff09; 7、七层的负载均衡&#xff08;基于虚拟的URL或主机IP的负载均衡) 8、四层负载与七层…