Java类与对象详解(从语法到内部存储)

news2024/11/16 23:45:52

Java类与对象详解(从语法到内部存储)

  • 一、什么是类?
    • 1、定义
    • 2、语法
  • 二、类的实例化
    • 1、什么是实例化
    • 2、语法
    • 3、成员变量和成员方法的访问
  • 三、构造方法
    • 1、什么是构造方法
    • 2、构造方法的重载
    • 3、构造方法的调用
  • 四、this关键字
  • 五、类对象的内部存储结构
  • 六、static关键字
    • 1、static的基本认知
    • 2、static的深入理解

一、什么是类?

1、定义

类(class)是Java中对一个实体的描述。对于一个实体,我们可以从属性和行为两个角度来描述。比如面对一只狗,它的属性有:姓名、性别等,它的行为有:吃饭、汪汪叫等。

那么在Java中如何体现这两个角度的描述呢?属性我们可以用基本数据类型来表示(在后面的学习中,我们也可以用其他的类来表示)。行为我们可以用方法(就是我们在C语言中说到的函数)来表示。

2、语法

[public] class 类名{
	属性
	
	方法
}

其中,类中的属性叫做“成员属性”,类中的方法叫做“成员方法”。

这里需要解释一个地方,class前面的public是可选择的,如果我们当前这个类和该java文件的文件名相同的时候,该类前面需要加public关键字,并且每个文件有且仅有一个类前面加public。比如我们有一个文件叫:test.java,那么在这个文件中,我们的test类的前面就需要加上public,但是其他类的前面不加该关键字。

另外大家不要随便地举一反三,有的读者可能了解到了public是一个访问限定符,就会有这样一种想法,这个能加public的类前面能不能将public替换成protected或者private呢?答案是不可以的。这个与文件名同名的类的前面只能加public

我们以刚刚的狗为例,看看我们应该如何描述?

public class Dog{
	//属性描述
    public String name;
    public int age;
    //行为描述
    public void eatFood(){
        System.out.println(name + "正在吃饭。");
    }
    public void barks(){
        System.out.println(name + "正在汪汪叫。");
    }
}    

二、类的实例化

1、什么是实例化

我们在上文中学到了如何描述一个对象,那么我们如何根据这个描述去实例化一个具体的对象呢?就好像,我们已经知道了狗有哪些属性以及哪些行为,那么我们是不是可以利用这些描述去描述生活中一只“具体”的狗呢?

这种根据抽象的描述创建具体的对象的过程就叫做实例化。

2、语法

类名 对象名 = new 类名();

我们还用刚刚的狗为例子,实例化过程如下。

Dog dog = new Dog();

3、成员变量和成员方法的访问

那么我们如何访问对象中的具体属性和方法呢?我们可以通过类名.属性名的语法去访问成员属性,当然也可以通过类名.方法名(参数)来访问成员方法。

我们创建一个main函数,那么我们可以写:

public static void main(String[] args) {
    Dog dog = new Dog();
    dog.name = "Tom";
    dog.eatFood();
    dog.barks();
    System.out.println("狗的名字是" + dog.name);
}

三、构造方法

我们在刚刚的语法中发现了一个很奇怪的地方。我们在new关键字的后面,写了一个类似于调用方法的代码段Dog(),这一部分其实就是调用了构造方法

1、什么是构造方法

构造方法就是在new对象的同时调用的方法,语法是类名()。但是我们会发现在之前的代码中,我们并未写构造方法,我们没写,编译器怎么调用呢?

其实,当我们不写的时候,Java会为我们提供一个默认的构造方法,这个构造方法没有参数,方法体内也是空白的,具体如下(以Dog类为例):

public Dog(){

}

这也就是为什么我们在调用构造方法的时候,没有在括号内写参数。

2、构造方法的重载

那么我们能不能根据我们的需要重新写构造函数呢?答案是可以的。语法如下:

public 类名(参数1,参数2...){
    方法体
}

我们以刚刚的Dog类为例子,如果我们想在构造Dog对象的同时给这个对象赋值。那么我们可以这样写构造方法。

public Dog(String n, int a){
    name = n;
    age = a;
}

3、构造方法的调用

由于我们重写了构造方法,所以原先编译器提供的构造方法就消失了,根据我们刚刚的例子,重写之后,我们有了形参,所以在new对象的时候就要传进去。

那么就可以写成

Dog dog = new Dog("Tom", 2);

四、this关键字

我们发现刚刚写的构造方法中,我们很难通过形参的名了解到它想让我们传入什么数据。那么我们可以把形参写地更清楚一些。

public Dog(String name, int age){
    name = name;
    age = age;
}

但是根据局部变量优先的原则,等号两边的name都是形参变量。但实际上,我们是想将形参变量name赋值给成员变量name。那么为了达到这一目的,我们就引入了this关键字,我们可以通过this.成员名来访问成员变量。

那么我们可以将上面的代码转化为:

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

五、类对象的内部存储结构

我们直接打印一下new出来的对象,如下所示:

public static void main(String[] args) {
     Dog dog = new Dog("Tom", 2);
     System.out.println(dog);
 }

通过终端我们可以观察到如下结果:
在这里插入图片描述
出乎意料的是,它并没有打印出dog中的成员属性。那么我来解释一下这段打印。
在这里插入图片描述
Dog所在包其实就可以理解为它所在的目录。后面才是重点。在学C语言的时候,我们都知道每一个变量对应一个硬件地址,那么这些地址经过转化后,会形成一串16进制的串,转化之后的这个值叫做哈希值,也叫做hash值

而我们的对象名指向的就是这一串hash值,而不是该对象。

具体存储结构如下:
在这里插入图片描述

因此我们把类似于dog的对象名称作引用。所以,我们的类又叫做引用类型

除此以外,类中的成员方法并不是和成员属性在一起的,而是共同存储在了成员方法区。

六、static关键字

1、static的基本认知

我们看下面这个例子:

public class Dog{
    public static String type;
    public String name;
    public int age;
}

那么我们new几个对象:

Dog d1 = new Dog("T1", 1, "Animal");
Dog d2 = new Dog("T2", 2, "Animal");
Dog d3 = new Dog("T3", 3, "Animal");
Dog d4 = new Dog("T4", 4, "Animal");
Dog d5 = new Dog("T5", 5, "Animal");

如果转化为内存的话,就相当于有5个引用分别是d1...d5,他们分别指向堆中五块不同的区域。但是我们发现成员属性type的值都是animal,因此我们没必要存储五份,只需要存储一份即可。

因此,我们可以将这一个属性抽离出来,让多个对象共用一个成员属性。

那么,我们就可以用static去修饰,此时就可以让多个对象共用一个成员变量。

public class Dog{
    public static String type;
    public String name;
    public int age;
}

那么此时的存储结构就会发生如下变化:

加static之前:
在这里插入图片描述

加static之后:
在这里插入图片描述

2、static的深入理解

既然所有的类对象共用一个静态变量,也就是说静态变量不依赖于对象。

所以即使我们没有实例化对象,我们依旧能够访问到类中的静态成员。

所以我们可以直接用:类名.静态变量名来访问,当然用实例化后的对象名.静态变量名访问也可以,但是不规范。

比如:

public static void main(String[] args) {
    Dog.type = "Animal";
}

除了成员变量之前可以加static关键字,我们的成员方法之前也可以加static。那么根据刚刚的分析,如果加了static。那么我们的静态方法也可以在不实例化对象的情况下调用。比如我们的println()方法。

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

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

相关文章

【STM32】STM32学习笔记-软件I2C读写MPU6050(33)

00. 目录 文章目录 00. 目录01. I2C简介02. MPU6050参数03. 软件I2C接线图04. I2C模拟应答时序示例05. I2C读取MPU6050程序示例06. 程序下载07. 附录 01. I2C简介 I2C(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式…

DeepSecrets:一款能够理解代码语义的代码敏感信息扫描工具

关于DeepSecrets DeepSecrets是一款能够理解代码语义的代码敏感信息扫描工具,在该工具的帮助下,广大研究人员将能够更有效地扫描和分析代码中的敏感信息。 社区中很多现有的代码分析工具其实并不能够真正地“理解”代码,而是直接解析代码文…

(亲测可行)关于提高IDEA运行速度的方案

1.作者IDEA软件版本和计算机内存 Ultimate 2022.1.2版IDEA,计算机内存为12GB 2.修改配置以提高IDEA运行速度的误区-调高堆内存 很多文章会教调配置的内存,但大多是让你调高堆内存,比如会让你调高-Xms -Xmx ,这两种对应的是最…

Linux:理解磁盘与文件系统

文章目录 前面基础的总结文件系统文件的管理目的问题文件的管理内容问题 磁盘磁盘的结构和基本原理磁盘的分区磁盘的索引原理磁盘的逻辑抽象写入 本篇主要对于磁盘进行深入的理解,从而对于文件系统有一个基本的认识 前面基础的总结 在开始对文件系统做理解前&…

【PostgreSQL】安装和常用命令教程

PostgreSQL window安装教程 window安装PostgreSQL 建表语句: DROP TABLE IF EXISTS student; CREATE TABLE student (id serial NOT NULL,name varchar(100) NOT NULL,sex varchar(5) NOT NULL,PRIMARY KEY (id) );INSERT INTO student (id, name, sex) VALUES (…

Ubuntu 22.04安装使用easyconnect

EasyConnect 百度百科,EasyConnect能够帮助您在办公室之外使用公司内网的所有系统及应用。在您的公司部署深信服远程应用发布解决方案后,您的公司所有业务系统及应用都可以轻松迁移至移动互联网上。您可以通过手机、PAD等智能移动终端随时随地开展您的业…

程序员接私活还不知道这几个平台?那你真的亏了!

程序员接私活现在已经是一个老生常谈的话题了,现在市面上各种程序员接单平台层出不穷,也参差不齐,有比较老牌的知名平台,也有比较好的新兴平台,如此多的平台就容易让人眼花缭乱,不知道该如何选择。 这期文…

CSS3背景样式详解(图像大小,图像位置等)

背景样式 在CSS3中,新增了3个背景属性 属性说明background-size背景大小background-origin背景位置background-clip背景剪切 background-size属性 概念:在CSS3之前,我们是不能用CSS来控制背景图片大小的,背景图片的大小都是由…

【HarmonyOS】消息通知场景的实现

从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是…

(N-139)基于springboot,vue宠物领养系统

开发工具:IDEA 服务器:Tomcat9.0, jdk1.8 项目构建:maven 数据库:mysql5.7 系统分前后台,项目采用前后端分离 前端技术:vue3element-plus 服务端技术:springbootmybatis-plusr…

C练习——杨辉三角

题目: 打印近似杨辉三角,行数n自选 百度找的杨辉三角,参考一下: 解析: 把它的全部元素左对齐,就可以看成近似杨辉三角的样子 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 …… 每个数等于它上方两数…

C++基础1

一、形参带默认值的函数 二、inline内联函数 内联函数是一种在编译器处理时,将函数的实际代码插入到调用处的方法。通常,函数调用涉及一定的开销,包括保存和恢复调用现场、跳转到函数的代码位置等。而内联函数通过在调用处直接插入函数的代码…

十五.流程控制与游标

流程控制与游标 1.流程控制1.1分支结构之IF1.2分支结构值CASE1.3循环结构之LOOP1.4循环结构之WHILE1.5循环结构之REPEAT1.6跳转语句之LEAVE语句1.7跳转语句之ITERATE语句 2.游标2.1什么是游标2.2使用游标步骤4.3举例4.5小结 1.流程控制 解决复杂问题不可能通过一个 SQL 语句完…

智慧校园大数据平台架构

平台架构 基础硬件层 基础硬件层是由一组低廉的PC或服务器组合构建而成。基础硬件层主要承载着数据的存储、运算、容错、调度和通信等任务,对基础应用层下达的指令进行执行和反馈。 数据集成 大数据特征表现在实时、交互、海量等方面,并且以半结构化、非结构化数据为主,价…

SpringBoot中 如何优雅的 重试调用 第三方API?

引言 在实际的应用中,我们经常需要调用第三方API来获取数据或执行某些操作。然而,由于网络不稳定、第三方服务异常等原因,API调用可能会失败。为了提高系统的稳定性和可靠性,我们通常会考虑实现重试机制。 本文将深入探讨如何在…

基于JAVA的固始鹅块销售系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固始鹅块模块2.4 鹅块订单模块2.5 评论管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 鹅块类型表3.2.2 鹅块表3.2.3 鹅块订单表3.2.4 鹅块评论表 四、系统展示五、核心代码5.…

vue前端开发自学,祖孙多层级组件嵌套关系数据传输

vue前端开发自学,祖孙多层级组件嵌套关系数据传输!官方提供了一个解决方案,就是,在根组件内使用provide,哪个子孙组件想调用这个数据,就可以inject接收就行了。虽然是方便了,但是这个有点要求,就是只能自上…

重新认识Word——页眉页脚

重新认识Word——页眉页脚 节设置页脚第X页,共Y页 奇偶页不同页眉包含章节号清除页眉横线 我们之前已经全面的构建了我们的文章,现在我们来了解一下,我们毕业论文的页眉(页面信息)页脚(页码)的设…

JVM运行时数据区(下篇)

紧接上篇:JVM运行时数据区(上篇)-CSDN博客 堆 一般Java程序中堆内存是空间最大的一块内存区域。创建出来的对象都存在于堆上。 栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态…

Java中的Servlet你了解吗?

☆* o(≧▽≦)o *☆嗨~我是小奥🍹 📄📄📄个人博客:小奥的博客 📄📄📄CSDN:个人CSDN 📙📙📙Github:传送门 📅&a…