Java的编程之旅27——继承

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();
    }
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java基于SSM+JSP的超市进销库存管理系统

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

【深度学习】SSD 神经网络:彻底改变目标检测

一、说明 Single Shot MultiBox Detector (SSD) 是一项关键创新,尤其是在物体检测领域。在 SSD 出现之前,对象检测主要通过两阶段过程执行,首先识别感兴趣的区域,然后将这些区域分类为对象类别。这种方法虽…

Git修改提交的文件的用户名和邮箱

实现效果 提交的测试二,用户名:git1 邮箱:email1,更改成 newGit1、newEmail1 一、概念 Git配置文件级别 系统级、全局级、本地级,生效规则是本地级>全局级>系统级,也就是当本地级配置上此属性,那么…

Uipath 读取Word模板实现录用通知书PDF批量生成

本文主要讲解如何使用Uipath 读取Excel 面试人员信息表,读取Word模板,再批量生成录用通知书PDF文件,该自动化大大提高了HR 的工作效率。 注:本方案实现采用无代码模式,通过拖拉控件实现。 1. 数据准备 1.1 面试人员…

最简单的基于 FFmpeg 的视音频分离器 - 简化版

最简单的基于 FFmpeg 的视音频分离器 - 简化版 最简单的基于 FFmpeg 的视音频分离器 - 简化版正文结果工程文件下载参考链接 最简单的基于 FFmpeg 的视音频分离器 - 简化版 参考雷霄骅博士的文章,链接:最简单的基于FFmpeg的封装格式处理:视音…

开源免费的NTFS for mac工具mounty

开源免费的NTFS for mac工具mounty 安装依赖 brew install gromgit/fuse/ntfs-3g-macbrew install --cask macfuse安装mounty 如果已经安装macFUSE和ntfs-3g-mac,可以直接点击下载的dmg安装包,安装升级。第一次启动mounty,你需要接受一系列…

DFT系列文章之 《DFT Scan chain》

我们知道,运用DFT技术的基本步骤: 1. 规划scan chain 规划 scan chain,首先将电路中的普通 DFF 换成 scan DFF: 2. scan cell 替换 scan DFF 是在原DFF 的输入端增加了一个 MUX,于是多了几个 pin :scan_in,scan_enable,scan_out。换完之后将所有的 scan DFF 首尾依…

dpdk环境搭建和工作原理

文章目录 1、DPDK环境搭建1.1、环境搭建1.2、编译DPDK 2、DPDK工作原理 1、DPDK环境搭建 1.1、环境搭建 工具准备:VMware、ubuntu16.04。 (1)VMware添加两个网卡。桥接网卡作为 DPDK 运行的网卡,NAT 网卡作为 ssh 连接的网卡。 …

C++奇怪的 ::template

答疑解惑 怎么会有::template的写法 起初 在阅读stl的源码的时候&#xff0c;发现了一条诡异的代码 // ALIAS TEMPLATE _Rebind_alloc_t template<class _Alloc,class _Value_type> using _Rebind_alloc_t typename allocator_traits<_Alloc>::template rebind…

AMRT3D数字孪生引擎详解

AMRT 3D数字孪生引擎介绍 AMRT3D引擎是一款融合了眸瑞科技的AMRT格式与轻量化处理技术为基础&#xff0c;以降本增效为目标&#xff0c;支持多端发布的一站式纯国产自研的CS架构项目开发引擎。 引擎包括场景搭建、UI拼搭、零代码交互事件、光影特效组件、GIS/BIM组件、实时数据…

洛谷B2084 质因数分解 题解

#题外话&#xff08;第36篇题解&#xff09;&#xff08;本题为普及-难度&#xff09;&#xff08;c语言&#xff09; #先看题目 #思路 从2遍历到n-1&#xff0c;如果被遍历的数是n的因数&#xff0c;且它是质数&#xff0c;且 n/遍历数 也是个质数&#xff0c;那么n/遍历数就…

LLMs之Gemma:Gemma(Google开发的新一代领先的开源模型)的简介、安装、使用方法之详细攻略

LLMs之Gemma&#xff1a;Gemma(Google开发的新一代领先的开源模型)的简介、安装、使用方法之详细攻略 导读&#xff1a;此文章介绍了Google推出的新一代开源模型Gemma&#xff0c;旨在帮助研发人员负责任地开发AI。 背景&#xff1a; >> Google长期致力于为开发者和研究人…

Java向ES库中插入数据报错:I/O reactor status: STOPPED

Java向ES库中插入数据报错&#xff1a;java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STO 一、问题问题原因 二、解决思路 一、问题 在使用Java向ES库中插入数据时&#xff0c;第一次成功插入&#xff0c;第二次出现以下错误&#xff1a…

Python reversed函数

在Python编程中&#xff0c;reversed()函数是一个内置函数&#xff0c;用于反转序列对象的元素顺序。这个函数可以应用于列表、元组、字符串等可迭代对象&#xff0c;并返回一个反向迭代器&#xff0c;可以按照相反的顺序遍历序列中的元素。本文将深入探讨Python中的reversed()…

springboot邮箱注册

1.准备工作 操作之前准备两个邮箱 我准备了网易邮箱和QQ邮箱&#xff0c;网易邮箱用来发送验证码&#xff0c;QQ邮箱用来做注册&#xff08;希望大家和我一样&#xff0c;不然可能会出错 &#xff09; 发送验证码的邮箱需要开启一些设置&#xff0c;否则不…

FFmpeg解析之avformat_find_stream_info函数

avformat_find_stream_info 的主要作用就是&#xff1a;解析媒体文件并获取相关的流信息 整体的逻辑如下图所示&#xff1a; /*** Read packets of a media file to get stream information. This* is useful for file formats with no headers such as MPEG. This* function…

【Java程序设计】【C00276】基于Springboot的就业信息管理系统(有论文)

基于Springboot的就业信息管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的就业信息管理系统 本系统分为前台功能模块、管理员功能模块、学生功能模块、企业功能模块以及导师功能模块。 前台功能模块&…

第十四章[面向对象]:14.8:枚举类

一,定义枚举类 1,把一个类定义为枚举类: 只需要让它继承自 enum 模块中的 Enum 类即可。 例如在下面的例子中,Weekday 类继承自 Enum 类, 则表明这是一个枚举类 枚举类的每个成员都由 2 部分组成,分别是 name 和 value, 其中 name 属性值为该枚举值的变量名(如下例中: …

SwiftUI 支持拖放功能的集合视图(Grid)如何捕获手指按下并抬起这一操作

功能需求 假设我们开发了一款 SwiftUI 应用,其中用户可以通过拖放 Grid 中的 Cell 来完成一些操作。现在,我们希望用户在某个 Cell 被按下并随后抬起手指时得到通知,这能够实现吗? 如上图所示,我们准确地捕获到了手指在 Grid 的 Cell 上按下再抬起这一操作!那么它是如何…

电子元件分销商

Top 10 Active Electronic Parts Distributors List – 2022 / 2023 一家从众多制造商那里收购所有电子元件并销售给客户的公司被称为电子元件分销商。 A company that acquires all electronic components from numerous manufacturers and sells them to customers from a si…