【Java】:类和对象

news2024/9/23 1:35:20

1.面向对象的初步认知

1.1 什么是面向对象

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

1.2 面向对象与面向过程

1.2.1 传统洗衣过程

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

而且不同衣服洗的方式、时间长度、拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另一种方式了。

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

1.2.2 现代洗衣过程

总共有四个对象:人、衣服、洗衣粉和洗衣机

整个洗衣服的过程:人将衣服放进洗衣机、倒入洗衣粉,启动洗衣机,洗衣机就完成洗衣过程并且甩干。

整个过程主要是:人、衣服、洗衣粉和洗衣机四个对象之间的交互完成,人不需要关心洗衣机具体是如何洗衣服的,是如何甩干的。

注意面向对象和面向过程不是一门语言,而是一种解决问题的办法,没有好坏之分,都有其善于运用的场景。

2.类定义和使用

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

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

2.1 简单认识类

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

比如:洗衣机,它是一个实体,在Java中可以将其看成是一个类别。

  • 属性:产品品牌,型号,产品重量,外观尺寸,颜色......
  • 功能:洗衣,烘干,定时......

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

2.2 类的定义格式

在Java中定义类时需要用到class关键字,具体语法如下:

//创建类
class ClassName{
     filed;    //字段(属性)或者成员变量
     method;   //行为或者成员方法
}

class为定义类的关键字,ClassName为类的名字(由自己命名,需要采用大驼峰定义),{}中为类的主体。

类中包含的内容称为类的成员属性主要是用来描述类的,称之为类的成员属性或者类成员变量方法主要是用来说明类有哪些功能,称为类的成员方法

类、属性和方法的关系为:

public class WashMachine {
    public String brand;    //品牌
    public String color;    //颜色
    public double weight;   //重量

    public void washClothes(){   //洗衣服
        System.out.println("洗衣功能");
    }

    public void dryClothes(){    //脱水
        System.out.println("脱水功能");
    }

    public void setTime(){       //定时
        System.out.println("定时功能");
    }
}

1~18行定义的一个名为WashMashine的,里面包含类的成员属性和成员方法。

2~4行类的成员属性,分别为所定义类的品牌、颜色和重量。

6~8行、10~12行、14~16行:三组均为所定义类里的成员方法。其内面语句作用分别为打印出“洗衣功能”、“脱水功能”和“定时功能”。

2.3 练习

2.3.1 定义一个狗类

public class Dog {
    public String name;
    public String color;
    //狗的属性
    
    public void barks(){    //狗叫行为
        System.out.println(color+name+"汪汪汪~~~");
    }
    
    public void wag(){      //狗的摇尾巴行为
        System.out.println(color+name+"摇尾巴~~~");
    }
}

2.3.2 定义一个学生类

public class Student {
    public String name;
    public String gender;
    public short age;
    public double score;
    
    public void DoClass(){
        System.out.println("按时上课,不要迟到,如果请假,及时去补");
    };
    
    public void DoHomeWork(){
        System.out.println("教务系统,完成作业,一旦拖沓,神仙难救");
    }
    
    public void Exam(){
        System.out.println("考试目的,了解学情,人人必考,暴露问题");
    };
}

注意

  • 一般一个文件只定义一个类
  • public修饰的类必须要和文件名相同
  • 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改。

3.类的实例化

3.1 什么是实例化

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

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

public class Main {
    public static void main(String[] args) {
        Dog dog1 = new Dog();  //通过new实例化对象
        dog1.name = "阿黄";
        dog1.color = "黑黄";
        dog1.barks();     //输出结果:黑黄阿黄汪汪汪~~~
        dog1.wag();       //输出结果:黑黄阿黄摇尾巴~~~

        Dog dog2 = new Dog();  //通过new实例化对象
        dog2.name = "赛虎";
        dog2.color = "棕黄";
        dog2.barks();     //输出结果:棕黄赛虎汪汪汪~~~
        dog2.wag();       //输出结果:棕黄赛虎摇尾巴~~~
    }
}

注意

  • new关键字用于创建一个对象的实例。
  • 可以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) {
        //构造三个日期类型的对象d1,d2,d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();

        //对d1,d2,d3的日期设置
        d1.SetDate(2024,3,19);
        d2.SetDate(2024,3,20);
        d3.SetDate(2024,3,21);

        //打印日期中的内容
        d1.PrintDate();
        d2.PrintDate();
        d3.PrintDate();
    }
}

以上代码定义了一个日期类,然后main方法中创建了三个对象,并通过Date类中的成员方法对对象进行设置和打印。

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

1.若形参名不小心与成员变量名相同:

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

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

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

一切让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.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.setDate(2024,3,20);
        d.printDate();
}

下图1:通过调试可以看到,被调用的方法地址均与被引用对象相同。 

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:java: 可能尚未初始化变量a

若要上述代码通过编译,非常简单,只需要在正式使用之前,给a设置一个初始值即可。但如果是对象:

public static void main(String[] args) {
        Date d = new Date();
        d.setDate(2024,3,20);
        d.printDate();
}

//代码可正常通过编译

需要调用之前写的setDate方法才能将具体的日期设置到对象中。

通过上述例子发现两个问题:

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

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

    public void printDate(){
        System.out.println(year+"/"+month+"/"+day);
    }

    public static void main(String[] args) {
        //此处创建了一个Date类型的对象,并没有显示调用构造方法
        Date d = new Date(2024,3,20);  //Date()方法被调用了
        d.printDate();  //输出  2024/3/20
    }
}

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

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 d1 = new Date();
        d1.printDate();  //输出  1900/1/1

        Date d2 = new Date(2024,3,20);
        d2.printDate();  //输出  2024/3/20
    }
}
}

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

5.如果用户没有显示定义,编译器会生成一份默认的构造方法,但其一定是无参的

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();  //输出  0/0/0
    }
}

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

6.构造方法中,可以通过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;
    }
}

注意:

1.this(...)必须是构造方法中的第一条语句:

2.不能形成环:

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

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

相关文章

CDNS PCIe VIP debug info

1. TLP payload的顺序是反向的,即大小端反的,比如下面的denalirc打印的信息看,pl是我们发TLP时的配置,Cfg才是真正的data顺序。 而seq写的时候如下:可以看到payload[2]时第三个8bit payload,但是我们是想配…

JS加密解密之应用如何保存到桌面书签

前言 事情起因是这样的,有个客户解密了一个js,然后又看不懂里边的一些逻辑,想知道它是如何自动拉起谷歌浏览器和如何保存应用到书签的,以及如何下载应用的。继而诞生了这篇文章,讲解一下他的基本原理。 渐进式Web应用…

UE5学习日记——蓝图节点前缀关键字整理

一、起因 节点如海,中英文翻译的时候还是有差别的,比如: 同一个中文,可能在英文里完全不同,连出现位置可能都不一样 附加 Attach Actor To Component(将Actor附加到组件)Append Array&#xf…

【竞技宝】DOTA2-PGL联赛:niu神无解 LGD2-0轻松击败DH

北京时间2024年3月26日,PGL联赛中国区的比赛在昨日正式打响,首日共进行了四场胜者组首轮的比赛,第四场比赛由LGD对阵DH。本场比赛,DH两局都在前中期和LGD有来有回,但niu的中期节奏完全摧毁了DH,最终LGD2-0轻松击败DH。以下是本场比赛的详细战报。 第一局: 首局比赛,LGD在天辉方…

Python Flask框架 -- flask-migrate迁移ORM模型

# 之前使用的这个db.create_all()很有局限性,它不能把在class里修改的东西同步上数据库,所以不用了 # with app.app_context(): # 请求应用上下文 # db.create_all() # 把所有的表同步到数据库中去 例如,在User类中增加一个email字段&…

selenium自动化测试-unittest框架

unittest框架的优点 (1)能够组织多个用例去执行 (2)提供丰富的断言方法 (3)能够生成测试报告 unittest框架的核心要素 1. TestCase测试用例 TestCase(测试用例),最小的测试单元,创建的测试类需要继承该基类 步骤: (1&#x…

Vue2(十一):全局事件总线、消息订阅与发布pubsub、TodoList的编辑功能、$nextTick、过渡与动画

一、全局事件总线 1、思路解析 一种组件间通信的方式,适用于任意组件间通信。通俗理解就是一个定义在所有组件之外的公共x,这个x可以有vm或vc上的同款$on、$off、$emit,也可以让所有组件都访问到。 第一个问题:那怎样添加这个x才…

代码随想录学习Day 18

530.二叉搜索树的最小绝对差 题目链接 讲解链接 思路:利用二叉搜索树的性质,其中序遍历序列是一个有序数组。所以先对二叉搜索树进行中序遍历,得到一个递增的数组后,再遍历整个数组,依次求相邻值的差,最…

java算法汇总(蓝桥常用-->自总版)(更新中...)

这里写目录标题 1.递归求n的阶乘2.互质3.例题:奇妙的数字两个数字拼接String.toCharArray()方法String.valueOf()方法 4.例题:美丽的2String.contains()方法 5.ASCII码---a,A,0的转换6.String[] a---->求sum(a[p].charAt(q))-0;7.复数BigInteger 大整数类型本题用到的方法--…

【SSH配置公钥私钥免密登录】

SSH配置公钥私钥免密登录 SSH的安全机制一、修改远程主机ssh设置二、在windows客户端生成公钥私钥文件三、将客户端公钥追加到远程主机 .ssh/authorized_keys中参考链接 SSH的安全机制 SSH之所以能够保证安全,原因在于它采用了非对称加密技术(RSA)加密了所有传输的…

28---Nand Flash电路设计

视频链接 Nand flash电路设计01_哔哩哔哩_bilibili NAND FLASH电路设计 1、NAND FLASH介绍 Nand-flash内存是flash内存的一种,其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案。Nand-flash具有容量较大,改写…

【GPT5】牛!用ChatGPT搞科研,1天顶替博士辛苦研究3个月......

一、GPT的意义 随着人工智能技术的飞速发展,特别是ChatGPT、GPT-4等大型语言模型以及Midjourney、StableDiffusion等AI绘图工具的问世,我们已经进入了所谓的AI 2.0时代。这一时代的标志性特征是AI技术不仅在复杂性和功能性上取得了巨大进步,…

【PyQt】18 -菜单等顶层操作

顶层界面的使用 前言一、菜单栏1.1 代码1.2 运行结果 二、工具栏2.1 代码几种显示方法 2.2 运行结果 三、状态栏3.1 代码3.2 运行结果 总结 前言 1、介绍顶层菜单栏目的使用,但没有陆续绑定槽函数。 2、工具栏 3、状态栏 一、菜单栏 1.1 代码 #Author &#xff1a…

华为防火墙二层墙(VAN/SVI/单臂路由)

二层墙只能做地址池形式的NAT。 交换机安全策略防火墙二层墙 路由器安全策略防火墙三层墙 交换机的光口是不能直接插线的,光模块,包括进和出 长距离:单模 短距离:多模 防火墙自身的ping流量需要单独配置

畅捷通T+ Ufida.T.DI.UIP.RRA.RRATableController 远程命令执行漏洞

一、漏洞信息 漏洞名称:畅捷通T+ Ufida.T.DI.UIP.RRA.RRATableController 远程命令执行漏洞 漏洞类别:远程命令执行漏洞 风险等级:高危 二、漏洞描述 畅捷通TPlus适用于异地多组织、多机构对企业财务汇总的管理需求;全面支持企业对远程仓库、异地办事处的管理需求;全…

期货开户交易领域的认知偏差

在交易领域,目前存在以下几种认知偏差问题,看看你中了其中几条: 1、认为不亏钱比赚钱更为重要 对于绝大多数人来说,盈利要比亏损更受欢迎,从纯粹的理论上来说,每赚到100元和亏了100元是相同的&#xff0c…

Cadence——导出BOM清单

首先使用Allegro PCB Designer打开xxx .brd PCB制板文件 如下图,然后点击Tools–>Quick Reports,再选择Bill of Material Report或者Bill of Material Report(Condensed),这两个的区别就是上面的导出的BOM物料清单中相同的器件是不会合并的…

VUE之首次加载项目缓慢

最近公司有个大型的项目,使用vue2开发的,但是最终开发完成之后,项目发布到线上,首次加载项目特别缓慢,有时候至少三十秒才能加载完成,加载太慢了,太影响用户体验了,最近研究了一下优…

Server-u配置FTP 多用户访问多目录图解

目录 一、 本案例目录环境 二、实现目标 三、实现方法 1、新建ftp域名 2、目录设置 3、用户创建 上篇文章【Server-U搭建FTP共享文件】很多朋友都私信我,希望深入了解Server-U的多用户设置,因此对多用户的访问设置进行了如下的总结。 一、

奥比中光深度相机(一):环境配置

文章目录 奥比中光深度相机(一):环境配置简介电脑环境SDK配置步骤安装环境依赖填写路径,点击Configure选择Visual studio点击Generate完成基于Python的SDK配置方法一:使用Cmake直接打开方法二:通过源文件打…