Java进阶----继承

news2024/9/20 16:33:47

继承

一.继承概述

继承是可以通过定义新的类,在已有类的基础上扩展属性和功能的一种技术.
案例:优化 猫、狗JavaBean类的设计

狗类:Dog
属性:名字 name,年龄 age
方法:看家 watchHome()Getter and Setter
猫类:Cat
属性:名字 name,年龄 age
方法:抓老鼠 catchMouse(),Getter and Setter

普通写法:

//猫类
public class Cat {
    private String name;
    private int age;

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
//狗类
public class Dog {
    private String name;
    private int age;

    public void watchHome() {
        System.out.println("狗看家");
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
相同的属性,有大量重复代码
private String name;
private int age;
相同的方法,有大量重复代码
public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

继承格式

继承使用 extends 关键字,让派生类扩展基类的功能。派生类也叫子类,基类也叫超类或父类

需求:使用继承优化猫狗类的设计

  • 猫和狗都属于动物的一种,它们的共有属性、功能是每种动物都具备的,可将狗和猫看成是动物的扩展;
  • 定义Animal动物类,并定义猫和狗的共有内容,作为动物的基础属性和功能
属性:姓名 name,年龄 age
方法:Getter and Setter
  • 分别定义Dog狗类和Cat猫类,使用继承技术在Animal动物类的基础功能上扩展自己的特有功能
Dog:看家 watchHome()
Cat:抓老鼠 catchMouse()

分析:
需求:使用继承技术优化Dog和Cat类
1.思考父类是什么?(将Dog和Cat中的相同内容全部放到父类中)子类是什么?子类需要继承父类什么?
2.先定义Animal动物类,作为Dog狗类和Cat猫类的父类
3.使用extends关键字让Dog和Cat继承Animal

// Animal动物类
public class Animal {
    //父类的私有内容不能直接继承(直接使用)
    private String name;
    private int age;
    
    //使用方法调用
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
//猫类 继承动物类
public class Cat extends Animal{
    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}

//狗类 继承动物类
public class Dog extends Animal{
    public void watchHome() {
        System.out.println("狗看家");
    }
}
//测试Dog和Cat的功能是否能够正常使用
public class Demo {
    public static void main(String[] args) {
        //需求:使用继承技术优化Dog和Cat类
        Dog dog = new Dog();
        dog.watchHome();
        dog.setAge(3);
        int age = dog.getAge();
        dog.setName("小黄");
        Cat cat = new Cat();
        String name = dog.getName();
        System.out.println(name);
        System.out.println(age);
        
    }
}

小结

继承技术的作用是什么?
可以使用___extends___关键字,让子类扩展父类的属性和功能
如何使用继承技术?
在__父类_____中定义子类们的共有内容,作为基础属性和功能
让___子类_____使用 extends__ 关键字,扩展父类的属性和功能
继承技术有什么好处?
可以提高代码__复用率________,减少重复的代码

拓展

什么时候使用继承呢?

  • 子类和父类具备 is a 的关系
  • is a 的关系:

假设A和B两个类,A是B的一种,那么A类和B类就有 is a 的关系
此时:A类 extends B类,苹果类 extends 水果,猫类 extends 动物.

继承案例练习

需求:在某个宠物店的宠物资源管理系统中,存在猫、狗角色。

猫类属性(姓名,年龄),行为(喝水,抓老鼠)
狗类属性(姓名,年龄),行为(喝水,看家)

利用继承技术,定义猫类和狗类,并实现效果:

3岁的小猫杰克,每天都抓一只老鼠当晚餐
2岁的小狗大黄,每天都趴在门口看家护院

1.先定义Animal动物类,作为父类
2.分别定义Dog狗类和Cat猫类,作为子类
3.创建子类对象,调用功能

/**
 *动物类:作为父类
 */
public class Animal {
    //提取子类们共有的属性和功能:共有的属性:姓名、年龄
    private String name;
    private int age;
//针对被私有的属性,需要提供Getter and Setter方法
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //共有行为方法
    public void drink(){
        System.out.println("喝水");
    }
}
/**
 * 狗类:使用extends关键字,继承Animal动物类
 */
public class Dog extends Animal {

    //特有功能:看家
    public void watchHome() {
        System.out.println(getAge() + "岁的小狗" + getName() + ",每天都趴在门口看家护院");
    }
}
public class Cat extends Animal {
    //特有功能:抓老鼠
    public void catchMouse() {
        System.out.println(getAge() + "岁的小猫" + getName() + ",每天都抓一只老鼠当晚餐");
    }
}
public class Test {
    public static void main(String[] args) {
        //1.先定义Animal动物类,作为父类

        //2.分别定义Dog狗类和Cat猫类,作为子类

        //3.创建子类对象,调用功能
        Dog dog = new Dog();
        dog.setName("大黄");
        dog.setAge(2);

        Cat cat = new Cat();
        cat.setName("杰克");
        cat.setAge(2);

        dog.watchHome();
        cat.catchMouse();
    }
}

继承的注意事项

  1. 单继承: 一个子类只能有一个父类
  2. 多层继承:子类可以有父类,父类也可以有父类
  3. 继承成员子类能从父类那直接或间接获取属性和功能
  4. 祖宗类:任何一个类都直接或间接的继承Object类

分析
1.Java只能单继承(一个子类有且仅有一个父类)
需求:尝试让Son类同时继承Dad类和GrandDad类

public class GrandDad {
    public void drawing() {
        System.out.println("绘画");
    }
}
//尝试Son多继承(同时继承)Dad和GrandDaD类,代码会报错!
//public class Son extends Dad, GrandDad {
//public class Son extends Dad extends GrandDad {

2.Java虽然只能单继承,但是可以多层继承(子类继承父类,但父类也可以继续继承父类)

  • 需求:尝试让Son类继承Dad类,然后让Dad类继承GrandDad类
  • 创建子类Son的对象,去调用Dad类和GrandDad类的功能
//尝试让Son继承Dad
public class Son extends Dad{
}
//让Dad类继承GrandDad
public class Dad extends GrandDad {
    String car = "玛莎拉蒂";
    private String house = "小洋楼";

    public void swim() {
        System.out.println("游泳");
    }
}

Son son = new Son();
System.out.println(son.car);
son.swim();
son.drawing();
System.out.println("----------------------");

3.子类可以直接或间接继承父类的成员(直接或间接的使用父类的成员变量、成员方法),父类的私有成员,子类不能直接继承,但是可以间接继承(使用super关键字)

//System.out.println(son.house);
//'house' has private access in 'i_extends.d3.Dad'

4.Java中任何一个类都直接或间接的继承Object类
,Object类提供了一个hashCode方法,可以返回对象在堆内存的十进制地址值

//需求:创建GrandDad类对象,尝试调用hashCode方法
        GrandDad grandDad = new GrandDad();
        int hashCode = grandDad.hashCode();
        System.out.println(hashCode);
玛莎拉蒂
游泳
绘画
----------------------
356573597

三.继承关系下,成员的访问特点

目标:了解继承关系中,子类访问成员的特点
就近原则
1.成员(变量、方法)访问的特点:

  • 子类有,就访问子类自己的
  • 子类没有,就访问父类的
  • 子、父类都没有,代码报错!
    2.指定访问父类的成员:
  • 使用 super 访问
public class Fu {
    String str = "我是父类变量";

    public void show() {
        System.out.println("我是父类的show方法");
    }
}

public class Zi extends Fu {
    String str = "我是子类变量";

    public void show() {
        System.out.println("我是子类的show方法");
    }

    public void test() {
        //1.访问变量str
        System.out.println(str);

        //2.访问show方法
        show();

        **//3.指定访问父类的str属性和show方法**
        System.out.println(super.str);
        super.show();
    }
public class Demo {
    public static void main(String[] args) {
        //1.需求:按要求完成Zi类中的test方法
        //创建Zi类对象,调用test()方法
        Zi zi = new Zi();
        zi.test();
      }
}
//父类
public class Father {
    String field = "父类的和子类同名属性";

    public void method() {
        System.out.println("父类的和子类同名方法");
    }
}

//子类
public class Son extends Father {
    String field = "子类的和父类同名属性";
    String ziField = "子类特有属性";

    public void method() {
        System.out.println("子类的和父类同名方法...");
    }

    public void use() {
        String ziField = "子类局部变量";

        //练习:按要求完成以下需求
        //1.访问子类的field属性
        System.out.println(field);

        //2.访问父类的field属性
        System.out.println(super.field);

        //3.访问ziField属性,此时发现方法中有一个成员变量和一个成员方法同名,此时需要用 this 来表明访问的是成员变量
        System.out.println(this.ziField);

        //4.访问ziField局部变量
        System.out.println(ziField);

        //5.访问method方法
        method();

        //6.访问父类的method方法
        super.method();

    }
}

小结

  1. 在子类方法中访问父类成员变量、成员方法遵循什么原则?
    就近原则:子类有就用子类的,子类没有就用父类的,父类没有就报错
  2. 如果子、父类中出现了重名的成员变量、成员方法,如何区分?
    super.父类成员 … this.本类成员

四.方法重写

  • 子类和父类有一模一样方法声明,但方法体可能不一样,此时子类方法会覆盖父类的方法(这种格式称为方法重写)

目标:掌握方法重写的特点和使用场景

### 实例
需求:在不影响B类继承使用Fu类show功能的前提下,让A类执行自己特有的show功能:"A类特有的show方法"
1.在子类A中,写一个和父类Fu一模一样的show方法(子类A重写了父类Fu的show方法)

```java
public class Fu {
    public void show() {
        System.out.println("fu...show...");
    }
}
public class B extends Fu {

}
public class A extends Fu {
    public void show() {
        System.out.println("A类特有的show方法");
    }
}
public class Demo01 {
    public static void main(String[] args) {
        A a = new A();
        //方法重写后,遵循就近原则
        a.show();
        B b = new B();
        b.show();
    }
}

//执行结果:
//A类特有的show方法
//fu...show...

``

方法重写的注意事项

目标:了解方法重写的注意事项

  1. 重写方法的名称、形参列表必须和父类相同
  2. 子类重写的方法返回值类型,要小于等于父类方法的返回值类型(约定:父类大于子类)
  3. 子类重写父类方法时,访问权限必须大于或者等于父类 (private < 缺省 < protected < public)
  4. 父类私有方法,子类不能重写

方法重写的校验

@Override注解,标记一个方法是重写父类方法(语法检查)
需求:让SubClass类重写SuperClass类的各个方法

public class SuperClass {
    public void method1() {
        System.out.println("super...public...");
    }

    public A method2() {
        return new A();
    }

    protected void method3() {
        System.out.println("super...protected...");
    }

    void method4() {
        System.out.println("super...default...");
    }

    private void method5() {
        System.out.println("super...private...");
    }
}
public class SubClass extends SuperClass {
    //1.重写method1方法:保持方法名称、形参列表相同
    @Override
    public void method1() {
    //public void method1(int age) {
        System.out.println("子类重写的method1");
    }

    //2.重写method2方法
    @Override
    //public Fu method2() {
    //注意:子类重写父类方法,返回值类型需要小于等于父类的
    public A method2() {
        return new A();
    }

    //3.重写method3、method4、method5方法
    @Override
    protected void method3() {
        //注意:子类重写父类方法,访问权限要大于等于父类的
        //public void method3() {
        //void method3() {
        //private void method3() {
        System.out.println("子类重写的method3");
    }

    @Override
    void method4() {
        //protected void method4() {
        //public void method4() {
        //private void method4() {
        System.out.println("子类重写的method4");
    }

    //@Override
    //注意:父类私有方法,子类不能重写
    private void method5() {
        System.out.println("子类自己的method5方法");
    }

继承关系下,构造器的访问特点

目标:了解继承关系中,构造器的访问特点
特点:访问构造器时,会先默认访问父类的空参构造器
原因:在子类的构造器第一行有一句隐藏的super();
在这里插入图片描述

  • super访问父类构造器
    super(); 用来访问父类空参数构造器
    super(参数); 访问父类有参数构造器
    在这里插入图片描述
    子类继承父类后构造器的访问特点是什么样的?
    子类中所有的构造方法默认都会先访问父类中__空参数构造方法

子类构方法第一行默认有一句__super()________
如果不想访问父类空参数构造器,可以使用___super(参数)_________ 访问父类有参数构造器
访问本类的构造器格式是:this()、this(参数)_____________
补充: this(),super() 都只能写在构造器的第 条语句

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

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

相关文章

机器学习统计学基础 - 最大似然估计

最大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是一种常用的参数估计方法&#xff0c;其基本原理是通过最大化观测数据出现的概率来寻找最优的参数估计值。具体来说&#xff0c;最大似然估计的核心思想是利用已知的样本结果&#xff0c;反推最有可能…

自定义类TMyLabel继承自QLabel ,实现mouseDoubleClickEvent

自定义类TMyLabel &#xff0c;继承自QLabel TMyLabel 中重新实现了 event 方法&#xff0c;重写了mouseDoubleClickEvent 发射信号 在主窗体中放入TMyLabel组件&#xff0c;将TMyLabel mouseDoubleClickEvent 信号&#xff0c; 绑定到实现方法do_doubleClick()槽函数 TMy…

知识付费系统3.0整站源码知识付费网课平台网创资源付费带自动采集同步插件

程序说明&#xff1a; 1.修复更新到最新版本 2.自动采集插件重写 3.关闭采集授权域名直接对接 4.更新插件主动请求同步资源 5.带自动采集插件 原始功能 支持分类替换 将主站同步过来的文章分类进行替换 支持自定义文章作者&#xff08;选择多个作者则同步到的文章作者将会随机分…

已解决 javax.xml.transform.TransformerFactoryConfigurationError 异常的正确解决方法,亲测有效!!!

已解决 javax.xml.transform.TransformerFactoryConfigurationError 异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 一、问题分析 二、报错原因 三、解决思路 四、解决方法 五、总结 博主v&#xff1a;XiaoMing_Java 博主v&#x…

Desktop docker 部署 WordPress

Desktop Docker 部署 WordPress 之前都是在Linux里面玩的&#xff0c;今天看到别人在windwos下安装docker&#xff0c;一时兴起装了一个试试&#xff0c;效果一般&#xff0c;很吃硬盘空间和内存。 首先在docker官方下载桌面版&#xff0c;安装下一步一直到完成。 安装完docke…

C++初阶:从C过渡到C++的入门基础

✨✨所属专栏&#xff1a;C✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ C发展历史 C的起源可以追溯到1979年&#xff0c;当时BjarneStroustrup(本贾尼斯特劳斯特卢普&#xff0c;这个翻译的名字不同的地⽅可能有差异)在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复…

ubantu安装k8s集群服务

进行主机优化配置 参考&#xff1a; 修改主机名称 hostnamectl set-hostname k8s-node03 关闭swap分区 swapoff -a #临时关闭 sed -i /\/swap/s/^/# /etc/fstab #永久关闭 增加主机解析 cat >> /etc/hosts << EOF 10.1.60.119 k8s-master01 10.1.60.12…

ArcGIS:探索地理信息系统的强大功能与实际应用

ArcGIS是一款功能强大的地理信息系统&#xff08;GIS&#xff09;软件&#xff0c;由Esri公司开发。它广泛应用于各个领域&#xff0c;包括城市规划、环境保护、资源管理、交通运输等。作为一名长期使用ArcGIS的用户&#xff0c;我深感这款软件在数据分析、地图制作和空间信息管…

ROS编译错误: fatal error: test_pkg/test_pkg.h: 没有那个文件

在ROS安装完毕后编译ros工作空间&#xff0c;出现了以下错误: 解决方法: 删除工作空间&#xff0c;重建再重新编译

Android EditText+ListPopupWindow实现可编辑的下拉列表

Android EditTextListPopupWindow实现可编辑的下拉列表 &#x1f4d6;1. 可编辑的下拉列表✅步骤一&#xff1a;准备视图✅步骤二&#xff1a;封装显示方法✅步骤三&#xff1a;获取视图并监听 &#x1f4d6;2. 扩展上下箭头✅步骤一&#xff1a;准备上下箭头icon图标✅步骤二&…

基于stm32开发的红外循迹小车

本项目算是接触32来开发的第一个小项目了&#xff0c;虽然前期用51写过一个循迹小车&#xff0c;以为直接转到32会比较简单&#xff0c;结果还是花了大几天才把小车的参数完全调完&#xff0c;以此来记录下自己的学习历程&#xff08;注&#xff1a;循迹算法并未加入PID算法&am…

PDA:Prompt-based Distribution Alignment for Unsupervised Domain Adaptation

文章汇总 式中&#xff0c; y s y^s ys表示源域数据的one-hot ground-truth&#xff0c; K K K为类数&#xff0c; w i w_i wi​和 z ~ s \tilde{z}_s z~s​分别表示源域经过提示调优的最终文本表示和最终图像表示的第 i i i类。 同理&#xff0c;为了进一步利用目标领域的数据…

多用户挂售转卖竞拍闪拍商城系统/NFT数藏系统/后端PHP+前端UNIAPP源码带教程(亲测源码)

挂售转卖竞拍商城系统源码/竞拍系统/转拍闪拍系统/后端PHP前端UNiapp源码 亲测可用 1、后台管理&#xff1a;系统管理员通过后台可以轻松添加商品进行挂单。这包括商品的详细信息&#xff0c;如名称、描述、价格、库存等。 商品展示&#xff1a;挂单后的商品会在商城前端进行…

Mysql笔记-v2【7月8日更新】

零、 help、\h、? 调出帮助 mysql> \hFor information about MySQL products and services, visit:http://www.mysql.com/ For developer information, including the MySQL Reference Manual, visit:http://dev.mysql.com/ To buy MySQL Enterprise support, training, …

概论(二)随机变量

1.名词解释 1.1 样本空间 一次具体实验中所有可能出现的结果&#xff0c;构成一个样本空间。 1.2 随机变量 把结果抽象成数值&#xff0c;结果和数值的对应关系就形成了随机变量X。例如把抛一次硬币的结果&#xff0c;正面记为1&#xff0c;反面记为0。有变量相对应的就有自…

MySQL高级----InnoDB引擎

逻辑存储结构 表空间 表空间(ibd文件)&#xff0c;一个mysql实例可以对应多个表空间&#xff0c;用于存储记录、索引等数据。 段 段&#xff0c;分为数据段&#xff08;Leaf node segment)、索引段(Non-leaf node segment)、回滚段(Rollback segment)&#xff0c;InnoDB是…

DETR目标检测框架

概念&#xff1a;DETR&#xff08;Detection Transformer&#xff09;是一种基于Transformer架构的端到端目标检测框架。它与传统的基于区域提议的目标检测方法有所不同。传统方法通常依赖于手工设计的组件&#xff08;如锚框、非极大值抑制等&#xff09;&#xff0c;而DETR将…

设计模式7-装饰模式

设计模式7-装饰模式 写在前面动机模式定义结构代码推导原始代码解决问题分析 选择装饰模式的理由1. 职责分离&#xff08;Single Responsibility Principle&#xff09;2. 动态扩展功能3. 避免类爆炸4. 开闭原则&#xff08;Open/Closed Principle&#xff09;5. 更好的组合复用…

【数据结构】11.快速排序

一、快速排序的思想 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右…

深度解密Spark性能优化之道课程

课程通过实战案例解析和性能调优技巧的讲解&#xff0c;帮助学员提升大数据处理系统的性能和效率。课程内容涵盖了Spark性能调优的各个方面&#xff0c;包括内存管理、并行度设置、数据倾斜处理、Shuffle调优、资源配置等关键技术和策略。学员将通过实际案例的演示和分析&#…