Java——类和对象

news2025/5/20 4:44:57

目录

一.类定义和使用

1.简单认识类

2.类的定义格式

3.注意事项

二.课堂练习

1.定义一个狗类

2.定义一个学生类

3.注意事项:

 三.类的实例化

1.什么是实例化

 2.注意事项

3.类和对象的说明 

四.this引用

1.为什么要有this引用  

2.什么是this引用

五.对象的构造及初始化

1.如何初始化对象

2.构造方法 

2.1概念

2.2特性

3.默认初始化

4.就地初始化 


一.类定义和使用

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

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

1.简单认识类

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

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

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的基础上计算机就可以识别了。

3.注意事项

  • 类名注意采用大驼峰定义
  • 成员前写法统一为public,后面会详细解释
  • 此处写的方法不带 static 关键字.。后面会详细解释

 

二.课堂练习

1.定义一个狗类

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(){

 }
}

3.注意事项:

  • 一般一个文件当中只定义一个类
  • main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
  • public修饰的类必须要和文件名相同
  • 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改(右键重命名)。

 三.类的实例化

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();
 }
}
 
输出结果:
阿黄: 旺旺旺~~~
阿黄: 摇尾巴~~~
赛虎: 旺旺旺~~~
赛虎: 摇尾巴~~~

 2.注意事项

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

3.类和对象的说明 

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

四.this引用

1.为什么要有this引用  

先看一个日期类的例子:

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

(1)形参名不小心与成员变量名相同 

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

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

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

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.year表示的是引用对象(即 public int year中)的year,赋值号后面的year表示的是参数中的year
        this.month = month;
        this.day = day;
   }
 
    public void printDate(){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
   }
}

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

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

 

五.对象的构造及初始化

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方法才可以将具体的日期设置到对象中。通过上述例子发现两个问题: 每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化? 
  • 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?(五.3默认初始化)

2.构造方法 

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

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

2.2特性

  • 名字必须与类名相同
  • 没有返回值类型,设置为void也不行
  • 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
  • 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
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();
   }
}

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

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

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

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
  找到: 没有参数
  原因: 实际参数列表和形式参数列表长度不同
*/
  •  构造方法中,可以通过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: 递归构造器调用
*/

绝大多数情况下使用public来修饰,特殊场景下会被private修饰(后序讲单例模式时会遇到)

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

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

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

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

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

相关文章

MySQL进阶二

目录 1.使用环境 2.排序窗口函数 3.聚合窗口函数 1.使用环境 数据库:MySQL 8.0.30 客户端:Navicat 15.0.12 接续MySQL进阶一: MySQL进阶一-CSDN博客文章浏览阅读452次,点赞9次,收藏4次。MySQL进阶操作一。https…

ThignsBoard通过服务端订阅共享属性

MQTT基础 客户端 MQTT连接 通过服务端订阅属性 案例 1、首先需要创建整个设备的信息,并复制访问令牌 ​​2、通过工具MQTTX连接上对应的Topic 3、测试链接是否成功 4、在MQTT上订阅对应的Topic 5、在客户端添加共享属性信息 6、查看整个设备的遥测数据 M…

Qt 窗⼝

Qt 窗⼝ 菜单栏创建菜单栏在菜单栏中添加菜单创建菜单项在菜单项之间添加分割线综合⽰例 ⼯具栏创建⼯具栏设置停靠位置设置浮动属性设置移动属性综合⽰例状态栏状态栏的创建在状态栏中显⽰实时消息在状态栏中显⽰永久消息 浮动窗⼝浮动窗⼝的创建设置停靠的位置 对话框对话框介…

Spring声明式事务控制

文章目录 1.编程式事务控制相关对象(了解即可)1.1PlarformTransactionManager1.2 TransactionDefinition 2.基于XML的声明式事务控制2.1声明式事务控制的实现 3.基于注解的声明式事务控制 1.编程式事务控制相关对象(了解即可) 1.1PlarformTransactionManager PlatformTransac…

NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧 NL2SQL基础系列(1):业界顶尖排行榜、权威测评数据集及LLM大模型(Spider vs BIRD)全面对比优劣分析[Text2SQL、Text2DSL] NL2SQL基础系列(2):主流大模型…

LLM应用开发框架LangChain

1、LangChain简介 1.1、LangChain发展史 LangChain 的作者是 Harrison Chase,最初是于 2022 年 10 月开源的一个项目,在 GitHub 上获得大量关注之后迅速转变为一家初创公司。2017 年 Harrison Chase 还在哈佛上大学,如今已是硅谷的一家热门…

314_C++_QT表格的撤销、恢复,可对多行、多item进行撤销、恢复操作

行–删除后的,撤销、恢复图示: 原图示 删除后 撤销操作 恢复操作 item修改后的撤销、恢复 原item 撤销修改 恢复修改 代码: --</

vue快速入门(二十四)输入停顿再进行响应

注释很详细&#xff0c;直接上代码 上一篇 新增内容 使用侦听器监视数据变化情况使用clearTimeout与定时器实现停顿一段时间再操作内容 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"view…

Chatgpt掘金之旅—有爱AI商业实战篇|播客剧本写作|(十三)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业播客剧本写作服务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。…

代码随想录算法训练营第三十九天|62.不同路径、63.不同路径II

代码随想录算法训练营第三十九天|62.不同路径、63.不同路径II 62.不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为…

nginx反向代理conf

打开nginx配置。 对登录功能测试完毕后&#xff0c;接下来&#xff0c;我们思考一个问题&#xff1a;前端发送的请求&#xff0c;是如何请求到后端服务的&#xff1f; 前端请求地址&#xff1a;http://localhost/api/employee/login 后端接口地址&#xff1a;http://localho…

[leetcode]maximum-width-of-binary-tree

. - 力扣&#xff08;LeetCode&#xff09; 给你一棵二叉树的根节点 root &#xff0c;返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每一层的 宽度 被定义为该层最左和最右的非空节点&#xff08;即&#xff0c;两个端点&#xff09;之间的长度。将这个二叉…

使用python编写网页自动答题-仿真考试

自动化实践经验分享 监听数据包地址&#xff1a;通过监听数据包地址&#xff0c;可以获得实时的答案信息&#xff0c;确保答题的准确性和实效性。提取答案内容&#xff1a;使用正则表达式和json模块&#xff0c;可以快速提取和处理答案信息。答题操作&#xff1a;根据答案内容…

前端三剑客 —— JavaScript (第八节)

目录 内容回顾&#xff1a; 事件对象 事件对象 事件对象的方法和属性 案例-移动DIV 案例-图片轮换 Ajax 内容回顾&#xff1a; 事件对象 1.1 什么是事件驱动 1.2 事件绑定 事件源&#xff1a;发生事件的源对象 事件对象&#xff1a;它包含了事件所有的信息&#xff0c;它…

深拷贝总结

JSON.parse(JSON.stringify(obj)) 这行代码的运行过程&#xff0c;就是利用 JSON.stringify 将js对象序列化&#xff08;JSON字符串&#xff09;&#xff0c;再使用JSON.parse来反序列化&#xff08;还原&#xff09;js对象&#xff1b;序列化的作用是存储和传输。&#xff08…

JavaScript(六)-高级篇

文章目录 作用域局部作用域全局作用域作用域链JS垃圾回收机制闭包变量提升 函数进阶函数提升函数参数动态参数多余参数 箭头函数 解构赋值数组解构对象解构 遍历数组forEach方法&#xff08;重点&#xff09;构造函数深入对象创建对象的三种方式构造函数实例成员 & 静态成员…

软考系规第2章思维导图,软硬件网络和次新技术大杂烩

虽然目前系统规划与管理师的教程是否改版存在不确定性&#xff0c;但是不影响咱们先概要了解当前的教程&#xff0c;使用思维导图的方式粗读教程。 为了帮助你更好的学习系规教程&#xff0c;降低系规教程阅读门槛&#xff0c;指尖疯特发起了教程伴读活动&#xff0c;通过伴读脑…

国内开通gpt会员方法

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…

全局代理导致JetBrains IDE CPU占用高,jdk.internal.net.http.common

GoLand版本&#xff1a;2022.3.4 解决办法&#xff1a; 使用SOCKS代理代替HTTP代理 禁用Space和Code With Me插件 禁用 TLS V1.3&#xff0c;参考&#xff1a;https://stackoverflow.com/questions/54485755/java-11-httpclient-leads-to-endless-ssl-loop 参考 https://…

卷积神经网络(LeNet5实现对Fashion_MNIST分类

参考6.6. 卷积神经网络&#xff08;LeNet&#xff09; — 动手学深度学习 2.0.0 documentation (d2l.ai) ps&#xff1a;在这里预备使用pythorch 1.对 LeNet 的初步认识 总的来看&#xff0c;LeNet主要分为两个部分&#xff1a; 卷积编码器&#xff1a;由两个卷积层组成; …