【Java SE】类和对象

目录

【1】面向对象的初步认识

【1.1】什么是面向对象

【1.2】面向对象与面向过程

【2】类定义和使用

【2.1】简单认识类

【2.2】类的定义格式

【2.3】练习

【2.3.1】定义一个狗类

【2.3.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】默认初始化


类和对象

【1】面向对象的初步认识

【1.1】什么是面向对象

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

【1.2】面向对象与面向过程

【传统洗衣服方式】

 

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

        而且不同衣服洗的方式,时间长度,拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另一种放方式。按照该种方式来写代码,将来扩展或者维护起来会比较麻烦

【现代洗衣服方式】

 

        以面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关心,只需要将衣服放进洗衣机,倒入洗衣粉,启动开关即可,通过对象之间的交互来完成的。注意:面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。

【2】类定义和使用

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

 

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

【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 关键字. 后面会详细解释 。

【2.3】练习

【2.3.1】定义一个狗类

 

class PetDog {// 狗的属性public String name;//名字public String color;//颜色// 狗的行为public void barks() {System.out.println(name + ": 旺旺旺~~~");}public void wag() {System.out.println(name + ": 摇尾巴~~~");}
}

【2.3.2】定义一个学生类

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修饰的类的名称,如果要修改,通过开发工具修改(给同学演示)。

【3】类的实例化

【3.1】什么是实例化

        定义了一个类,就相当于在计算机中定义了一种新的类型,与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 关键字用于创建一个对象的实例。

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

  • 同一个类可以创建对个实例。

【3.2】类和对象的说明

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

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

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

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

 

【4】this的引用

【4.1】为什么要有this引用

【先看一个日期类的例子】

public class Date {// 成员属性public int year;public int month;public int day;// 成员方法public void setDate(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) {Date date1 = new Date();date1.year = 2022;date1.month = 12;date1.day = 12;Date date2 = new Date();date2.year = 2022;date2.month = 11;date2.day = 11;Date date3 = new Date();date3.year = 2022;date3.month = 10;date3.day = 10;date1.printDate();date2.printDate();date3.printDate();}
}

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

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

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

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

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

 

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

【4.2】什么是this引用

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

public class Date {// 成员属性public int _year;public int _month;public int _day;public void setDate(int year, int month, int day) {this._year = year;this._year = month;this._year = day;}// 成员方法public void printDate() {System.out.println(_year + "年" + _month + "月" + _day + "日");}public static void main(String[] args) {Date date1 = new Date();date1._year = 2022;date1._month = 12;date1._day = 12;Date date2 = new Date();date2._year = 2022;date2._month = 11;date2._day = 11;Date date3 = new Date();date3._year = 2022;date3._month = 10;date3._day = 10;date1.printDate();date2.printDate();date3.printDate();}
}

【注意】this引用的是调用成员方法的对象

 

【4.3】this引用的特性

  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 {// 构造方法:// 名字与类名相同,没有返回值类型,设置为void也不行// 一般情况下使用public修饰// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次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 int _year;public int _month;public int _day;/* 入口函数Main */public static void main(String[] args) {// 此处创建了一个Date类型的对象,并没有显式调用构造方法Date date1 = new Date(2022,12,12);  // 输出Date(int,int,int)方法被调用了date1.printDate();}
}

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

【5.2.2】特性

  1. 名字必须与类名相同

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

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

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

public class Date {// 无参构造方法public Date() {System.out.println("我是一个无参的构造方法");}// 带有三个参数的构造方法public Date(int year, int month, int day) {System.out.println("我是一个带3个参数的构造方法");this._year = year;this._month = month;this._day = day;}// 成员方法public void printDate() {System.out.println(_year + "年" + _month + "月" + _day + "日");}// 成员属性public int _year;public int _month;public int _day;/* 入口函数Main */public static void main(String[] args) {Date date1 = new Date(2022,12,12);  date1.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();}
}

上述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找到: 没有参数原因: 实际参数列表和形式参数列表长度不同*/
  1. 构造方法中,可以通过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: 递归构造器调用*/
  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) {// 此处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. 初始化所分配的空间

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

数据类型默认值
byte0
char'\u0000'
short0
int0
long0L
booleanfalse
float0.0f
double0.0
referencenull

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

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

相关文章

【Java基础学习打卡18】运算符(上)

目录 前言一、运算符和表达式1.运算符2.表达式 二、算术运算符1.加法运算符2.减法运算符3.乘法运算符4.除法运算符5.取余运算符6.表达式类型自动提升 总结 前言 本文主要介绍运算符和表达式,及运算符中的算术运算符。在 Java 编程中,运算符起着非常重要…

Java 使用 Google Guava 实现接口限流

一、引入依赖 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version> </dependency>二、自定义注解及限流拦截器 自定义注解&#xff1a;Limiter package com.haita…

安装requests模块及其他依赖库的完美解决办法

业务场景 导入requests库时报错&#xff0c;单独离线下载安装requests&#xff0c;发现仍然报错&#xff0c;问题在于requests库有其他依赖库。 WARNING: Retrying (Retry(total1, connectNone, readNone, redirectNone, statusNone)) after connection broken by NewConnect…

PgSQL-使用技巧-如何衡量网络对性能的影响

PgSQL-使用技巧-如何衡量网络对性能的影响 PG数据库和应用之间常见的部件有连接池、负载平衡组件、路由、防火墙等。我们常常不在意或者认为涉及的网络hops对整体性能产生的额外开销是理所当然的。但在很多情况下&#xff0c;它可能会导致严重的性能损失和拖累整体吞吐量。相当…

Set集合类详解(附加思维导图)

目录 一、Set集合思维导图 二、set集合类常用方法 2.1、HashSet集合常用方法 2.2、TreeSet集合的使用 三、HashSet、LinkedHashSet、TreeSet的使用场景 四、list和set集合的区别 一、Set集合思维导图 二、set集合类常用方法 2.1、HashSet集合常用方法 ①&#xff1a;add…

redis面试1

Redis基础面试题 1、为什么要使用Redis做缓存 缓存的好处 使用缓存的目的就是提升读写性能。而实际业务场景下&#xff0c;更多的是为了提升读性能&#xff0c;带来更好的性 能&#xff0c;带来更高的并发量。Redis 的读写性能比 Mysql 好的多&#xff0c;我们就可以把 Mysq…

【小白必看】利用Python生成个性化名单Word文档

文章目录 前言所需文件及文件格式说明excel数据如下word 模板如下文件目录格式及生成后的文件 导入所需的模块&#xff1a;打开 Excel 文件&#xff1a;选择工作表&#xff1a;获取数据列表&#xff1a;遍历数据并生成 Word 文档&#xff1a;完整代码结束语 前言 对于需要批量…

【MyBatis 学习一】认识MyBatis 第一个MyBatis查询

目录 一、认识MyBatis 1、MyBatis是什么&#xff1f; 2、为什么要学习MyBatis? 二、配置MyBatis环境 1、建库与建表 2、创建新项目 3、xml文件配置 &#xff08;1&#xff09;配置数据库连接 &#xff08;2&#xff09;配置 MyBatis 中的 XML 路径 三、测试&#x…

mysql(三)用户权限管理

目录 前言 一、概述 二、用户权限类型 三、用户赋权 四、权限删除 五、删除用户 前言 为什么要设置用户权限&#xff1f; MySQL设置用户管理权限的主要目的是为了确保数据库的安全性和数据的机密性。以下是一些原因&#xff1a; 1. 安全性&#xff1a;MySQL是一个开源的关系型…

Java集合之List

ArrayLsit集合 ArrayList集合的特点 ArrayList集合的一些方法 ①.add(Object element) 向列表的尾部添加指定的元素。 ②.size() 返回列表中的元素个数。 ③.get(int index) 返回列表中指定位置的元素&#xff0c;index从0开始。 public class Test {public static void m…

dependency walker工具简介及使用

dependency walker工具 简介使用 简介 官方概述&#xff1a; Dependency Walker is a free utility that scans any 32-bit or 64-bit Windows module (exe, dll, ocx, sys, etc.) and builds a hierarchical tree diagram of all dependent modules. For each module found, …

C++ 核心编程

一、 内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理 全局区&#xff1a;存放全局变量和静态变量以及常量 栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值、…

gensim conherence model C_V 值与其他指标负相关BUG

在我用gensim3.8.3 conherence model分析京东评论主题模型时&#xff0c; C_V 与npmi、u_mass出现了强烈的皮尔逊负相关&#xff1a; 这些地方也反映了类似问题&#xff1a; https://github.com/dice-group/Palmetto/issues/12 https://github.com/dice-group/Palmetto/issue…

测等保2.0——安全区域边界

一、前言 今天我们来说说安全区域边界&#xff0c;顾名思义&#xff0c;安全区域边界就是保障网络边界处&#xff0c;包括网络对外界的边界和内部划分不同区域的交界处&#xff0c;我们的重点就是查看这些边界处是否部署必要的安全设备&#xff0c;包括防火墙、网闸、网关等安…

git相关

gerrit用户指南&#xff1a; 资料&#xff1a;Gerrit 用户指南 gerrit-user-guide 上述有介绍如何review&#xff0c;review并非修改代码之后如何重新提交等操作 jenkins介绍 Jenkins详细教程 - 知乎 一、jenkins是什么&#xff1f; Jenkins是一个开源的、提供友好操作界…

使用Ensp配置DHCP协议

如何使用Ensp配置DHCP协议&#xff0c;为PC自动分配IP地址 什么是DHCP&#xff1f; Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff0c;简单理解为自动分配IP地址&#xff0c;有了这个协议就不用手动配置IP地址了&#xff0c;如图 思路 给路由…

Ubuntu 上编译protobuf 指

欢迎大家关注我的B站主页MYVision_MY视界的个人空间-MYVision_MY视界个人主页-哔哩哔哩视频 下载protobuf GitHub - protocolbuffers/protobuf: Protocol Buffers - Googles data interchange format 根据需要从release 中下载指定的版本 下载完之后&#xff0c;根据提供的C…

Godot 4 着色器 - Shader调试

我之前用OpenCV进行图像相关处理&#xff0c;觉得已经很不错&#xff0c;结合GDI可以实现流畅的动画效果 直到近来用Shader后才发现&#xff0c;着色器更上一层楼&#xff0c;原来这是入了GPU的坑 Shader编程限制很多&#xff0c;各种不支持&#xff0c;看在它性能不错功能炫…

发布npm包流程

发布npm包的步骤如下&#xff1a; 在终端中通过 npm init 命令创建一个新的npm包&#xff0c;按照提示填写包的信息&#xff0c;如包名称、版本、描述、作者、许可证等。 在包的根目录下创建一个 index.js 文件&#xff0c;编写你的代码。 确认你已经注册了npm账号&#xff0…

mysql进阶2——prosysql实现mysql读写分离

文章目录 一、读写分离方案类型1.1 最简单的读写分离1.2 多个读组或写组的分离模式 二、案例2.1 初始化操作2.2 mysql主添加proxysql连接用户2.3 Proxysql添加连接mysql集群参数2.4 添加健康检测用户2.5 添加读写分离的路由规则2.6 验证 一、读写分离方案类型 基本了解&#xf…