【JAVASE】类与对象

⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:浅谈Java
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖

类与对象

  • 1. 面向对象
    • 1.1 什么是面向对象
    • 1.2 面向对象与面向过程
  • 2. 类的定义与使用
    • 2.1 简单认识类
    • 2.2 类的定义格式
  • 3. 类的实例化
    • 3.1 什么是实例化
    • 3.2 类和对象说明
  • 4. this 引用
    • 4.1 为什么要有this引用
    • 4.2 什么是this引用
    • 4.3 this引用的特性
  • 5. 对象的构造级及初始化
    • 5.1 如何初始化对象
    • 5.2 构造方法
      • 5.2.1 概念
      • 5.2.2 特性
    • 5.3 默认初始化
    • 5.4 就地初始化

在这里插入图片描述

1. 面向对象

1.1 什么是面向对象

Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象

面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。 用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。

1.2 面向对象与面向过程

举个例子说明一下:

传统的洗衣方式,需要我们亲力亲为,准备一盆水 --> 放衣服 --> 放洗衣粉 --> 洗衣服 --> 换水 --> 拧干 --> 晾衣服,过程很多,少了一个环节可能都不行。

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

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

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

2. 类的定义与使用

2.1 简单认识类

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

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

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

2.2 类的定义格式

在 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 + ": 摇尾巴~~~");}
}

实例2:定义一个 学生 类

在这里插入图片描述

public class Student{//属性public String name;//姓名public String gender;//性别public short age;//年龄public double score;//学分//方法public void DoClass(){}//上课public void DoHomework(){}//写作业public void Exam(){}//考试
}

注:

  • 一般一个文件当中只定义一个类
  • main 方法所在的类一般要使用 public 修饰(注意:Eclipse默认会在 public 修饰的类中找 main 方法)
  • public 修饰的类必须要和文件名相同
  • 不要轻易去修改 public 修饰的类的名称

3. 类的实例化

3.1 什么是实例化

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

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

在这里插入图片描述

public class oop {public static void main(String[] args) {PetDog dogh = new PetDog(); //通过new实例化对象dogh.name = "Jack";dogh.color = "黑色";dogh.barks();dogh.wag();PetDog dogs = new PetDog();dogs.name = "Peter";dogs.color = "棕色";dogs.barks();dogs.wag();}
}
class PetDog {// 狗的属性public String name;//名字public String color;//颜色//狗的行为public void barks() {System.out.println(name + ": 旺旺旺~~~");}public void wag() {System.out.println(name + ": 摇尾巴~~~");}
}

🍤 运行结果:

在这里插入图片描述
注:

  • new 关键字用于创建一个对象的实例
  • 使用 . 来访问对象中的属性和方法
  • 同一个类可以创建对个实例

3.2 类和对象说明

  • 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员
  • 类是一种自定义的类型,可以用来定义变量
  • 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量
  • 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

4. this 引用

4.1 为什么要有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 d3Date d1 = new Date();Date d2 = new Date();Date d3 = new Date();
// 对d1,d2,d3的日期设置d1.setDay(2023,8,1);d2.setDay(2023,8,2);d3.setDay(2023,8,3);
// 打印日期中的内容d1.printDate();d2.printDate();d3.printDate();}
}

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

但是仔细想想有两个疑问:

  1. 形参名不小心与成员变量名相同:
public void setDay(int year, int month, int day){
year = year;
month = month;
day = day;
}

那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?

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

在这里插入图片描述

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

4.2 什么是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引用的是调用成员方法的对象。this.month = month;this.day = day;}public void printDate() {System.out.println(this.year + "/" + this.month + "/" + this.day);}public static void main(String[] args) {Date d = new Date();d.setDay(2023, 8, 1);d.printDate();}
}

🍩在今后写代码中尽量都用 this

4.3 this引用的特性

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

5. 对象的构造级及初始化

5.1 如何初始化对象

在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。

比如:

public static void main(String[] args) {
int a;
System.out.println(a);
}

编译器就会提示你,使用了未初始化的变量 a:
在这里插入图片描述
要让上述代码通过编译,非常简单,只需在正式使用 a 之前,给 a 设置一个初始值即可。

如果是对象:

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);}public static void main(String[] args) {Date d = new Date();d.printDate();d.setDay(2023,8,1);//初始化具体日期d.printDate();}
}

🍤 运行结果:

在这里插入图片描述
通过上述例子发现两个问题:

  • 每次对象创建好后调用 SetDay 方法设置具体日期,比较麻烦,那对象该如何初始化?
  • 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

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(2023,8,1); // 输出Date(int,int,int)方法被调用了d.printDate(); // 2023-8-1}
}

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

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

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

🍩构造方法可以有多个
🍩构造方法之间构成重载

  1. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
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();}
}

🍤 运行结果:

在这里插入图片描述

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

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

报错:

在这里插入图片描述

  1. 构造方法中,可以通过 this 调用用其他构造方法来简化代码。
public class Date {public int year;public int month;public int day;// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法// 但是this(2023,8,1);必须是构造方法中第一条语句public Date(){//System.out.println(year); 注释取消掉,编译会失败this(2023, 8, 1);//this.year = 2023;//this.month = 8;//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();}
}

🍤 运行结果:

在这里插入图片描述

注:

  • this(…)必须是构造方法中第一条语句
  • 不能形成环

例如:

public Date(){this(1900,1,1);
}
public Date(int year, int month, int day) {this();
}
  1. 绝大多数情况下使用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) {//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. 初始化所分配的空间
    即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:
数据类型默认值
byte0
char‘\u0000’
short0
int0
long0L
booleanfalse
float0.0f
double0.0
referencenull
  1. 设置对象头信息
  2. 调用构造方法,给对象中各个成员赋值

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) {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 d1 = new Date(2023,8,1);Date d2 = new Date();d1.printDate();d2.printDate();}
}

🍤 运行结果:

在这里插入图片描述

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


在这里插入图片描述

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

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

相关文章

Cordova+Vue2.0打包apk,保姆教程来袭!

1.环境准备(全部都需要配置环境变量) java version "1.8.0_341" 安卓sdk android-29 Gradle 4.10.1 node v16.16.0 cordova 10.0.0 (cordova-lib10.1.0)2.安卓环境变量 1. 确认已安装 Android SDK Build-Tools 和 Android SDK Platform-Tool…

QMLDay2:圆角按钮,关联键盘左右键,鼠标点击。状态切换控制。

QMLDay2 test1 作用: 圆角按钮,关联键盘左右键,鼠标点击。状态切换控制。 代码: import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15Window {width: 640height: 480visible: truecolor: "wh…

mysql--InnoDB存储引擎--架构和事务

MySQL进阶篇 文章目录 架构1、逻辑结构InnoDB 逻辑存储单元主层级关系图:1、表空间2、段3、区4、页5、行总结: 2、架构2、1 内存架构2、2 磁盘架构 3、事务3、1事务基础(1)事务(2)特性 架构 1、逻辑结构 I…

IO进线程——库的制作(静态库、动态库)

库的制作 1、静态库 ①生成二进制文件 gcc -c linkstack.c -o linkstack.o②制作静态库文件,把.o文件转换为.a文件 ar crs liblinkstack.a linkstack.o③编译时链接 gcc linkstack_main.c -L. -llinkstack2、动态库 ①生成地址无关二进制文件 gcc -fPIC -c l…

实现 rollup 实现多模块打包

rollup 是一个 JavaScript 模块打包器,可以将许多 JavaScript 库和应用程序打包成少量的捆绑包,从而提高了应用程序的性能。本文详细描述如何通过 rollup 实现多模块打包。 前提 项目的目录结构 先看下项目的 package.json 文件夹: {&qu…

我的 365 天创作纪念日

✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…

【Unity造轮子】实现一个类csgo的武器轮盘功能

文章目录 前言素材导入开始1.放背景和中间的圆圈,调整合适的宽高和位置2.添加选择图像框3.添加一些武器道具选择4.书写脚本RadialMenuManager5.绑定脚本和对象6.运行效果,按tab键开启关闭轮盘7.优化添加显示选中的武器文本8.添加鼠标选中放大的效果9.添加…

MySQL和Oracle区别

由于SQL Server不常用,所以这里只针对MySQL数据库和Oracle数据库的区别 (1) 对事务的提交 MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮 (2) 分页查询 MySQL是直接在SQL…

JIT 与 C#热更

JIT与AOT 一般程序运行有两种方式,静态编译与动态编译。 AOT: Ahead Of Time,预先(静态)编译 静态编译的程序,需要在执行之前全部翻译为机器码,运行前会使得程序安装时间相对较长,但程序运行的时候&#…

加载已训练好的目标检测YOLOv8,v5,v3,v6模型,对数据集中某张图片中的object打上方框、标出类别,并将图片保存到本地

参考的教程:Python - Ultralytics YOLOv8 Docs 在与ultralytics代码同一层级下新建 predict.py 里面写下面的内容。运行即可 from ultralytics import YOLO from PIL import Image import cv2# 加载计划使用的模型 model YOLO("yolov8n.pt") # load a…

2023年的深度学习入门指南(24) - 处理音频的大模型 OpenAI Whisper

2023年的深度学习入门指南(24) - 处理音频的大模型 OpenAI Whisper 在这一讲之前,我们所用的大模型都是针对文本的。这一讲我们增加一个新的领域,即音频。我们将介绍OpenAI的Whisper模型,它是一个处理音频的大模型。 Whisper模型的用法 Wh…

Qt信号与槽机制的本质

引入 对象与对象之间的通信有多个方式,如果我们要提供一种对象之间的通信机制。这种机制,要能够给两个不同对象中的函数建立映射关系,前者被调用时后者也能被自动调用。 再深入一些,两个对象如果都互相不知道对方的存在&#xff…

leetcode每日一练-第102题-二叉树的层序遍历

一、思路 BFS 二、解题方法 通过广度优先搜索(BFS)的方式,按层遍历二叉树节点,并将每层的节点值保存在一个一维数组中,然后再将所有的一维数组存储在二维数组中,最后返回二维数组作为层序遍历的结果。 …

三菱plcCCLINK转profinet与西门子PLC通讯案例分析

用三菱PLC的控制系统需要和西门子的PLC控制系统交互数据,捷米JM-PN-CCLK 是自主研发的一款 PROFINET 从站功能的通讯网关。该产品主要功能是将各种 CCLINK 总线和 PROFINET 网络连接起来。 捷米JM-PN-CCLK总线中做为从站使用,连接到 CCLINK 总线中做为…

地产变革中,物业等风来

2023年7月,也许是中国房地产行业变局中的一个大拐点。 中信建投研报表示,政治局会议指出当前我国房地产形势已发生重大变化,要适时调整优化政策,为行业形势定调……当前房地产行业β已至。 不久前,国家统计局公布了2…

洞悉安全现状,建设网络安全防护新体系

一、“网络攻防演练行动“介绍 国家在2016年发布《网络安全法》,出台网络安全攻防演练相关规定:关键信息基础设施的运营者应“制定网络安全事件应急预案,并定期进行演练”。同年“实战化网络攻防演练行动”成为惯例。由公安部牵头&#xff0…

Monorepo

❌现有的架构可能会遇到什么问题 分散的git仓库 随着时间的沉淀,项目数量在飞速增长,增加了项目的工程管理难度 怎么区分来源呢? 通过git目录划分通过项目命名 新员工入职的时候需要,需要下载代码并安装所需的依赖。在这种情…

计算机毕设 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉…

【技术讨论】RF环境搭建手册

简要整理下环境搭建的步骤,以便快速、准确的搭建测试环境。 一、环境搭建 一、Python 2.7 1、 不要用Python3.6,很多库3.6中还没有,wxPython官方只支持Python 2。 2、 环境变量配置后需要重启才能生效。 3、 环境变量添加C:\Python27\Sc…

一文详解:自动化测试工具——Selenium

前言 Selenium是一个用于Web应用程序测试的工具。是一个开源的Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium可以直接运行在浏览器上,…