Java类与对象:从概念到实践的全景解析!

                                                                                个人主页:秋风起,再归来~

                                                                                文章专栏:javaSE的修炼之路                                

                                                                        个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!

1、类的定义格式

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

// 创建类
class ClassName{  field;       // 字段(属性) 或者 成员变量method;      // 行为 或者 成员方法
}

class为定义类的关键字,ClassName为类的名字,{}中为类的主体。 比如:洗衣机,它是一个品牌,在Java中可以将其看成是一个类别。 属性:产品品牌,型号,产品重量,外观尺寸,颜色... 功能:洗衣,烘干、定时....

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

举一个简单的栗子啦~

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("洗衣服");}
}

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

注意事项:

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

2. main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法) 3. public修饰的类必须要和文件名相同

4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改。

下面通过IDEA来看一下怎么修改:

2、类的实例化 

定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自 带的内置类型,而类是用户自定义了一个新的类型

它们都是类(一种新定 义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。 用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。

class PetDog{public String name;public String color;public void bark(){System.out.println("汪汪叫~~");}public void wag(){System.out.println("摇尾巴~~");}
}
public class Test {public static void main(String[] args) {PetDog dog1=new PetDog();//通过new实例化对象dog1.name="阿黄";dog1.color="黑黄";System.out.println(dog1.name);System.out.println(dog1.color);dog1.bark();dog1.wag();}
}

注意事项

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

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

3。同一个类可以创建多个实例.

3、类和对象的说明

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

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

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

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

4、this引用

4.1为什么要有this引用

下面我先举一个栗子~

class Data{public int year;public int month;public int day;public void setData(int y,int m,int d){year=y;month=m;day=d;}public void show(){System.out.println("年:"+year+" 月:"+month+" 日:"+day);}
}
public class Test {public static void main(String[] args) {Data data1=new Data();//新建一个对象Data data2=new Data();Data data3=new Data();data1.setData(2024,1,30);//引用对象的函数赋值日期data2.setData(2024,2,30);data3.setData(2024,3,30);data1.show();//引用对象的函数打印数据data2.show();data3.show();}

现在看上面的代码似乎没有任何问题~

但我们仔细思考就会以下有两个问题:

1.但如果形参名与变量名相同怎么办呢?

  public void setData(int year,int month,int day){year=year;month=month;day=day;}

那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?估计自己都搞不清楚了。下面看一下改变之后的结果~

为什么呢?

其实原因很简单:局部变量优先,在方法中,它认为只是形参自己给自己赋值了,并没有给成员变量赋值~

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

一切让this引用来揭开这层神秘的面纱~

4.2什么是this引用

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

class Data{public int year;public int month;public int day;public void setData(int year,int month,int day){this.year=year;this.month=month;this.day=day;}public void show(){System.out.println("年:"+year+" 月:"+month+" 日:"+day);}
}

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

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

4.3this引用的特性

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

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

3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象

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

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

5、对象的构造及初始化

5.1 如何初始化对象

通过前面知识点的学习知道,在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. 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

5.2 构造方法

5.2.1 概念

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

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}
}

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

5.2.2 特性

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修饰(后序讲单例模式时会遇到)

5.3 默认初始化

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. 调用构造方法,给对象中各个成员赋值  

5.4 就地初始化

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

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();}
}

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

6、 完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

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

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

相关文章

LabVIEW车载轴承振动监测系统

LabVIEW车载轴承振动监测系统 随着汽车工业的快速发展,车用轴承的稳定性和可靠性对保障车辆安全运行越来越重要。目前,大多数车用轴承工作在恶劣的环境下,容易出现各种故障。开发了一种基于LabVIEW的车载轴承振动监测系统,提高车…

941: 有序顺序表的合并操作的实现

学习版 【c语言】 1.顺序表元素类型 2.顺序表的初始化 3.顺序表的插入 4.顺序表的合并 #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm>typedef struct {int* data; // 数据数组的指针int length; // 当前顺序表…

学习平台的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 1. 系统功能…

【Qt 学习笔记】Day1 | Qt 开发环境的搭建

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Day1 | Qt 开发环境的搭建 文章编号&#xff1a;Qt 学习笔记 / 02 文…

Redis命令-Set命令

基础篇Redis 4.7 Redis命令-Set命令 Redis的Set结构与Java中的HashSet类似&#xff0c;可以看做是一个value为null的HashMap。因为也是一个hash表&#xff0c;因此具备与HashSet类似的特征&#xff1a; 无序元素不可重复查找快支持交集.并集.差集等功能 Set类型的常见命令 …

浅谈AI未来发展趋势与挑战

对于AI大模型未来发展趋势与挑战的个人看法&#xff1a; 1、未来的发展趋势&#xff1a; AI大模型未来发展趋势可以从以下几个关键方面来讨论&#xff1a; 1. 能源与计算效率 绿色计算与节能技术&#xff1a;随着硬件技术的发展&#xff0c;预计未来的AI大模型将进一步降低能…

redis学习-主从复制和哨兵模式

目录 1. 主从复制&#xff0c;读写分离 1.1 介绍 1.2 使用命令介绍 1.3 实现 1.4全量复制和增量复制 2.哨兵模式 1. 主从复制&#xff0c;读写分离 1.1 介绍 指的是将一台redis服务器中的数据复制到其他redis服务器&#xff0c;前者称为主机&#xff0c;后者称为从机&#xf…

基于SpringBoot + Vue实现的高校汉服租赁网站系统设计与实现+毕业论文

介绍 高校汉服租赁网站管理系统可以提高高校汉服租赁网站信息管理问题的解决效率&#xff0c;优化高校汉服租赁网站信息处理流程&#xff0c;保证高校汉服租赁网站信息数据的安全&#xff0c;它是一个非常可靠&#xff0c;非常安全的应用程序。系统包含普通用户和管理员两个角…

【AI系列】Python NLTK 库和停用词处理的应用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

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

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

GEE23:基于植被物候实现农作物分类

地物分类 1. 写在前面2. 北京作物分类 1. 写在前面 今天分享一个有意思的文章&#xff0c;用于进行农作物分类。文章提出了一个灵活的物候辅助监督水稻(PSPR)制图框架。主要是通过提取植被物候&#xff0c;并自动对物候数据进行采样&#xff0c;获得足够多的样本点&#xff0c;…

探索一致性哈希算法以及在 Dubbo 负载均衡中的应用

文章目录 负载均衡简介基于哈希算法的负载均衡策略传统哈希算法一致性哈希算法虚拟一致性哈希算法 一致性哈希在 Dubbo 中的应用ConsistentHashSelector 构造方法ConsistentHashSelector select方法 负载均衡简介 负载均衡&#xff08;Load Balance&#xff0c;简称 LB&#x…

WPF中获取TreeView以及ListView获取其本身滚动条进行滚动

实现自行调节scoll滚动的位置(可相应获取任何控件中的内部滚动条) TreeView:TreeViewAutomationPeer lvap new TreeViewAutomationPeer(treeView); var svap lvap.GetPattern(PatternInterface.Scroll) as ScrollViewerAutomationPeer; var scroll svap.Owner as ScrollVie…

【HCIP学习】网络类型级数据链路层协议

思维导图在上面哦~ 一、网络类型的分类&#xff08;4种&#xff09; 出现原因&#xff1a;数据链路层使用的协议及规则不同&#xff0c;造成了不同的网络类型 1、多点接入网络&#xff08;MA&#xff09;------一条网段内上出现多个设备 BMA&#xff1a;广播型多点接入&…

linux内核:ftrace——追踪内核行为

文章目录 1. 简介2. 使用2.1 加入ftrace2.2 ftrace 基础2.2.1 tracer2.2.2 filter&#xff08;可选&#xff09;2.2.3 读取trace2.2.4 ftrace_enabled 2.3 使用function_graph查看do_sys_open的执行过程2.3 使用function查看do_sys_open的执行2.3 使用wakeup2.3 使用wakeup_rt2…

C语言例1-11:语句 while(!a); 中的表达式 !a 可以替换为

A. a!1 B. a!0 C. a0 D. a1 答案&#xff1a;C while()成真才执行&#xff0c;所以!a1 &#xff0c;也就是 a0 原代码如下&#xff1a; #include<stdio.h> int main(void) {int a0;while(!a){a;printf("a\n");} return 0; } 结果如…

JUC:Monitor 与 Java对象头的内容与锁关系

文章目录 Monitorjava对象头Monitor&#xff08;锁、管程&#xff09; Monitor java对象头 普通对象 Mark Word 主要用来存储对象自身的运行时数据、klass word就是指向该对象的类型。 数组对象 mark word 不同对象状态下结构和含义不同。 Monitor&#xff08;锁、管…

SRS OBS利用RTMP协议实现音视频推拉流

参考&#xff1a;https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started 1&#xff09;docker直接运行SRS服务&#xff1a; docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5运行起来后可以http://localho…

数据恢复宝典:揭秘分区合并后的数据拯救之路

在计算机存储管理中&#xff0c;分区合并是一项常见的硬盘操作。它通过将两个或多个相邻的磁盘分区合并成一个更大的分区&#xff0c;来扩展存储空间或简化磁盘管理。然而&#xff0c;这个看似简单的操作背后&#xff0c;却隐藏着数据丢失的巨大风险。许多用户在尝试分区合并时…

ElementUI表格table组件实现单选及禁用默认选中效果

在使用ElementUI&#xff0c;需要ElementUI表格table组件实现单选及禁用默认选中效果, 先看下效果图&#xff1a; 代码如下&#xff1a; <template><el-tableref"multipleTable":data"tableData"tooltip-effect"dark"style"widt…