当前位置: 首页 > news >正文

类和对象解析

导言:

Java是一门纯面向对象的语言,在面对对象的世界里,一切皆为对象。而对象的创建又和类的定义息息相关。本文主要阐述了类和对象的使用与理解。解释类的定义方式以及对象的实例化,类中的成员变量和成员方法的使用,以及对象的整个初始化过程。

目录

导言:

正文:

一.类的定义和使用

二.类的构造方法

三.this引用

四.类的实例化

五.类的初始化

总结:


正文:

一.类的定义和使用

类是一种抽象的数据类型,是用于描述具有相同属性和行为的对象的集合。

具体来说,类是用来对一个实体(对象)来进行描述的,主要用来描述该实体(对象)具有哪些属性,哪些功能。

类的定义:使用关键字class来定义一个类,通常包含类的访问修饰符、类名、类体等部分。

  1. 类的访问修饰符:类可以有四种访问修饰符,分别是public、protected、private和默认(即不加修饰符)。这些修饰符控制着类的可见性,即哪些代码可以访问该类。

  2. 类名:类名是一个标识符,用于唯一标识一个类。类名的命名规范是以大写字母开头,采用驼峰命名法。

  3. 类体:类体是类的主体部分,包含了类的属性和方法的定义。类体由一对花括号{}括起来。

这里对修饰符先进行一个解释,,类、方法和属性都可以使用权限修饰符来控制它们的访问权限,这些权限修饰符包括public、protected、private和默认(即不加修饰符)。

  • public:public是最宽松的权限修饰符,它可以被任何类、方法和属性访问。如果一个类、方法或属性被声明为public,那么它可以被同一个包中的其他类、不同包中的其他类以及任何地方的子类和非子类访问。

  • protected:protected修饰符可以被同一个包中的其他类访问,也可以被不同包中的子类访问。如果一个类、方法或属性被声明为protected,那么它可以被同一个包中的其他类、不同包中的子类访问,但是不可以被不同包中的非子类访问。

  • private:private是最严格的权限修饰符,它只能被同一个类中的其他方法和属性访问。如果一个方法或属性被声明为private,那么它只能被同一个类中的其他方法和属性访问,不可以被同一个包中的其他类或不同包中的任何类访问。

  • 默认权限修饰符:如果一个类、方法或属性没有使用任何权限修饰符,那么它的访问权限就是默认的。默认权限修饰符只能被同一个包中的其他类访问,不可以被不同包中的任何类访问。

类的定义具体语法如下

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

例如:

public class Student11_4 {public String name;//成员变量public int age;//成员变量//成员方法public void show(){System.out.println("hello world");}
}

二.类的构造方法

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

构造方法有以下几个特点:

  1. 构造方法与类同名:构造方法的名称必须与类的名称完全相同。

  2. 没有返回类型:与普通方法不同,构造方法没有返回类型,包括void。构造方法的主要目的是初始化对象,而不是返回某个值。

  3. 可以有多个构造方法:一个类可以有多个构造方法,它们之间的区别可以通过参数的类型、个数和顺序来区分。这种情况下被称为构造方法的重载,即构造方法也支持重载。

  4. 默认构造方法:如果一个类没有定义任何构造方法,编译器会自动为该类生成一个默认的无参构造方法。默认构造方法不做任何初始化操作。

  5. 显式定义构造方法:如果在类中显式定义了一个或多个构造方法,编译器就不会生成默认构造方法。在这种情况下,如果想使用无参构造方法,需要显式地定义一个无参构造方法。

  6. 构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。内存分配的工作是由JVM在实例化对象时自动完成的。构造方法只负责对对象的属性进行初始化。构造方法执行完毕后,对象才被完全创建并可以使用。

例如,假设有一个名为Person的类,它有属性name和age,并且定义了两个构造方法:

//定义一个人类
public class Person {//成员变量private String name;private int age;// 无参构造方法public Person() {name = "Unknown";age = 0;}// 带参构造方法public Person(String name, int age) {//this在这里先进行使用,后面会进行解释this.name = name;this.age = age;}
}

在这个例子中,Person类定义了一个无参构造方法和一个带参构造方法。无参构造方法用于初始化name和age属性的默认值,带参构造方法用于接收外部传入的name和age值,并将其赋给对象的属性。

三.this引用

在Java中,this是一个特殊的关键字,它表示当前对象的引用。this关键字可以在类的方法和构造方法中使用,用于引用当前对象的成员变量、成员方法和构造方法。

this关键字的主要作用有以下几个方面:

1. 引用当前对象的成员变量:在类的方法中,如果方法中的局部变量与成员变量同名,可以使用this关键字来引用当前对象的成员变量。

例如:

public class Person {private String name;public void setName(String name) {this.name = name; // 使用this关键字引用当前对象的成员变量}
}

在这个例子中,setName方法中的参数name与成员变量name同名,为了区分它们,使用this.name表示当前对象的成员变量。

2. 调用当前对象的成员方法:在类的方法中,可以使用this关键字来调用当前对象的其他成员方法。例如:

public class Person {private String name;public void setName(String name) {this.name = name; // 使用this关键字引用当前对象的成员变量}
}

在这个例子中,method2方法中使用this.method1()调用了当前对象的method1方法。

3. 在构造方法中调用其他构造方法:在一个类中,可以定义多个构造方法,通过使用this关键字在一个构造方法中调用另一个构造方法。这种方式称为构造方法的重载。例如:

public class Person {private String name;private int age;public Person() {this("Unknown", 0); // 调用带参构造方法}public Person(String name, int age) {this.name = name;this.age = age;}
}

在这个例子中,无参构造方法中使用this("Unknown", 0)调用了带参构造方法,实现了对name和age属性的初始化。

需要注意的是,this关键字只能在非静态方法和构造方法中使用,因为静态方法没有this引用,它是属于类而不是对象的。

4.事实上,成员方法中都有this。this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收在代码层面来简单演示--->注意:下图右侧中的Date类也是可以通过编译的

 

四.类的实例化

定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义的一个新的类型,它们本质都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。

对象的构造和初始化是指在创建对象时,为对象分配内存空间并对对象的属性进行初始化的过程。

  1. 对象的构造:在Java中,使用关键字"new"来创建一个对象。当使用"new"关键字实例化一个类的对象时,JVM会为该对象分配内存空间,并调用该类的构造方法来初始化对象的属性。

  2. 对象的初始化:对象的初始化是指在构造方法中对对象的属性进行赋值操作,使对象的属性具有初始值。初始化可以在构造方法中直接赋值,也可以通过调用其他方法或外部传入的参数来进行赋值。对象的初始化是在对象创建之后立即执行的,确保对象的属性在创建之后具有正确的初始值。

具体的语法是:类名 对象名 = new 类名();

//定义一个人类
public class Person {
//成员变量private String name;private int age;
//构造方法public Person(String name, int age) {this.name = name;this.age = age;}
//成员方法public void sayHello() {System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");}
}

可以通过以下方式实例化Person类:

//调用Person类的有参构造
//创建了一个Person类的对象
Person person = new Person("John", 25);
//调用成员方法
person.sayHello();

 在这个例子中,通过new关键字创建了一个Person类的对象,并将其赋值给变量person。同时,调用了Person类的构造方法来初始化对象的属性。然后,可以通过person来访问和调用对象的属性和方法,例如person.name、person.age和person.sayHello()。

五.类的初始化

先来看一段代码,

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) {
// int a;
// System.out.println(a);
// 此处a没有初始化,编译时会报错:
// Error:(24, 28) java: 可能尚未初始化变量a//编译通过
Date d = new Date(2021,6,9);
}
}

 可以看到局部变量在使用时必须要初始化,但成员变量即使没有初始化也可以正常使用。

事实上,并非成员变量没有初始化,只是编译器帮我们做了这件事,对成员变量设置了初始值。

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

在程序层面只是简单的一条语句,但在JVM层面需要做好多事情,下面简单介绍下:
1. 检测对象对应的类是否加载了,如果没有加载则加载
2. 为对象分配内存空间
3. 处理并发安全问题
比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
4. 初始化所分配的空间 即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:

数据类型默认值
byte

0

char'\u0000'
short0
int0
long0L
booleanfalse
float0.0f
double0.0
referencenull

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

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

总结:

类和对象之间的关系可以理解为类是对象的模板,而对象是类的实例。通过类可以创建多个对象,每个对象都有自己的属性和行为,但是它们共享同一个类的定义。对象是类的实例化结果,它是类的具体实体。对象具有类定义的属性和行为,并且可以通过访问对象的成员变量和调用对象的方法来操作对象。每个对象都有自己的状态(成员变量的值)和行为(方法的执行)。希望本文对你有所帮助。

相关文章:

  • Java21-虚拟线程小试牛刀-meethigher
  • Python---字符串中的查找方法--index()--括号里是要获取的字符串
  • Qt5 安装 phonon
  • 力扣:150. 逆波兰表达式求值(Python3)
  • 数据结构和算法的区分和学习
  • Flask蓝图(Blueprint)
  • Pycharm 对容器中的 Python 程序断点远程调试
  • visual basic 6.0软件安装包(永久),适用于Windows各系统附安装教程
  • 旅游业为什么要选择VR全景,VR全景在景区旅游上有哪些应用
  • 路由器基础(二): BGP原理与配置
  • 【计算机组成与设计】Chisel取指和指令译码设计
  • ‘spmatrix‘ has no attribute ‘__div__‘. Did you mean: ‘__dir__‘?
  • lamba stream处理集合
  • 【Midjourney入门教程4】与AI对话,写好prompt的必会方法
  • Spring Boot创建多模块项目
  • CentOS 7 防火墙操作
  • conda常用的命令
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • js写一个简单的选项卡
  • Laravel Telescope:优雅的应用调试工具
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 高性能JavaScript阅读简记(三)
  • 基于axios的vue插件,让http请求更简单
  • 使用putty远程连接linux
  • 算法系列——算法入门之递归分而治之思想的实现
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • Mac 上flink的安装与启动
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • (13):Silverlight 2 数据与通信之WebRequest
  • (2)(2.10) LTM telemetry
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (定时器/计数器)中断系统(详解与使用)
  • (二十三)Flask之高频面试点
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (十一)手动添加用户和文件的特殊权限
  • (一)Linux+Windows下安装ffmpeg
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • ***监测系统的构建(chkrootkit )
  • .gitignore文件—git忽略文件
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET CF命令行调试器MDbg入门(一)
  • .net 调用php,php 调用.net com组件 --
  • .net 生成二级域名
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .net程序集学习心得
  • .sh 的运行
  • [ 第一章] JavaScript 简史
  • [100天算法】-x 的平方根(day 61)
  • [android] 手机卫士黑名单功能(ListView优化)
  • [AX]AX2012 SSRS报表Drill through action
  • [Bada开发]初步入口函数介绍