JavaSE学习笔记第二弹——对象和多态(下)

news2024/9/20 6:33:40

今天我们继续复习与JavaSE相关的知识,使用的编译器仍然是IDEA2022,大家伙使用eclipse或其他编译环境是一样的,都可以。


目录

数组

定义

一维数组

​编辑

二维数组

多维数组

数组的遍历

for循环遍历

​编辑

foreach遍历

封装、继承和多态

封装

继承

多态

重写

instanceof关键字

final关键字

抽象类

接口

总结


数组

定义

数组是相同类型数据的有序集合。数组可以代表任何相同类型的一组内容(包括引用类型和基本类型)其中存放的每一个数据称为数组的一个元素,数组的下标是从0开始,也就是第一个元素的索引是0,不是基本数据类型。

一维数组

一维数组中,元素是依次排列的(线性),每个数组元素可以通过下标来访问。声明方式如下:

  1. 类型[] 变量名称 = new 类型[数组大小];
  2. 类型[] 变量名称 = new 类型[数组大小];
  3. 类型[] 变量名称 = new 类型[]{...}; //静态初始化(直接指定值和大小)
  4. 类型[] 变量名称 = {...};
public class Main {
    public static void main(String[] args) {
        int[] arr_1 = new int[10];
        float[] arr_2 = new float[10];
        int[] arr_3 = new int[]{1,1,4,5,1,4};
        double[] arr_4 = {1.0,2.3,4.9};
    }
}

创建出来的数组每个元素都有默认值,我们可以通过下标去访问。

public class Main {
    public static void main(String[] args) {
        int[] arr = new int[10];
        arr[0] = 626;
        System.out.println(arr[0]);
        System.out.println(arr[1]);
    }
}

我们可以通过数组变量名称.length来获取当前数组长度:

public class Main {
    public static void main(String[] args) {
        int[] arr_3 = new int[]{1,1,4,5,1,4};
        System.out.println(arr_3.length);
    }
}

 

数组在创建时,就固定长度,不可更改。访问超出数组长度的内容,会出现错误。例如在Java当中,如果你尝试访问超出数组长度的内容,程序会抛出ArrayIndexOutOfBoundsException异常。

public class Main {
    public static void main(String[] args) {
        int[] arr_3 = new int[]{1,1,4,5,1,4};
        System.out.println("length of arr_3" + "=" + arr_3.length);
        System.out.println(arr_3[10]);
    }
}

二维数组

二维数组是存放数组的数组,每一个元素都存放一个数组的引用,等于在数组当中嵌套一个数组,套娃中的套娃,可以类比线性代数当中的矩阵或行列式来理解。以下就是一个典型的二维数组:

int[][] arr = { {1, 2},
                {3, 4},
                {5, 6}};
System.out.println(arr[2][1]);

二维数组的定义方式与一维数组几乎完全一致,如下所示:

  1. 类型[][] 变量名称 = new 类型[数组大小][数组大小];
  2. 类型[][] 变量名称 = new 类型[数组大小][数组大小];
  3. 类型[][] 变量名称 = new 类型[][]{...}; //静态初始化(直接指定值和大小)
  4. 类型[][] 变量名称 = {...};
public class Main {
    public static void main(String[] args) {
        int[][] arr_1 = new int[10][10];
        float[][] arr_2 = new float[10][10];
        int[][] arr_3 = new int[][]{{1,1},{4,5},{1,4}};
        double[][] arr_4 = {{1.0,2.3},{4.9,5.2}};
    }
}

当然,这里我们也可以用length来查看数组的长度,方法与一维数组一样。

多维数组

多维数组与二维数组类似,只是不断的套娃而已,可以借鉴二维数组的原理来理解。

数组的遍历

for循环遍历

for循环是我们马上就能想到的一种遍历方法,从我们学习C语言开始,我们就知道想要遍历一个数组,最直接的方法就是使用for循环来遍历。同样,在Java当中,for循环他也是存在的,格式也一样,for循环直呼:没想到吧!下面是一个常规的for循环:

public class Main {
    public static void main(String[] args) {
        int[] arr = new int[]{1,1,4,5,1,4};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

foreach遍历

foreach属于增强型的for循环,它使得代码更简洁,同时我们能直接拿到数组中的每一个数字。它隐藏了迭代器和索引的细节,使得遍历数组或集合更加直观。但是,它不允许你直接访问元素的索引。

public class Main {
    public static void main(String[] args) {
        int[] arr = new int[]{1,1,4,5,1,4};
        for (int i : arr) {
            System.out.println(i);
        }
    }
}


封装、继承和多态

封装、继承和多态是面向对象编程的三大特性。

封装

封装的主要目的是保护对象的内部状态,防止外部代码直接访问对象的内部属性,并通过定义公共的方法来访问这些属性。这样做的好处包括提高代码的安全性、可维护性和灵活性。封装的作用主要可以概括为以下五点:数据隐藏、提高代码的安全性、提高代码的可维护性、灵活性、促进模块化。

如下我为大家展示了一段经过封装的代码:

public class PleaSure {
    private String name;
    private int age;

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

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
}

要调用已经封装好的代码中的 getAge 方法,我们需要首先创建一个 PleaSure 类的实例,然后使用这个实例来调用 getAge 方法。具体代码如下:

public class Main {
    public static void main(String[] args) {
        // 创建一个Student对象,并通过构造函数初始化它的name和age属性
        PleaSure pleasure = new PleaSure("Pleasure", 18);

        // 使用student对象调用getAge方法,并打印返回的年龄
        int age = pleasure.getAge();
        System.out.println("age is: " + age);
    }
}

那么如果现在我想要更改姓名name,那么我们需要新增加一个方法在封装的类内部:

public class Main {
    public static void main(String[] args) {
        // 创建一个Student对象,并通过构造函数初始化它的name和age属性
        PleaSure pleasure = new PleaSure("Pleasure", 18);

        // 使用student对象调用getAge方法,并打印返回的年龄
        int age = pleasure.getAge();
        System.out.println("age is: " + age);
        pleasure.setAge(20);
        age = pleasure.getAge();
        System.out.println("age is: " + age);
    }
}
public class PleaSure {
    private String name;
    private int age;

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

    public int getAge() {
        return age;
    }

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

    public void setAge(int age) {
        if (age >= 0) {
            this.age = age;
        } else {
            throw new IllegalArgumentException("Age cannot be negative.");
        }
    }
}

此时如果我们想要更改年龄,就会得出如下结果:

当然这段代码当中,我已经通过直接在代码片段当中调用setAge来修改年龄,如果想要通过键盘输入,减少每次查找到这段setAge代码再进行修改的麻烦,我们可以通过new一个Scanner来进行键盘输入,这样就可以每次通过键盘输入,而非反复查找相关代码,节约时间。

继承

继承允许我们基于一个已存在的类(称为父类或基类)来创建一个新的类(称为子类或派生类),子类会继承父类的属性和方法,可以减少代码的重复定义。封装的作用主要可以概括为以下七点:代码重用、扩展功能、建立类之间的层次关系、多态性的基础、模板化设计、访问控制、实现接口的一种替代方式。

现在PleaSure分为两种,A和B,他们都是PleaSure的分支,但是他们都有自己的方法:

public class APleaSure extends PleaSure{
    public APleaSure(String name, int age) {
        super(name, age);
    }

    public void guanzhu(){
        System.out.println("关注");
    }
}
//CSDN的PleaSure乐事水印
public class BPleaSure extends PleaSure{
    public BPleaSure(String name, int age) {
        super(name, age);
    }

    public void dianzan(){
        System.out.println("点赞");
    }
}

需要一定注意的是,在继承后我们必须先通过super关键字(指代父类),实现父类的构造方法。当我们已经像上面这样完成了两个继承完毕的子类,我们可以通过如下方法完成调用方法:

public class Main {
    public static void main(String[] args) {
        // 创建APleaSure实例
        APleaSure apleaSure = new APleaSure("Alice", 30);
        // 调用APleaSure的guanzhu方法
        apleaSure.guanzhu();
        // 创建BPleaSure实例
        BPleaSure bpleaSure = new BPleaSure("Bob", 25);
        // 调用BPleaSure的dianzan方法
        bpleaSure.dianzan();
    }
}

需要注意的是,每一个子类必须定义一个实现父类构造方法的构造方法,也就是需要在构造方法开始使用super,如果父类使用的是默认构造方法,那么子类不用手动指明。

所有类都默认继承自Object类,除非手动指定类型,但是依然改变不了最顶层的父类是Object类。所有类都包含Object类中的方法。

多态

多态允许一个引用变量在运行时指向多种实际类型的对象,并且这些对象可以执行相同的方法但表现出不同的行为。多态的作用主要包含以下几点:增加程序的扩展性和可维护性、接口和抽象类的实现、动态绑定、提高代码复用性和灵活性。

重写

方法的重写和重载是不一样的,重载是原有的方法逻辑不变的情况下,支持更多参数的实现,而重写是直接覆盖原有方法。

假设我们在父类中有这样一个方法:

public void study(){
    System.out.println("点赞");
}

在子类中我们通过重写后的代码如下:

@Override
public void study(){
    System.out.println("关注");
}

那么我们在主函数中调用study方法后我们会得到如下结果:

public class Main {
    public static void main(String[] args) {
        // 创建APleaSure实例
        APleaSure apleaSure = new APleaSure("Alice", 30);
        // 调用APleaSure的guanzhu方法
        apleaSure.study();
    }
}

当我们在重写方法时,不仅想使用我们自己的逻辑,同时还希望执行父类的逻辑(也就是调用父类的方法)时我们可以写如下代码:

public void study(){
    super.study();
    System.out.println("给你看点好康的");
}

同理,如果想访问父类的成员变量,也可以使用super关键字来访问,例如:

public void setTest(int test){
    test = 1;
  	this.test = 1;
  	super.test = 1;
}

instanceof关键字

我们如果只是得到一个父类引用,但是不知道它到底是哪一个子类的实现时,我们可以使用instanceof关键字来帮助我们进行类型判断。

final关键字

final关键字能够使得一个变量的值不可更改,那么如果在类前面声明final,则该类无法再被继承,不允许子类的存在。如果类的成员属性被声明为final,那么必须在构造方法中或是在定义时赋初始值。

private final String name;   //引用类型不允许再指向其他对象
private final int age;    //基本类型值不允许发生改变

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

抽象类

类本身就是一种抽象,而抽象类,把类还要抽象,也就是说抽象类可以只保留特征,而不保留具体呈现形态,比如方法可以定义好,但是我可以不去实现它,而是交由子类来进行实现。例如:

public abstract class Student {    //抽象类
		public abstract void test();  //抽象方法
}

通过使用abstract关键字来表明一个类是一个抽象类,抽象类可以使用abstract关键字来表明一个方法为抽象方法,也可以定义普通方法,抽象方法不需要编写具体实现,但是必须由子类实现(除非子类也是一个抽象类)

但是需要注意的是,抽象类由于不是具体的类定义,因此无法直接通过new关键字来创建对象。

接口

在Java当中,接口只代表某个确切的功能,也就是只包含方法的定义,接口包含了一些列方法的具体定义,类可以实现这个接口,表示类支持接口代表的功能。使用interface实现。

public interface Eat {
	void eat(); 
}

一个类可以实现很多个接口,类通过implements关键字来声明实现的接口,每个接口之间用逗号隔开。比如:

public class SportsStudent extends Student implements Eat, ...{
		@Override
    public void eat() {
        
    }
}

总结

至此,我们大致浏览和学习了JavaSE当中有关数组、封装、继承、多态、抽象类和接口相关的知识,希望对大家有所帮助,也希望大家可以为我留下点赞、关注和收藏,这对我真的很重要,谢谢!也希望能与大家一起努力,获得更好的未来。

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

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

相关文章

14-63 剑和诗人37 - 分布式系统中的数据访问设计

​​ 在分布式系统中,跨服务和数据库提供统一、可靠的数据访问至关重要,但又极具挑战性。微服务和数据库的拓扑结构为分布、缓存、复制和同步带来了复杂性。 让我们探索有助于解决这些复杂性并简化构建强大、高性能分布式系统的常见数据访问模式。 概述 我们将通过示例介绍…

嵌入式音频处理技术的现在发展及未来的方向

嵌入式音频处理技术&#xff1a;从音频流媒体到声音识别 嵌入式音频处理技术的迅猛发展正在改变我们的生活方式&#xff0c;从音频流媒体到声音识别&#xff0c;这个领域为人们的生活和工作带来了巨大的影响。本文将探讨嵌入式音频处理技术的最新趋势和应用&#xff0c;以及提…

HCIP课堂笔记

第一章 1、数据转换---目标&#xff1a;抽象语言---二进制---电信号 2、应用程序---接收参数和指令&#xff08;编码&#xff1a;接收传递给计算机指令参数最终转换为二进制&#xff09; 3、二进制---电信号 4、对于整个互联网而言指定了统一的标准——OSI/RM参考模型 &…

运算放大器(运放)输入失调电压

输入失调电压定义 理想状态下&#xff0c;如果运算放大器的两个输入端电压完全相同&#xff0c;输出应为0 V。实际上&#xff0c;还必须在输入端施加小差分电压&#xff0c;强制输出达到0。该电压称为输入失调电压VOS。输入失调电压可以看成是电压源VOS&#xff0c;与运算放大…

洞庭湖决堤前后——SAR视角

洞庭湖决堤前后——SAR视角 数据&#xff1a;哨兵1 IW GRD&#xff0c;决堤前2024年6月15日、决堤后2024年7月4日&#xff0c;决口封堵后的影像 工具&#xff1a;SNAP 区域&#xff1a;洞庭湖位置如下 处理流程&#xff1a; &#xff08;0&#xff09; 原始数据 &#xff08;1…

iNavFlight飞控固件学习-1《开发环境搭建》

目录 文章目录 目录摘要1.官网2.形成Linux开发环境工具2.1 简介2.2 相关工具2.2.1 Ubuntu / Debian系统配置命令2.2.2 Fedora系统配置命令2.2.3 Fedora系统配置命令 2.3 克隆存储库2.4 构建工具2.5 使用cmake2.6 构建固件2.7 清除2.8 cmake 缓存维护2.9 编译通过ninja2.10 更新…

【漏洞复现】锐捷校园网自助服务系统 任意文件读取

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 锐捷校园网自助服务系统是用于学校网络管理的一个平台&#xff0c;login_judge.jsf接口存在任意文件读取…

甘肃美食于兰洽会数智电商馆展现魅力

在近日盛大开幕的兰洽会上&#xff0c;数智电商馆成为了备受瞩目的焦点&#xff0c;而甘肃平凉的特产更是在其中大放异彩。 平凉&#xff0c;这座拥有深厚历史文化底蕴的城市&#xff0c;带着其独具特色的物产走进了兰洽会的舞台。走进数智电商馆&#xff0c;首先映入眼帘的便是…

防火墙小试——部分

1.实验拓扑及要求 1&#xff0c;Dz区内的服务器&#xff0c;办公区仅能在办公时间内(9: 00 - 18 : 00〉可以访问&#xff0c;生产区的设备全天可以访问. 2&#xff0c;生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3&#xff0c;办公区设备10.0.2.10不允…

数据结构 —— BellmanFord算法

数据结构 —— BellmanFord算法 BellmanFord算法检测负权值环BellmanFord和Dijkstra思想上的区别Dijkstra算法的思想Bellman-Ford算法的思想思想上的对比 我们今天来看一个算法BellmanFord算法&#xff0c;我们之前的Dijkstra算法只能用来解决正权图的单源最短路径问题。 Bell…

计算机的错误计算(二十七)

摘要 介绍错数&#xff1a;任给一个单变元函数&#xff0c;当自变量被截断时&#xff0c;函数值中含有的错误的有效数字个数&#xff0c;并给出其计算方法。 首先&#xff0c;从字面上看&#xff0c;错数表示错误的有效数字个数。 下面从一个略显粗糙的化简过程&#xff0c;推…

数据结构-散列表(hash table)

6.1 散列表的概念 散列表又叫哈希&#xff08;hash&#xff09;表&#xff0c;是根据键&#xff08;key&#xff09;直接访问在内存存储位置的值&#xff08;value&#xff09;的数据结构&#xff0c;由数组演化而来&#xff08;根据数组支持按照下标进行随机访问数据的特性&a…

14-60 剑和诗人34 - Kubernetes 是部署 LLM 的首选平台

​​​​ 介绍 近年来&#xff0c;大型语言模型 (LLM) 一直在彻底改变自然语言处理领域。从 GPT-3 到 PaLM 等&#xff0c;这些模型可以生成类似人类的文本、回答问题、总结文档等等。然而&#xff0c;训练和部署 LLM 需要大量的计算。随着这些模型的规模和能力不断增长&#…

类和对象——【const成员】【static成员】【友元】【内部类】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件iostream的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

有必要找第三方软件测评公司吗?如何选择靠谱软件测评机构?

软件测试是确保软件质量的重要环节&#xff0c;而在进行软件测试时&#xff0c;是否有必要找第三方软件测评公司呢?第三方软件测评公司是指独立于软件开发公司和用户之间的中立机构&#xff0c;专门从事软件测试和测评工作。与自身开发团队或内部测试团队相比&#xff0c;选择…

修BUG:程序包javax.servlet.http不存在

貌似昨晚上并没有成功在tomcat上面运行&#xff0c;而是直接运行了网页。 不知道为啥又报错这个。。。 解决方案&#xff1a; https://developer.baidu.com/article/details/2768022 就整了这一步就行了 而且我本地就有这个tomcat就是加进去了。 所以说啊&#xff0c;是不是&a…

CentOS7 安装 git 命令

通过yum源install下载的git版本比较低&#xff0c;不推荐此方式安装。 官网下载最新版git源码&#xff1a;Git 1. 解压安装包 tar -xzvf git-2.45.2.tar.gz 2. 安装相关依赖 yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils…

政安晨:【Keras机器学习示例演绎】(五十四)—— 使用神经决策森林进行分类

目录 导言 数据集 设置 准备数据 定义数据集元数据 为训练和验证创建 tf_data.Dataset 对象 创建模型输入 输入特征编码 深度神经决策树 深度神经决策森林 实验 1&#xff1a;训练决策树模型 实验 2&#xff1a;训练森林模型 政安晨的个人主页&#xff1a;政安晨 欢…

Git常见命令和用法

Git 文件状态 Git 文件 2 种状态: 未跟踪:新文件&#xff0c;从未被 Git 管理过已跟踪:Git 已经知道和管理的文件 常用命令 命令作用注意git -v查看 git 版本git init初始化 git 仓库初始化之后有工作区、暂存区(本地库)、版本库git add 文件标识暂存某个文件文件标识以终…

吹田电气绿色能源 未来可期

在2024年7月的上海慕尼黑电子展上&#xff0c;吹田电气功率分析仪成为了备受瞩目的明星产品。作为电子测试与测量领域的重要工具&#xff0c;功率分析仪在展会上展示了其在绿色能源和高效能量管理方面的最新应用&#xff0c;引发了广泛关注和热议。 领先技术&#xff0c;精准测…