【详识JAVA语言】类和对象

面向对象的初步认知

什么是面向对象

Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人 们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。

面向对象与面向过程

传统洗衣服过程

传统的方式:注重的是洗衣服的过程,少了一个环节可能都不行。 

而且不同衣服洗的方式,时间长度,拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另一种放方式。

按照该种方式来写代码,将来扩展或者维护起来会比较麻烦

现代洗衣服过程

总共有四个对象:人 衣服、洗衣粉、洗衣机

整个洗衣服的过程:入将衣服放进洗衣机、倒入洗衣粉,启动洗衣机,洗衣机就会完成洗衣过程并且甩干

整个过程主要是:人、衣服、洗衣粉、洗衣机四个对象之间交互完成的,人不需要关新洗衣机具体是如何洗衣服的,是如何甩干的

面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关 心,只需要将衣服放进洗衣机,倒入洗衣粉,启动开关即可,通过对象之间的交互来完成的

注意:面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。

类定义和使用

面相对象程序设计关注的是对象,而对象是现实生活中的实体,比如:洗衣机。但是洗衣机计算机并不认识,需要开发人员告诉给计算机什么是洗衣机。

该过程称为对洗衣机对象(实体)进行抽象(对一个复杂事物的重新认知),但是 这些简化的抽象结果计算机也不能识别,开发人员可以采用某种面相对象的编程语言来进行描述,比如:Java语 言。 

简单认识类

类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干 啥),描述完成后计算机就可以识别了。

比如:洗衣机,它是一个品牌,在Java中可以将其看成是一个类别。 属性:产品品牌,型号,产品重量,外观尺寸,颜色... 功能:洗衣,烘干、定时....

在Java语言中,如何对上述的洗衣机类来进行定义呢?

类的定义格式

在java中定义类时需要用到class关键字,具体语法如下

// 创建类

class ClassName{

field; // 字段(属性) 或者 成员变量

method; // 行为 或者 成员方法

}

class为定义类的关键字,ClassName为类的名字,{}中为类的主体。

类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类 具有哪些功能,称为类的成员方法。

class WashMachine{

public String brand; // 品牌

public String type; // 型号

public double weight; // 重量

public double length; // 长

public double width; // 宽

public double height; // 高

public String color; // 颜色

public void washClothes(){ // 洗衣服

System.out.println("洗衣功能");

}

public void dryClothes(){ // 脱水

System.out.println("脱水功能");

}

public void setTime(){ // 定时

System.out.println("定时功能");

}

}

采用Java语言将洗衣机类在计算机中定义完成,经过javac编译之后形成.class文件,在JVM的基础上计算机就可以 识别了。

注意事项

类名注意采用大驼峰定义

成员前写法统一为public,后面会详细解释

此处写的方法不带 static 关键字. 后面会详细解释

练习 

定义一个狗类

class PetDog {

public String name;//名字 
public String color;//颜色

// 狗的属性 
public void barks() { 
System.out.println(name + ": 旺旺旺~~~"); 
}

// 狗的行为 
public void wag() { 
System.out.println(name + ": 摇尾巴~~~"); 
}

}

定义一个学生类 

public class Student{

public String name;

public String gender;

public short age;

public double score;

public void DoClass(){}

public void DoHomework(){}

public void Exam(){}

}
注意事项:

1. 一般一个文件当中只定义一个类

2. main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)

3. public修饰的类必须要和文件名相同

4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改(给同学演示)。

类的实例化

什么是实例化

定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自 带的内置类型,而类是用户自定义了一个新的类型,比如上述的:PetDog类和Student类。它们都是类(一种新定 义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。

用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。

 

public class Main{

public static void main(String[] args) {

PetDog dogh = new PetDog(); //通过new实例化对象

dogh.name = "阿黄";

dogh.color = "黑黄";

dogh.barks();

dogh.wag();

PetDog dogs = new PetDog();

dogs.name = "阿黄";

dogs.color = "黑黄";

dogs.barks();

dogs.wag();

}

}

输出结果:

阿黄: 旺旺旺~~~

阿黄: 摇尾巴~~~

赛虎: 旺旺旺~~~

赛虎: 摇尾巴~~~
注意事项

new 关键字用于创建一个对象的实例.

使用 . 来访问对象中的属性和方法.

同一个类可以创建对个实例.

类和对象的说明 

 

1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.

2. 类是一种自定义的类型,可以用来定义变量.

3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东 西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

this引用 

为什么要有this引用

先看一个日期类的例子:

public class Date {

public int year;

public int month;

public int day;

public void setDay(int y, int m, int d){

year = y;

month = m;

day = d;

}

public void printDate(){

System.out.println(year + "/" + month + "/" + day);

}

public static void main(String[] args) {

// 构造三个日期类型的对象 d1 d2 d3

Date d1 = new Date();

Date d2 = new Date();

Date d3 = new Date();

// 对d1,d2,d3的日期设置

d1.setDay(2020,9,15);

d2.setDay(2020,9,16);

d3.setDay(2020,9,17);

// 打印日期中的内容

d1.printDate();

d2.printDate();

d3.printDate();

}

}

以上代码定义了一个日期类,然后main方法中创建了三个对象,并通过Date类中的成员方法对对象进行设置和打 印,代码整体逻辑非常简单,没有任何问题。

但是细思之下有以下两个疑问:

1. 形参名不小心与成员变量名相同:

public void setDay(int year, int month, int day){

year = year;

month = month;

day = day;

}

那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?估计自己都搞不清楚了。

2. 三个对象都在调用setDate和printDate函数,但是这两个函数中没有任何有关对象的说明,setDate和 printDate函数如何知道打印的是那个对象的数据呢?

什么是this引用

this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

public class Date {

public int year; 
public int month; 
public int day;

public void setDay(int year, int month, int day){ 
this.year = year; 
this.month = month; 
this.day = day; 
}

public void printDate(){ 
System.out.println(this.year + "/" + this.month + "/" + this.day); 

}
}

注意:this引用的是调用成员方法的对象。 

public static void main(String[] args) { 
Date d = new Date(); 
d.setDay(2020,9,15); 
d.printDate(); 
}

this引用的特性 

1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型

2. this只能在"成员方法"中使用

3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象 4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收

在代码层面来简单演示--->注意:下图右侧中的Date类也是可以通过编译的

对象的构造及初始化 

如何初始化对象

通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。

public static void main(String[] args) {

int a;

System.out.println(a);

}

// Error:(26, 28) java: 可能尚未初始化变量a

要让上述代码通过编译,非常简单,只需在正式使用a之前,给a设置一个初始值即可。如果是对象:

public static void main(String[] args) {

Date d = new Date();

d.printDate();

d.setDate(2021,6,9);

d.printDate();

}

// 代码可以正常通过编译

需要调用之前写的SetDate方法才可以将具体的日期设置到对象中。通过上述例子发现两个问题:

1. 每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?

2. 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

构造方法

概念

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且 在整个对象的生命周期内只调用一次

public class Date {

public int year;

public int month;

public int day;

// 构造方法:

// 名字与类名相同,没有返回值类型,设置为void也不行

// 一般情况下使用public修饰

// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次

public Date(int year, int month, int day){

this.year = year;

this.month = month;

this.day = day;

System.out.println("Date(int,int,int)方法被调用了"); }

public void printDate(){

System.out.println(year + "-" + month + "-" + day);

}

public static void main(String[] args) {

// 此处创建了一个Date类型的对象,并没有显式调用构造方法

Date d = new Date(2021,6,9);

// 输出Date(int,int,int)方法被调用了

d.printDate(); // 2021-6-9

}

}

注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。

特性 

1. 名字必须与类名相同

2. 没有返回值类型,设置为void也不行

3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)

4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)

public class Date {

public int year; 
public int month; 
public int day;

// 无参构造方法 
public Date(){

this.year = 1900;

this.month = 1; this.day = 1;

} // 带有三个参数的构造方法 
public Date(int year, int month, int day) {

this.year = year;

this.month = month;

this.day = day; 
}

public void printDate(){ 
System.out.println(year + "-" + month + "-" + day); 
}

public static void main(String[] args) { 
Date d = new Date(); 
d.printDate(); 
}

}

上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载。

5. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。 

public class Date {

public int year; 
public int month; 
public int day;

public void printDate(){ 
System.out.println(year + "-" + month + "-" + day); 
}

public static void main(String[] args) { 
Date d = new Date(); d.printDate(); 
}

}

上述Date类中,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。

注意:一旦用户定义,编译器则不再生成。 

public class Date {

public int year;

public int month;

public int day;

public Date(int year, int month, int day) {

this.year = year;

this.month = month;

this.day = day;

}

public void printDate(){

System.out.println(year + "-" + month + "-" + day);

}

public static void main(String[] args) {

// 如果编译器会生成,则生成的构造方法一定是无参的

// 则此处创建对象是可以通过编译的

// 但实际情况是:编译期报错

Date d = new Date();

d.printDate();

}

}

/* Error:(26, 18) java: 无法将类 extend01.Date中的构造器 Date应用到给定类型; 需要: int,int,int 找到: 没有参数 原因: 实际参数列表和形式参数列表长度不同 */

6. 构造方法中,可以通过this调用其他构造方法来简化代码

public class Date {

public int year;

public int month;

public int day;

// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复

// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法

// 但是this(1900,1,1);必须是构造方法中第一条语句

public Date(){

//System.out.println(year); 注释取消掉,编译会失败

this(1900, 1, 1);

//this.year = 1900;

//this.month = 1;

//this.day = 1;

}

// 带有三个参数的构造方法

public Date(int year, int month, int day) {

this.year = year;

this.month = month;

this.day = day;

}

}
注意:

this(...)必须是构造方法中第一条语句

不能形成环

public Date(){

this(1900,1,1);

}

public Date(int year, int month, int day) {

this();

}

/* 无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用 编译报错:Error:(19, 12) java: 递归构造器调用 */

7. 绝大多数情况下使用public来修饰,特殊场景下会被private修饰(后序讲单例模式时会遇到)

默认初始化

在上文中提出的第二个问题:为什么局部变量在使用时必须要初始化,而成员变量可以不用呢?

public class Date {

public int year; 
public int month; 
public int day;

public Date(int year, int month, int day) { 
// 成员变量在定义时,并没有给初始值, 为什么就可以使用呢? 
System.out.println(this.year); 
System.out.println(this.month); 
System.out.println(this.day); 
}

public static void main(String[] args) {

// 此处a没有初始化,编译时报错: 
// Error:(24, 28) java: 可能尚未初始化变量a 
// int a; // 

System.out.println(a);

Date d = new Date(2021,6,9);

}

}

要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:

Date d = new Date(2021,6,9);

在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:

1. 检测对象对应的类是否加载了,如果没有加载则加载

2. 为对象分配内存空间

3. 处理并发安全问题 比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突

4. 初始化所分配的空间

即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:

5. 设置对象头信息(关于对象内存模型后面会介绍)

6. 调用构造方法,给对象中各个成员赋值 

就地初始化

在声明成员变量时,就直接给出了初始值。

public class Date {

public int year = 1900;

public int month = 1;

public int day = 1;

public Date(){

}

public Date(int year, int month, int day) {

}

public static void main(String[] args) {

Date d1 = new Date(2021,6,9);

Date d2 = new Date();

}

}

注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中

 

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

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

相关文章

排序算法——快速排序的非递归写法

快速排序的非递归 我们写快速排序的时候,通常用的递归的方法实现快速排序,那么有没有非递归的方法实现快速排序呢?肯定是有的。思想还是一样的,不过非递归是看似是非递归其实还是递归。 思路解释 快速排序的非递归使用的是栈这…

【yolov8部署实战】VS2019+Onnxruntime环境部署yolov8-seg分割模型|含详细注释源码

0、前言 在之前博客中已经实现用onnxruntime来部署yolov8的目标检测模型(cpu和gpu皆可)。感兴趣的可以看看:【yolov8部署实战】VS2019环境下使用Onnxruntime环境部署yolov8目标检测|含源码 今天为大家带来的是yolov8-seg分割模型用onnxrunt…

Maven(黑马学习笔记)

初识Maven 什么是Maven Maven是Apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。 官网:https://maven.apache.org/ Apache 软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会&#xff0…

springer模板参考文献不显示

Spring期刊模板网站,我的问题是23年12月的版本 https://www.springernature.com/gp/authors/campaigns/latex-author-support/see-where-our-services-will-take-you/18782940 参考文献显示问好,在sn-article.tex文件中,这个sn-mathphys-num…

【MySQL】索引(重点)-- 详解

一、索引 没有索引,可能会有什么问题? 索引 :提高数据库的性能,索引是物美价廉的东西了。不用加内存,不用改程序,不用调 sql ,只要执行正确的 create index ,查询速度就可能提高成…

Java集合-ArraysLIst集合

集合是“由若干个确定的元素锁构成的整体”,在程序中,一般代表保存若干个元素(数据)的某种容器类。在Java中,如果一个Java对象可以在内部持有(保存)若干其他Java对象,并对外提供访问接口,我们把这种Java对象的容器称为…

Sora模型风口,普通人如何抓住-最新AI系统ChatGPT网站源码,AI绘画系统

一、前言说明 PandaAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧。已支持…

python标识符、变量和常量

一、保留字与标识符 1.1保留字 保留字是指python中被赋予特定意义的单词,在开发程序时,不可以把这些保留字作为变量、函数、类、模块和其它对象的名称来使用。 比如:and、as、def、if、import、class、finally、with等 查询这些关键字的方…

通过 Jenkins 经典 UI 创建一个基本流水线

通过 Jenkins 经典 UI 创建一个基本流水线 点击左上的 新建任务。 在 输入一个任务名称字段,填写你新建的流水线项目的名称。 点击 流水线,然后点击页面底部的 确定 打开流水线配置页 点击菜单的流水线 选项卡让页面向下滚动到 流水线 部分 在 流水线 …

软考55-上午题-【数据库】-数据库设计步骤1

一、数据库设计的步骤 新奥尔良法,四个主要阶段: 1、用户需求分析:手机用户需求,确定系统边界; 2、概念设计(概念结构设计):是抽象概念模型,较理想的是采用E-R方法。 …

uniapp聊天记录本地存储(详细易懂)

目录 目录 1、通过websocket拿取数据 2、获取聊天数据 3、聊天信息存储 、更新 4、读取聊天记录 5、发送信息,信息获取 6、最终效果 1.聊天信息的存储格式 2、样式效果 写聊天项目,使用到了本地存储。需要把聊天信息保存在本地,实时获…

如何限制一个账号只在一处登陆

大家好,我是广漂程序员DevinRock! 1. 需求分析 前阵子,和问答群里一个前端朋友,随便唠了唠。期间他问了我一个问题,让我印象深刻。 他问的是,限制同一账号只能在一处设备上登录,是如何实现的…

Vue中如何实现动态路由?

在前端开发中,Vue.js 是一个极为流行的 JavaScript 框架,提供了灵活性和易用性,使得开发者可以快速构建单页面应用(SPA)。在 Vue 中,我们经常需要处理动态路由的情况,比如根据用户的操作或者权限…

Linux——进程控制(二)进程等待

目录 前言 一、进程等待 二、如何进行进程等待 1.wait 2.waitpid 2.1第二个参数 2.2第三个参数 3. 等待多个进程 三、为什么不用全局变量获取子进程的退出信息 前言 前面我们花了大量的时间去学习进程的退出,退出并不难,但更深入的学习能为本…

IPC资源在linux内核中如何管理

1.先看各个通信的接口 1.共享内存接口 2.消息队列接口 3.信号量接口 2.管理他们的结构体: 其实管理他们的是一个数组,和open返回的fd差不多,shmid,msqid,semid的大小都是这个数组的下标。那数组的结构是什么呢? 然后…

UniApp项目处理小程序分包

目前 uniApp也成为一种 App端开发的大趋势 因为在目前跨端 uniApp可以说相当优秀 可以同时兼容 H5 PC 小程序 APP 的技术 目前市场屈指可数 那么 说到微信小程序 自然就要处理分包 因为微信小程序对应用大小限制非常铭感 限制在2MB 超过之后就会无法真机调试与打包 不过需要注…

前端学习第四天-css提升

达标要求 掌握css复合选择器 块级元素和行内元素及行内块的区别? 哪些元素是块元素,行内元素及行内块元素? 熟练掌握display的用法 能够说出css三大特性 熟练运用背景样式 1. CSS复合选择器 复合选择器是由两个或多个基础选择器,通过不同的方式组合而成的…

使用 Docker 部署 MrDoc 在线文档管理系统

1)MrDoc 介绍 MrDoc 简介 MrDoc 觅思文档:https://mrdoc.pro/ MrDoc 使用手册:https://doc.mrdoc.pro/p/user-guide/ MrDoc 可以创建各类私有化部署的文档应用。你可以使用它进行知识管理、构建团队文库、制作产品手册以及在线教程等。 Mr…

抖音视频批量采集软件|视频评论下载工具

在日常工作中,需要频繁下载抖音视频,但逐个复制分享链接下载效率太低?别担心!我们推出了一款专业的抖音视频批量采集软件,基于C#开发,满足您的需求,让您通过关键词搜索视频并自动批量抓取&#…

Zookeeper学习2:原理、常用脚本、选举机制、监听器

文章目录 原理选举机制(重点)情况1:正常启动集群情况2:集群启动完,中途有机器挂了 监听器客户端向服务端写入数据客户端向服务端Leader节点写入客户端向服务端Follower节点写入 Paxos算法(每个节点都可以提…