面向对象进阶(上)(JAVA笔记第二十二期)

p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解

目录

  • static修饰符
    • 静态变量
    • 静态方法
  • 工具类
    • 工具类的使用例子
      • 第一题
      • 第二题
  • static注意事项
  • 继承关系
    • 建立继承关系的格式
    • 继承的好处及使用场景
    • 继承的特点
    • 继承体系的设计
    • 继承中类的三大要素的访问特点
      • 继承中成员变量的访问特点
      • 继承中成员方法的访问特点
      • 方法的重写
      • 继承中成员方法的访问特点
      • this和super
    • 带有继承结构的标准Javabean类例题

static修饰符

static,翻译过来的意思为静态。static可以用来修饰成员变量,成员方法

被static修饰的成员变量叫做静态变量
被static修饰的成员方法叫做静态方法

静态变量

特点:被这个类所有的对象共享。其不属于某个对象,是属于类的
静态变量是随着类的加载而加载的,是优先于对象出现的

调用方式:

  • 类名调用(推荐)
  • 对象名调用

静态方法

特点:多用在测试类和工具类当中。javabean类中很少会使用

调用方式:

  • 类名调用(推荐)
  • 对象名调用

工具类

定义工具类的规则

  • 类名见名知意
  • 私有化构造方法,为了不让外界创建它的对象
  • 方法定义为静态,方便调用

工具类的使用例子

第一题

编写一个工具类ArrayUtil
提供一个工具类方法printArr,用于返回整数数组的内容,返回的字符串格式: [12,15,13,100] (只考虑一维整数数组)
提供这样一个工具方法getAverage,用于返回平均数(只考虑一维浮点型数组)
定义一个测试类Test,调用该工具类的工具方法,并返回结果

工具类

public class ArrayUtil {

    private ArrayUtil(){}


    public static String printArr(int[]arr){
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if (i== arr.length-1) {
                sb.append(arr[i]);
            }
            else {
                sb.append(arr[i]).append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }


    public static double getAverage(double[]arr){
        double sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum = sum + arr[i];
        }
        return  sum/arr.length;
    }
}

测试类

public class Test {
    public static void main(String[] args) {

        int[]arr = new int[]{1,2,3,4,5};
        double[]arr2 = new double[]{1,2,3,4,5};


        String string = ArrayUtil.printArr(arr);
        System.out.println(string);

        double average = ArrayUtil.getAverage(arr2);
        System.out.println(average);
    }
}

第二题

需求:定义一个集合,用于存储3个学生对象
学生类的属性为:name、age、gender
定义一个工具类,用于获取集合中最大学生的年龄

javabean类

public class Student {
    private String name;
    private int age;
    private char gender;

    public Student() {}

    public Student(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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 char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }
}

工具类

import java.util.ArrayList;

public class StudentUtil {
    private StudentUtil() {}

    public static int getMaxAge(ArrayList<Student> list){

        int maxAge = list.get(0).getAge();
        for (int i = 1; i < list.size(); i++) {
            if (maxAge<=list.get(i).getAge()){
                maxAge = list.get(i).getAge();
            }
        }
        return maxAge;
    }


}

测试类

import java.util.ArrayList;

public class StudentTest {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();

        Student student1 = new Student("张三",18,'男');
        Student student2 = new Student("李四",22,'女');
        Student student3 = new Student("王五",20,'男');

        list.add(student1);
        list.add(student2);
        list.add(student3);

        System.out.println(StudentUtil.getMaxAge(list));

    }
}

static注意事项

静态方法只能访问静态变量和静态方法
非静态的方法可以访问静态变量和静态方法,也可以访问非静态的成员变量和非静态的成员方法
静态方法中没有this关键字

简略来说:
静态方法中只能访问静态
非静态可以访问所有
静态方法中没有this关键字

详细解析看这里

继承关系

继承关系是类与类之间的关系。
比如学生老师会有的所有属性以及行为,也会有所不具有的、特有的属性(比如就读学校、就业学校)和行为(比如在学校学习、在学校教书)。
既然如此,当我们在写类(学生)类(老师) 的时候,可以将他们共有的属性(比如姓名)和行为(比如吃饭)提取出来写在一个新的类 类(人) 里面,而他们所特有的属性和行为就继续放在他们的类里面。这便是继承。
其中类(学生)类(老师) 称为子类类(人) 称为父类

继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
继承就是子类继承父类的特征和行为,使得子类对象具有父类的方法,或子类从父类继承方法,使得子类具有父类相同的行为。

子类可以得到父类的属性和行为,子类可以继续使用
子类可以在父类的基础上新增其他功能,使得子类更加强大

建立继承关系的格式

使用extends关键字,我们可以让一个类和另一个类建立起继承关系

格式

public class 子类 extends 父类{}

子类也叫派生类;父类也叫基类或超类

继承的好处及使用场景

继承可以把多个子类中的重复代码抽取到父类中,提高了代码的复用性
子类可以在父类的基础上再增加其他的功能,使子类更强大

当类与类之间,存在相同(共性)的内容,并满足子类是父类的一种时,就可以考虑使用继承来优化代码

继承的特点

JAVA只支持单继承、不支持多继承,但支持多层继承
单继承:一个子类只能继承一个直接父类
不支持多继承:子类不能同时继承多个父类
多层继承:子类A继承父类B,父类B可以继承父类C。父类B是子类A的直接父类,父类C是子类A的间接父类
每一个类都直接或间接的继承于Object
.
子类只能使用父类中非私有的成员,可以继承父类的成员变量(不论是否非私有)和非私有的成员方法,但是不能使用继承下来的父类中私有的成员变量。不能继承构造方法。如果父类的成员方法在虚方法表中就可以被继承,否则就不行

在这里插入图片描述
以内存图的形式解释原因

继承体系的设计

技巧:画图法
从下往上画,下面为子类,上面为父类
把子类的共性内容抽取到父类中
核心:共性内容抽取;子类是父类的一类

设计继承体系是要从父类开始写
下面为设计继承体系的例子

类(学生)

//设计继承体系
//给定4个学生:A、B、C、D
//暂时不考虑属性,只考虑行为
//按照继承的思想特点进行继承体系的设计


//A:学习、吃饭、玩游戏、emo
//B:学习、吃饭、玩游戏、emo
//C:学习、吃饭、追剧
//D:学习、吃饭、运动


public class Student {

    public  void eat(){
        System.out.println("吃饭!!");
    }
    public  void study(){
        System.out.println("学习");
    }
}

类(玩游戏和emo的学生)

public class PLAYandEMO__Students extends Student {
    private void play(){
        System.out.println("玩游戏!!");
    }
    private void emo(){
        System.out.println("emo");
    }
}

类(学生C)

public class StudentC {
    public void watchTY(){
        System.out.println("追剧中······");
    }
}

类(学生D)

public class StudentD {
    public void exercise(){
        System.out.println("运动中...");
    }
}

继承中类的三大要素的访问特点

继承中成员变量的访问特点

特点:就近原则:谁离我近,我就用谁
如果没有修饰符的话,先在局部位置找,再在本类成员位置找,再在父类成员位置找,逐级往上

举例

 class Fu{
    String name = "Fu";
}
 class Zi extends Fu{
    String name = "Zi";
    public void ziShow(){
        String name = "ziShow";
        System.out.println(name);
    }
}

输出

ziShow

当出现了重名的成员变量怎么办?
举例

class Fu {
    String name = "张三";
    String hobby = "内卷";
}

class Zi extends Fu{
    String name = "李四";
    String game = "卡拉彼丘";
    public void show(){

        //如何打印李四
        System.out.println(name);
        System.out.println(this.name);

        //如何打印张三
        System.out.println(super.name);

        //如何打印内卷
        System.out.println(hobby);//先在局部变量位置找,再在成员变量位置找,最后到父类成员变量位置中找
        System.out.println(this.hobby);//先在成员变量位置找,再到父类成员变量位置中找
        System.out.println(super.hobby);//到父类成员变量位置中找


        //如何打印卡拉彼丘
        System.out.println(game);
        System.out.println(this.game);

    }
}

继承中成员方法的访问特点

直接调用时满足就近原则:谁离我近,我就用谁
即先在本类中查找有无该方法,若有就调用本类的该方法,若没有就调用父类中继承下来的该方法
若用super调用就直接到父类中找

举例

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.eatLunch();
    }
}


class Fu {
   public void eat(){
       System.out.println("吃烧烤");
   }
   public void drink(){
       System.out.println("喝雪碧");
   }
}

class Zi extends Fu{

    public void eatLunch(){
        eat();//这里隐藏了一个this,所以其实这句话应该为 this.eat()
        drink();//同理

        super.eat();
        super.drink();

    }
    public void eat(){
        System.out.println("吃火锅");
    }
    public void drink(){
        System.out.println("喝加多宝");
    }
}

输出结果

吃火锅
喝加多宝
吃烧烤
喝雪碧

可以发现**类(zi)里面的eat()和drink()方法其实类(Fu)**里面的eat()和drink()方法重写了一遍得到的,而这我们便叫作方法的重写

方法的重写

当父类的方法不能满足子类现在的需求时,需要进行方法重写
.
书写格式:在继承体系中,子类出现了和父类一模一样的方法声明,我们就称子类这个方法是重写的方法
.
@override重写注解
@override是写在重写后的方法上面,校验子类重写时语法是否正确(虚拟机来校验)
若加上注解后出现红色波浪线,则表示语法错误
建议重写方法都加上@override重写注解,可以提高代码的安全性、可读性
.
方法重写的本质是将父类继承下来的虚方法表中的对应方法进行重写覆盖
虚方法表:类中没有被private、static、final修饰的方法的集合
.
注意事项:

  1. 重写方法的名称、形参列表必须与父类中的一致
  2. 子类重写父类方法时,访问权限子类必须大于父类(空着不写<protected<public)
  3. 子类重写父类时,返回值类型子类必须小于等于父类
  4. 重写方法时子类和父类尽量保持一致
  5. 只有被添加到虚方法表里的方法才能被重写

下面为方法重写在设计继承体系时的作用

 class TeacherTest {
     public static void main(String[] args) {
         TeacherA teacherA = new TeacherA();
         TeacherB teacherB = new TeacherB();
         TeacherC teacherC = new TeacherC();

         teacherA.eat();
         teacherA.teach();
         teacherA.game();


         teacherB.eat();
         teacherB.teach();


         teacherC.eat();
         teacherC.teach();


     }
}



//=========================================
class Teacher {
    //现在有三位老师,只考虑行为
    //设计一个继承体系
    //老师A:教书(语文) 、吃饭 、打游戏
    //老师B:教书(数学) 、吃饭
    //老师C:教书(英语) 、吃饭
    public void eat(){
        System.out.println("吃饭中");
    }
    public void teach(){
        System.out.println("老师在教书");
    }
}
//=========================================
class TeacherA extends Teacher{

    @Override
    public void teach(){
        System.out.println("老师在教语文");
    }
    public void game(){
        System.out.println("老师在打游戏");
    }

}
//=========================================
class TeacherB extends Teacher{

    @Override
    public void teach(){
        System.out.println("老师在教数学");
    }
}
//=========================================
class TeacherC extends Teacher{

    @Override
    public void teach(){
        System.out.println("老师在教英语");
    }
}

继承中成员方法的访问特点

父类中的构造方法不会被子类继承,但能通过super调用
.
子类中所有的构造方法默认先访问父类中的无参构造,再执行自己
原因:子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
因此子类在初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
.
怎么调用的父类构造方法?
子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行
super() →调用父类的无参构造
如果想调用父类的有参构造,就必须手动写super进行调用

下面为调用父类的无参构造

public class Test1 {
    public static void main(String[] args) {
        Student1 student1 = new Student1();
         
    }
}
//======================================
class Person{
    String name;
    String id;

    public Person() {
        System.out.println("父类的无参构造被调用");
    }

    public Person(String name, String id) {
        this.name = name;
        this.id = id;
    }
}
//======================================
class Student1 extends Person{

    public Student1() {
        //子类构造方法中隐藏的super()方法是用来访问父类的无参构造的
        super();
        System.out.println("子类的无参构造被调用");
    }
}

输出

父类的无参构造被调用
子类的无参构造被调用

下面为调用父类的有参构造

public class Test1 {
    public static void main(String[] args) {
        Student1 student1 = new Student1("张三","001");
        System.out.println(student1.name+", "+student1.id);
    }
}
//======================================
class Person{
    String name;
    String id;

    public Person() {
        System.out.println("父类的无参构造被调用");
    }

    public Person(String name, String id) {
        this.name = name;
        this.id = id;
    }
}
//======================================
class Student1 extends Person{

    public Student1() {
        //子类构造方法中隐藏的super()方法是用来访问父类的无参构造的
        super();//这一步可以手动书写,程序会自动帮我们写
        System.out.println("子类的无参构造被调用");
    }

    public Student1(String name,String id) {
        super(name,id);//需要手动调用父类的有参构造
    }
}

输出

张三, 001

this和super

this可以理解为一个变量,表示当前方法调用者的地址值; super代表父类的存储空间
在这里插入图片描述
this访问本类构造方法举例

public class Students {
    String name;
    String id;
    String school;
    
    //要求:默认为为AA大学

    public Students() {
        this(null,null,"AA大学");
        //表示调用本类其他构造方法
        //这时虚拟机就不会再添加super()。因为其他构造方法开头有隐藏的super()
    }

    public Students(String name, String id, String school) {
        this.name = name;
        this.id = id;
        this.school = school;
    }
}

带有继承结构的标准Javabean类例题

需求:写出带有继承结构的标准Javabean类
1.经理
成员变量:工号、姓名、工资、成就
成员变量:工作(管理别人)、吃饭
2、厨师
成员变量:工号、姓名、工资
成员方法:工作(炒菜)、吃饭

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

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

相关文章

redis集群介绍

Redis集群是一种分布式存储系统&#xff0c;它通过将数据分散存储在多个Redis节点上来实现可扩展性和高可用性。每个节点都是一个独立的Redis服务器实例&#xff0c;它们通过网络相互连接&#xff0c;共同协作以提供数据服务。 在Redis集群中&#xff0c;数据被划分为多个槽&am…

巧用这4款免费视频剪辑软件,帮你释放无限的创意。

可以免费使用的视频剪辑软件对于普通创作者而言还是比较重要的。因为越来越多的人渴望通过视频来表达自己的创意、分享生活点滴以及传达各种信息。专业的软件价格贵&#xff0c;操作复杂。简单免费的工具才是大多数人的选择&#xff0c;所以我要给大家介绍几个好用且免费的剪辑…

3D Slicer 教程三 ---- 坐标系

上篇提到3D Slicer 教程二 ---- 数据集-CSDN博客 3d slicer的坐标系与大多数医学影像软件使用LPS&#xff08;左、后、上&#xff09;坐标系统不太一样, 今天就仔细介绍一下坐标系的区别,复盘一下在影像处理中遇到的坐标问题(集中在坐标处理相关的,图像插值,图像处理, 定位线,翻…

服务器软件之Tomcat

服务器软件之Tomcat 服务器软件之Tomcat 服务器软件之Tomcat一、什么是Tomcat二、安装Tomcat1、前提&#xff1a;2、下载3、解压下载的tomcat4、tomcat启动常见错误4.1、tomcat8.0 startup报错java.util.logging.ErrorManager: 44.2、java.lang.UnsatisfiedLinkError 三、Tomca…

Ansible概述

目录 一、ansible简介 二、absible的特点 三、ansible的工作原理以及流程 四、ansible环境安装部署 五、ansible命令行模块 六、inventory 主机清单 一、ansible简介 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。…

应用层——电子邮件、MIME、简单网络管理协议SNMP

电子邮件 电子邮件系统采用三个主要构件组成&#xff1a;用户代理、邮件服务器、电子邮件所需的协议 我们可以简单的认为邮件服务器中有很多邮箱&#xff0c;还有用来缓存再转发邮件的缓存&#xff0c;发送方使用用户代理通过邮件发送协议。例如SMTP将邮件发送给发送方。 邮件服…

基于MATLAB的混沌序列图像加密程序

设计目的 图像信息生动形象&#xff0c;它已成为人类表达信息的重要手段之一&#xff0c;网络上的图像数据很多是要求发送方和接受都要进行加密通信&#xff0c;信息的安全与保密显得尤为重要&#xff0c;因此我想运用异或运算将数据进行隐藏&#xff0c;连续使用同一数据对图…

排序04 视频播放建模

视频播放时长 用p拟合y&#xff0c;t是用户的实际观看时长&#xff0c;用y和p熵作为损失函数&#xff0c;使得p接近y。 输出z,对z做sigmoid变换。 exp(z)可以视为对播放时长的预估 视频完播 回归方法 二元分类方法 调整&#xff1a;预估完播率不能直接使用

预置持久化应用或者常驻应用会导致自升级不了android:persistent=”true”属性

1.错误打印&#xff1a; 2.问题原因&#xff1a; Android系统策略限制&#xff0c;持久化&system 不能自升级 3.持久化应用通常会在AndroidManifest.xml上下文有没配置android:persistent”true”属性 4.解决方案&#xff1a; 1.应用去掉android:persistent”true”属性…

【基于docker的深度学习训练环境】关键步骤记录

最近给公司搭建了一个小型的深度学习环境&#xff0c;实现了多人通过SSH对GPU资源的利用&#xff0c;下面对一些关键架构和易用性部分进行记录。 一、整体软硬件框架 1、硬件配置&#xff0c;采用的双GPU的方案&#xff0c;两块消费级显卡。 2、应用层架构 宿主机系统为ubunt…

【Redis】缓存预热、雪崩、击穿、穿透、过期删除策略、内存淘汰策略

Redis常见问题总结&#xff1a; Redis常见问题总结Redis缓存预热Redis缓存雪崩Redis缓存击穿Redis缓存穿透 Redis 中 key 的过期删除策略数据删除策略 Redis内存淘汰策略一、Redis对过期数据的处理&#xff08;一&#xff09;相关配置&#xff08;二&#xff09;内存淘汰流程&a…

WSL2-轻量级AI训练场景最佳生产环境

WSL2 只适用于 Win 10 、Win11 在运行 AI 软件、AI 模型训练&#xff0c;Linux 是最佳的操作系统。 在运行各种软件&#xff0c;如&#xff1a;Stable Diffusion Web UI 等&#xff0c;使用 Docker 容器运行也更方便后期的快速复用&#xff0c;同样的 Docker 容器在 Linux 中…

【STM32学习】PWM学习(四),散热风扇的控制,PWM调速调制,

目录 1、基础概念 2、PWM调速风扇功能介绍 2.1风扇功率 2.2、PWM输出流程图 2.3、PWM占空比计算 2.4参数计算 3、配置实现 3.1、添加TIM1功能 3.2、生成代码 3.3、修改代码 1、基础概念 参考&#xff1a;【STM32学习】PWM脉冲宽度调制学习笔记&#xff0c;&#xff…

关于k8s集群高可用性的探究

1. k8s的高可用的核心是什么&#xff1f; 说到核心、本质 意味着要从物理层来考虑技术 k8s是一个容器编排管理工具&#xff0c;k8s受欢迎的时机 是docker容器受欢迎时&#xff0c;因为太多的docker容器&#xff0c;管理起来是一个大工程 那么刚好k8s是google自己用了十来年…

《向量数据库指南》揭秘:GraphRAG如何重塑知识图谱与RAG的融合之道

嘿,各位向量数据库和AI领域的探索者们,我是你们的老朋友,大禹智库的向量数据库高级研究员王帅旭,也是《向量数据库指南》的作者。今天,咱们来聊聊一个既前沿又实用的话题——GraphRAG,一个通过结合知识图谱来增强检索增强生成(RAG)能力的新方法。如果你对向量数据库和A…

web网页QQ登录

代码&#xff1a; <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>QQ登录ent</title> </head> <style>ul > li{list-style: none; } a …

Axure重要元件三——中继器函数

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;中继器函数 主要内容&#xff1a;Item、Reperter、TargetItem 1、中继器的函数&#xff1a;Item\Reperter\TargetItem Item item&#xff1a;获取…

【重学 MySQL】七十四、揭秘存储过程的强大功能与实战技巧

【重学 MySQL】七十四、揭秘存储过程的强大功能与实战技巧 存储过程简介存储过程的分类存储过程的创建基本语法语法元素分析注意点示例 存储过程的调用基本语法语法元素分析调用示例注意事项 存储过程的强大功能实战技巧示例总结 在 MySQL 的学习过程中&#xff0c;存储过程&am…

如何删除Maven

1.找到Maven安装路径 方法一&#xff1a; 可以直接在文件资源管理器里面选中“此电脑”然后右上角搜“apache-maven”&#xff0c;这个过程可能长达几分钟甚至更久 方法二&#xff1a; 这里推荐一个名叫“Everything”的软件&#xff0c;能够快速的查找到需要的文件 2.找到本…

Vue3中ref和reactive的对比

1. ref 定义 用途: 用于创建基本数据类型或单一值的响应式引用。语法: const myRef ref(initialValue); 特性 返回一个包含 .value 属性的 Proxy 对象。适用于基本数据类型&#xff08;如数字、字符串、布尔值等&#xff09;和单一值。 import { ref } from vue;const co…