java中的继承和组合

news2025/7/6 12:19:11

继承

        在java中继承指的是让类与类之间产生父子关系,被继承的类叫做父类或者基类、超类,继承的类叫做子类或者派生类。这里所说的继承和现实生活中的继承可以理解为同一个意思。当子类继承父类时,子类就能使用父类之中的非私有成员,包括成员变量和成员方法。这里要注意的是子类能使用的父类成员变量和成员方法都只能是非私有的,比如父类中用private修饰的成员方法和成员变量就无法在子类中被使用。这个就像某位富豪死后他的后代会继承他的财产,不过在这些财产中有一些是富豪的私人物品,富豪用了一把单独的锁给锁起来了,即使他的后代继承了所有权,但仍然无法使用箱子里被锁起来的动西。

        在java中,当使用继承后就能够发现,子类继承父类后如果要实现父类的某些功能,如果没有特别强调,那是不需要重新写代码的,这就体现了继承的优点,能够提高代码的复用性,,简化了代码结构,提高了代码的可维护性,但是显而易见,当使用继承时,可以理解为子类和父类相通了,因此父类代码的封装性被打破了,提高了代码的耦合性。

继承的实现

        在java中,通过关键字extends来实现子类对父类的继承。extends的意思不是继承而是扩展。这里需要说的是为什么子类是父类的扩展呢?其实子类肯定是有自己的成员变量和成员方法的,当子类继承父类之后,在拥有父类的成员变量和成员方法外,还有属于它自己的成员方法和成员变量,这样一看,子类的范围就比父类的范围更大了,因此叫扩展。此外,这个就像一个石油老板的儿子又加入了房地产开发一样,他不仅拥有了石油老板的石油产业还拥有了自己的房地产产业,那么对于这个家族来说吗,产业在这个石油老板儿子的手下被扩展了。

        在java中,实现扩展的语法为:

                        class 父类{

                                //….

                        }

                        class 子类 extends 父类{

                                //…..

                        }

        需要注意的是,如果没有明确说明写的类是哪一个类的子类,那么默认为这个类是Object类的子类,也就是说,在java中程序员写的类都是Object类的子类。

方法重写

        方法重写是指在子类中出现和父类中相同的方法的现象,又叫方法的复写和方法的覆盖。具体表象为,当子类中要用到父类中的方法,但是方法的功能和父类中方法的功能在实现上又有差异时会将父类中的这个方法重新写一遍,并在实现细节上做出修改。也是由于这个原因,要求在子类中进行方法重写时方法明、参数列表以及返回值的类型必须和父类中的相同。

        这里需要特别注意,方法重载和方法重写的区别,由于只有一字之差故而时常被混淆。根据方法重载中提到的区分方法的方式能够发现,方法重载针对的是方法名相同的不同方法来说的,而且这些方法在同一个类中,而对于方法重写,由于方法名和参数列表均相同,因此可以认为他们是同一个方法,并且方法重写是子类中对父类的方法重写,也就是说并不在同一个类中发生,也就是说,方法重写和方法重载是啷个完全不相同的概念。

        此处,举一个例子用来演示方法的重写。定义一个Animal类,在这个类中定义一个eat方法。然后定义一个Dog类,狗的eat方法实现要比动物的细节,所有的动物都需要进食,不过狗狗能具体到需要吃什么,所以在Dog类中重写eat方法。

        这时在测试类中创建一个Dog类对象,对象名为布鲁斯,调用eat方法,打印结果应该是“布鲁斯吃骨头”。

package jiangchen.practice1;

//定义父类Animal
public class Animal {
    //姓名
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Animal() {
    }

    public Animal(String name) {
        this.name = name;
    }
//成员方法
    public void eat(){
        System.out.println("吃饭");
    }
}
package jiangchen.practice1;

//子类
public class Dog extends Animal {
    private String name;
    public void setName(String name){
        this.name = name;

    }
    public String getName(){
        return name;
    }
    @Override
    public void eat() {
        System.out.println(getName()+"吃骨头");
    }
    public void watch(){
        System.out.println("狗会看家");
    }
}
package jiangchen.practice1;

public class Test {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.setName("布鲁斯");
        showAnimal(d);
    }
    public static void showAnimal(Animal an){
      if(an instanceof Dog){
          Dog dog = (Dog)an;
          dog.watch();
      }
      an.eat();
    }
}

instanceof运算符

        instanceof运算符是二元运算符,他的左边是对象,右边是类。当左边的对象是右边的类或者子类创建的对象时,返回true否则返回false。这里要注意,当instanceof运算符的右边是左边对象对应的类或者这个类的父类时,返回的值都是true。比如在上面的的Dog类和Animal类中,定义一个属于Dog类的对象dog,运用运算符instanceof进行运算dog instanceof Dog 和 dog instandeof Animal,返回的值都是true。

super关键字

         super关键字在java中可以理解成直接父类对象的引用,可以通过super关键字来访问父类中被子类覆盖的方法或者属性。

        在java中,当编写一个子类用来继承父类时,父类中的数据并没有被替换,而是被子类的数据覆盖了,这样在子类中,当调用和父类中名称相同的变量或者方法时如果没有使用关键字super则优先调用子类中的变量或者方法。

        比如在下面这个程序中,创建了一个父类,父类中有一个成员变量叫value,给其赋值为100,在这个父类的子类中也创建一个成员变量value,给其赋值为200,当没有使用super关键字强调时调用的时子类中的value,当使用super关键字强调时调用的时父类中的value。

public class SuperTest {
    public static void main(String[] args) {
        new ChildClass().f();
    }
}
class FatherClass{
    public int value;
    public void f(){
        value = 100;
        System.out.println("FathersClass.value="+value);
    }

}
class ChildClass extends FatherClass{
    public int value;
    public void f(){
      super.f();
      value = 200;
        System.out.println("ChildClass.value="+value);
        System.out.println(value);
        System.out.println(super.value);
    }
}

import org.w3c.dom.ls.LSOutput;

public class TestSuper01 {
    public static void main(String[] args) {
        System.out.println("开始创建一个ChildClass01对象……");
        new ChildClass01();
    }
}
class FatherClass01{
    public  FatherClass01(){
        System.out.println("创建一个FstherClass01类");
    }

}
class ChildClass01 extends FatherClass01 {

    public  ChildClass01(){
        System.out.println("创建一个ChildClass类");
    }
}

        在关于super关键字的使用中,还需要说明的是super()。这个方法是系统会默认加在子类的构造方法中的,也就是在写子类构造方法是,第一行就隐藏了super();代码,这个代码是用来调用父类的无参构造方法的。如果要调用父类的有参构造方法,只要在super()的括号内的输入父类含参构造方法中的参数即可。这里要特别注意的是,无论调用的父类构造方法是否含有参数,都只能放在子类构造方法的第一行。

        这里用一个例子来说明super()的运用。如下代码所示。从他的运行结果中能看出,在创建子类对象的时候,即使没有调用super()方法,在调用子类的构造器时,也会先调用父类的无参构造器。

import org.w3c.dom.ls.LSOutput;

public class TestSuper01 {
    public static void main(String[] args) {
        System.out.println("开始创建一个ChildClass01对象……");
        new ChildClass01();
    }
}
class FatherClass01{
    public  FatherClass01(){
        System.out.println("创建一个FstherClass01类");
    }
    /* FatherClass01(int a){
        System.out.println("创建一个带参数的父类构造器");
    }*/

}
class ChildClass01 extends FatherClass01 {
    public  ChildClass01(){
        //super();不用特意编写,系统自动加上的
        //super(3)若要调用含参构造器,只需要调用super()时输入对应参数即可
        System.out.println("创建一个ChildClass类");

    }

}

组合

        在java中,使用继承的主要目的是为了提高代码的复用性,但如果仅仅是为了提高代码的复用性,组合也可以实现这个目的,并且相对于继承来说,组合更加灵活。只是需要强调,继承关系有很强的逻辑关系,比如动物和人类就是所属关系,但是组合就没有这种逻辑关系,只要一个类想用另一个类中的方法或者成员变量就可通过组合来实现,不需要二者之间存在所属关系,就相当于使用组合可以将人和植物这两个在生物学上完全不同的物种关联起来。也因为如此,继承和组合只能说是各有优缺点,并不存在孰优孰劣的问题。

        那么在java中怎么实现组合呢?其实只要在需要使用组合的类中新建一个属于另一个类的对象就能将另一个类中的属性和方法在这个类中使用了,也就是所谓的组合。比如下面的这个程序所示。

        在这个程序中,可以发现在Student类中先通过Person person = new Person();这个代码实现了将Person类和Student类组合起来,接下来在Student类中要使用Person类中的方法和成员变量只需要通过调用就可以实现。比如在Student的构造方法中的his.person.name = name;这行代码。

package com.zuhe.demo;
//组合:将父类的对象作为子类的属性,子类通过调用这个属性来获得父类的属性和方法
public class ZhHeDemo {
    public static void main(String[] args) {
        Student student = new Student("张三",180,"机械");

        System.out.println(student.person.name);
        System.out.println(student.person.height);
        System.out.println(student.major);
    }
}
 class Person{
    String name;
    int height;
    public void rest(){
        System.out.println("休息一会儿");
    }
}
class Student /*extends Person*/{
    Person person = new Person();
    String major;
    public Student(String name,int height,String major){
        //天然拥有父类的属性
        //this.person.rest();
        this.person.name = name;
        this.person.height = height;
        this.major = major;
    }
}

         

 

 

 

 

 

 

 

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

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

相关文章

深度学习pytorch——卷积神经网络(持续更新)

计算机如何解析图片? 在计算机的眼中,一张灰度图片,就是许多个数字组成的二维矩阵,每个数字就是此点的像素值(图-1)。在存储时,像素值通常位于[0, 255]区间,在深度学习中&#xff0…

C++多线程:线程的创建、join、detach、joinable方法(二)

1、线程的开始与结束 程序运行起来,生成一个进程,该进程所持有的主线程开始自动运行,main主线程运行完所有的代码从main函数中返回表示整个进程运行完毕,标志着主线程和进程的死亡,等待操作系统回收资源,因…

五、基于KubeAdm搭建多节点K8S集群

如需查阅上一步骤,请点击下面链接:四、戴尔R630本地服务器Linux Centos7.9系统安装docker-ce-20.10.10-3.el7版本-CSDN博客文章浏览阅读727次,点赞12次,收藏13次。1、准备工作3、Linux Centos7.9系统的iDRAC远程管理、网络设置、SecureCRT远程登录终端、企业级静态ip地址配…

SpringBoot实现RabbitMQ的定向交换机(SpringAMQP 实现Direct定向交换机)

文章目录 Direct 交换机特点实战声明交换及其队列(以注解方式)发消息 应用 上一篇文章中的 Fanout 模式,一条消息,会被所有订阅其交换机的队列都消费。 但是,在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到 Dir…

Unity-通过AB包使用SpriteAtlas图集(基于unity2018)

项目遇到了一个性能问题,需要优化UI。其中就涉及UI的合批问题,其中自然而然就会关联到图集的概念。旧版图集,Legacy Atlas,还没有太研究。今天主要看一下SpriteAtlas怎么使用的。 因为我们项目资源工程和Runtime是分离的&#xf…

(十二)图像的Sobel梯度锐化

环境:Windows10专业版 IDEA2021.2.3 jdk11.0.1 OpenCV-460.jar 系列文章: (一)PythonGDAL实现BSQ,BIP,BIL格式的相互转换 (二)BSQ,BIL,BIP存储格式的相互转换算法 (三…

RabbitMQ 延时消息实现

1. 实现方式 1. 设置队列过期时间:延迟队列消息过期 死信队列,所有消息过期时间一致 2. 设置消息的过期时间:此种方式下有缺陷,MQ只会判断队列第一条消息是否过期,会导致消息的阻塞需要额外安装 rabbitmq_delayed_me…

327京东一面

1.项目相关 2.手撕SQL 两道 3.JMeter性能测试 首先,进行基准测试: 单用户测试(单用户循环多次得到的数据);为多用户并发执行提供参考 其次,进行负载测试: 通过逐步增加系统负载&#xff0…

2024年水电站大坝安全监测工作提升要点

根据《水电站大坝运行安全监督管理规定》(国家发改委令第23号)和《水电站大坝运行安全信息报送办法》(国能安全〔2016〕261号)的相关规定、要求,电力企业应当在汛期向我中心报送每日大坝汛情。近期,全国各地…

Qt+OpenGL入门教程(三)——绘制三角形

通过前两篇文章的学习,我想大家应该有了基本的理解,我们接下来实操一下。 创建Qt OpenGL窗口 QOpenGLWidget QGLWidget是传统QtOpenGL模块的一部分,与其他QGL类一样,应该在新的应用程序中避免使用。相反,从Qt5.4开始…

蓝桥杯23年第十四届省赛真题-三国游戏|贪心,sort函数排序

题目链接: 1.三国游戏 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-三国游戏 - C语言网 (dotcpp.com) 虽然这道题不难,很容易想到,但是这个视频的思路理得很清楚: [蓝桥杯]真题讲解:三国游戏&#xff0…

备考ICA----Istio实验14---出向流量管控Egress Gateways实验

备考ICA----Istio实验14—出向流量管控Egress Gateways实验 1. 发布测试用 pod kubectl apply -f istio/samples/sleep/sleep.yaml kubectl get pods -l appsleep2. ServiceEntry 创建一个ServiceEntry允许流量访问edition.cnn.com egressgw/edition-ServiceEntry.yaml api…

前端bugs

问题: Failed to load plugin typescript-eslint declared in package.json eslint-config-react-app#overrides[0]: Cannot find module eslint/package.json 解决: google了一晚上还得是chatgpt管用 运行以下命令【同时还要注意项目本身使用的Node版…

亚信安全联合人保财险推出数字安全保障险方案,双重保障企业数字化转型

数字化发展,新兴技术的应用与落地带来网络攻击的进一步演进升级,同时全球产业链供应链融合协同的不断加深,更让网络威胁的影响范围与危害程度不断加剧。 企业单纯依靠自身安全能力建设,能否跟上网络威胁的进化速度?能否…

Day55:WEB攻防-XSS跨站CSP策略HttpOnly属性Filter过滤器标签闭合事件触发

目录 XSS跨站-安全防御-CSP XSS跨站-安全防御-HttpOnly XSS跨站-安全防御-XSSFilter(过滤器的意思) 1、无任何过滤 2、实体化 输入框没有 3、全部实体化 利用标签事件 单引号闭合 4、全部实体化 利用标签事件 双引号闭合 5、事件关键字过滤 利用其他标签调用 双引号闭合…

物联网监控可视化是什么?部署物联网监控可视化大屏有什么作用?

随着物联网技术的深入应用,物联网监控可视化成为了企业数字化转型的关键环节。物联网监控可视化大屏作为物联网监控平台的重要组成部分,能够实时展示物联网设备的运行状态和数据,为企业管理决策和运维监控提供了有力的支持。今天,…

【OpenBayes 官方教程】在模型训练中使用子域名访问服务

本教程主要为大家讲解 OpenBayes 上如何在模型训练中使用子域名访问服务,新朋友点击下方链接注册后,即可获得 4 小时 RTX 4090 5 小时 CPU 的免费使用时长哦! 注册链接 https://openbayes.com/console/signup?ryuudi_nBBThttps://openbay…

matlab及其在数字信号处理中的应用001:软件下载及安装

目录 一,matlab的概述 matlab是什么 matlab适用于的问题 matlab的易扩展性 二,matlab的安装 1,解压所有压缩文件 2,解压镜像压缩文件 3,运行setup.exe 4,开始安装 5,不要运行软件…

慧天【HTWATER】:水文水动力模型的革命性工具,城市内涝的精准解决方案

城市内涝水文水动力模型介绍 在城市排水防涝规划过程中,水文水动力耦合模型已经成为一种不可或缺的分析工具。在模型建立、城市内涝风险评估、排水系统性能诊断以及海绵城市规划等方面,内涝耦合模型提供了相应的模拟及分析工具: 1.1丰富的数…

Windows系统下ESP-IDF环境的搭建

第一步:clone项目,建议是下到"Desktop\esp-idf"的路径 下载地址:https://github.com/espressif/esp-idf 第二步:在VSCode下载ESP-IDF插件 第三步:在Setup页面选择第一个选项EXPRESS 参考文档:h…