【JavaSE】类与对象

前言

Java是一门纯面向对象的语言,在面向对象的世界里,一切都为对象。它是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。类与对象是我们学习面向对象最基础的知识,是面向对象实现的基石,可见它是有多么重要

1. 面向对象的含义

面向对象是一种编程思想,与之相对的还有面向过程,我们就拿炒菜这件事来解释一下这两者之间的区别

面向过程:准备食材 — 打开油烟机 — 热锅加油 — 油热放入食材翻炒 — 加入调味品 — 出锅

面向对象:食材、自动炒菜机、人、调味品,由这几个对象,我们就能完成炒菜这一件事

在这个例子中,我们能够看出来面向过程跟面向对象,是两种不同的思维方式,处理问题的思考的角度不一样。面向过程中,我们注重的是炒菜这个过程是如何进行的;但在面向对象中,我们只需要注重完成炒菜需要哪些对象,通过对象之间的交互来完成,将它们组合在一起就行,完全不需要管具体的实现过程

在Java中,一切皆对象,一切都围绕对象进行,我们只需要关心找对象、建对象,用对象等

2. 类的定义和使用

类:是用来对一个物体的属性和功能进行描述的。像生活中我们经常使用的手机,在Java中就可以看成一个类,手机品牌,型号,外观,材料都是它的属性;而打电话,上网,刷视频就是它的功能;这样我们就可以在Java中创建一个手机类

对象:某个类的一个实体。我们可以用手机类创建出一部华为手机,此时这部手机就可以称之为一个对象,创建好了对象后,我们就可以来操作手机的属性和功能

2.1 类的定义格式

// 创建类
class ClassName{
    field;  // 成员变量/字段/属性
    method; // 成员方法/行为
}
  • class是定义类的关键字,ClassName是类的名字,可以根据需求自己命名,取的尽量要有意义
  • 类中包含的内容称为类的成员,成员变量是用来描述类的,成员方法是用来说明类具有哪些功能

注意事项:

  1. 类名要采用大驼峰单词命名法,即每个单词的首字母都要大写
  2. 一个源文件中只能存在唯一一个主类(用public修饰的类)
  3. 类的成员变量都有默认值:引用数据类型为null,基本数据类型为各自的0值,boolean类型为false

2.2 类的实例化

类的实例化指的就是用类创建对应的对象,在Java中我们采用new关键字,配合类来实例化对象

类名称 引用名称 = new 类名称( )
例如:
Person person = new Person( );

在上面的例子中,我们使用Person这个类创建了一个person对象,要注意的是,所有类的对象都是引用数据类型。所以person就是引用变量,变量名可以根据自己的需求命名

我们可以把上面的例子再扩充一下,想一下人会有什么属性,有什么行为?

class Person{
    //成员变量
    String name;   //姓名
    int age;       //年龄
    String gender; //性别

    //成员方法
    void run(){
        System.out.println(name+"在跑步~~~");
    }

    void print(){
        System.out.println("姓名:"+name+" 年龄:"+age+" 性别:"+gender);
    }
}

public class Test {
    public static void main(String[] args) {
        //创建一个实例化对象
        Person A = new Person();
        //通过对象来给对象的成员变量进行赋值,并使用成员方法
        A.name = "小A";
        A.age = 18;
        A.gender = "男";
        A.print();
        A.run();
        System.out.println("=========");
        //创建对象后不给成员变量赋值
        Person B = new Person();
        B.print();
    }
}

输出结果如下:

我们可以用一个图来理解上面的代码

从上面的例子中可以看到:在创建好类后,我们可以通过new来实例化多个对象,使用“对象名.”给成员变量一一赋值,也可以调用类中的成员方法实现各种功能;当我们没有初始化对象时,成员变量都会有各自类型对应的默认值

2.3 类和对象的关系

我们可以把类看成一张产品设计图,在设计图上面有产品的各种属性,还有产品附带的各种功能

有了设计图,我们就可以根据设计图生产大量产品,生产出来的产品也附带有各种功能

这种拿产品设计图来生产产品就等同于类实例化对象,一个类可以实例化出多个对象,而且实例化出来的对象也要占据内存空间,用来存储各自的成员变量

补充说明

下图展示的就是创建对象以及使用对象在计算机中的执行原理

从图中我们可以得知:

  • 我们创建出来的对象在栈内存当中,变量里面记住的是对象的地址
  • 每次new对象,就是在堆内存中开辟一块内存区域代表一个对象
  • 类存在于方法区中

3. this关键字

3.1 什么是this

this就是一个变量,可以用在方法中,来拿到当前对象;哪个对象调用方法,this就指向哪个对象,也就是拿到哪个对象。我们来看一下具体的例子

class Student {
    public void printThis() {
        System.out.println(this);
    }
}

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student);
        student.printThis();
    }
}

在上面的代码中,我们创建了一个学生类,并在里面定义了printThis方法,打印this的值;在Test主类中我们new了一个学生对象student,直接打印了student,同时也调用了printThis方法。

在前面我们有讲到“创建出来的对象在栈内存当中,变量里面记住的是对象的地址”,那现在student里面装的就是对象的地址,我们来看一下运行结果

通过结果我们可以看到:student和this打印出来的结果一模一样,都是对象的地址,也就是说:this指向的就是对象,它就是对象在方法中的分身

3.2 this有什么作用

  • this主要用来解决:变量名称的冲突问题

我们还是用上面的学生类来举例子,假设有一个学生,他在一次考试中考了59分,而及格分数要求不小于60分,我们用代码来实现一下这个情景

class Student {
    double score;

    public void printfPass(double score) {
        if(score >= score) {
            System.out.println("通过考试~~~");
        } else {
            System.out.println("考试不及格~~~");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.score = 59;      //考试成绩
        student.printfPass(60);  //及格分数
    }
}

运行结果如下

为什么会出现这种情况呢?

原因在于:我们的成员变量名和方法的形参名相同,导致考试成绩59压根就没有进入到方法里,本质上是及格分数60分在自己和自己比较,60肯定是不小于60,故输出“通过考试~~~”

因此,我们需要在第一个score前面加上“this.”,这样就是避免变量名冲突产生的问题

class Student {
    double score;

    public void printfPass(double score) {
        if(this.score >= score) {  //第一个score前面加上this.
            System.out.println("通过考试~~~");
        } else {
            System.out.println("考试不及格~~~");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.score = 59;      //考试成绩
        student.printfPass(60);  //及格分数
    }
}

这就是this引用所发挥的作用,除了this引用成员变量外,this还可以引用成员方法。当我们创建多个对象后,它们要使用同一个方法时,就可以在前面加上this引用,这样可以让编译器知道是哪个对象调用的方法

总结一下:

  1. this就是一个变量,它指向的就是对象,它就是对象在方法中的分身
  2. this只能在成员方法中使用,不能再类(用static修饰的)方法中使用——这个在后面我们会详细讲解
  3. 在成员方法中,this只能引用当前一个对象
  4. 我们在写代码的过程中要习惯性地加上this,这样可以避免访问冲突的问题,减少不必要的麻烦

4. 构造方法

在前面的学习中,我们明白了如何去创建一个对象,但是在初始化对象的时候,我们使用对象引用成员变量一个一个初始化的,这未免有些麻烦

//创建一个实例化对象
Person A = new Person();
//通过对象来给对象的成员变量进行赋值,并使用成员方法
A.name = "小A";
A.age = 18;
A.gender = "男";
A.print();
A.run();

哎,这时候,构造方法就能发挥作用了

4.1 构造方法的定义

构造方法,也叫做构造器。它是一种特殊的成员方法,它可以帮助我们更加方便地去初始化对象。而且构造方法的名字必须跟类名一样,我们在使用new创建对象时,实际上就是调用了当前类的构造方法。下面就是一个Student类的构造方法

class Student {
    double score;

    //构造方法
    public Student(double score) {
        this.score = score;
    }
}

4.2 构造方法的语法规则

  1. 方法名和类名完全相同
  2. 构造方法没有返回值(也不能写void)
  3. 在一个类中至少存在一个构造方法,如果没有显示定义,那么编译器就会生成一个默认的无参构造
  4. 构造方法可以重载(我们可以根据需求来创建不同参数的构造方法)
class Student {
    String name;
    int age;
    String gender;

    //编译器默认给的无参构造方法
    public Student() {

    }

    //自己创建的有参构造方法
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}
public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        Student student1 = new Student("张三",19,"男");
    }
}

通过构造方法,我们就可以在创建对象的时候边给它赋值,省去了一个一个变量赋值的麻烦

如果我们不自己定义构造方法,那么编译器就会生成一份默认的无参构造方法,但如果我们自己定义了构造方法,编译器就不会生成了,说白了就是“救急不救穷”

4.3 构造方法的重载

关于构造方法的重载,我们得先来认识什么是重载?

重载:就是方法名称相同,但是参数列表不相同(顺序、个数、类型)的情形,这样的同名不同参数的方法之间,就称之为方法的重载

//编译器默认给的无参构造方法
public Student() {

}

//自己创建的有参构造方法
public Student(String name, int age, String gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

重载的好处在于:它方便了程序员可以根据不同的参数顺序、个数、类型来自动匹配方法,减少写多个方法名的重复步骤。所以我们在创建对象时,可以根据需要选择是否要初始化对象

小技巧

在idea中,它给我们提供了快速生成构造方法的途径

这样就能让idea自动帮你生成有参构造方法啦

5. 封装

封装是面向对象的三大特征之一,其余两项分别是继承和多态,今天我们着重讲一下封装

5.1 封装的定义

封装:就是当我们用类去设计对象去处理某一个事物的数据时,应该把要处理的数据,以及处理数据的方法,设计到应该对象中去。简单来说——将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互,就是封装

5.2 封装的设计规范

合理隐藏、合理暴露。我们在设计封装的时候要牢记这“八字真言”。就像一辆汽车,它的内部是由很多成员的,比如发动机、油箱等器件,汽车设计者会用外壳把这些内部元器件都隐藏起来,只暴露出方向盘、刹车、油门这些器件供司机使用。这就是所谓的合理隐藏、合理暴露

5.3 设计封装的示例

如果我们想要公开成员,可以使用public来修饰,如果想要隐藏成员,可以使用private来修饰

我们可以发现,成员变量name是用public修饰的,那在我们创建好student对象后,可以用对象引用直接调用它并赋值;而成员变量age是用private修饰的,我们用同样的方法却会报错。这是因为,public是公开的,面向任意包的任意类;而private就只能在当前类使用

如果我们就是想要调用成员变量age,那要怎么做呢?

我们可以在Student类里定义getAge和setAge方法,用来得到age和给age赋值。这两个方法使用public修饰的,相当于age的经纪人,它们可以让对象间接的接触到age,这样就能解决上面的问题了。而成员方法也是同理,用public就表示公开,用private就表示隐藏

在一般情况下,我们会将成员变量设置为private,成员方法设置为public。诚然,实际情况还得根据业务需求来定,这里只是提供参考

小技巧

在idea中,它也给我们提供了快速get和set方法的途径

这样就能让idea自动帮你生成get和set方法啦

结语

今天我们一起学习了Java当中的类与对象,还讲解了this关键字、构造方法以及封装的知识,希望大家能喜欢这篇文章,有总结不到位的地方还请多多谅解,若有出现纰漏,希望大佬们看到错误之后能够在私信或评论区指正,博主会及时改正,共同进步!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

打破数据孤岛,TDengine 与 Tapdata 实现兼容性互认证

当前,传统行业正面临着数字化升级的紧迫需求,但海量时序数据的处理以及数据孤岛问题却日益突出。越来越多的传统企业选择引入时序数据库(Time Series Database,TSDB)升级数据架构,同时,为了克服…

cesium 动态立体墙效果

cesium 动态立体墙效果 以下为源码直接复制可用 实现效果 实现思路 通过修改“material”自定义材质实现动态效果 核心类(WallImageTrailMaterialProperty)自定义材质 class WallImageTrailMaterialProperty {constructor(options) {this

推荐一款好用的前端分页插件jqPaginator

jqPaginator 简洁、高度自定义的jQuery分页组件,适用于多种应用场景。 现在网上各种各样的分页组件很多,但是很难找到十分“称心如意”的,于是jqPaginator诞生了。 我心中理想的分页组件,要不受CSS框架限制,可以使用…

汽车电子零部件(6):DMS/OMS、CMS

前言: 有一个部件过去不曾有,而如今有可能要标准化标配化,那就是Driver Monitoring System (DMS)驾驶员监控系统、Occupant Monitoring System (OMS)乘客监控系统和Camera Monitor System(CMS)摄像头监控系统。 汽车视觉技术的创新推动先进驾驶辅助系统的变革(ADAS),并…

力扣39. 组合总和

Problem: 39. 组合总和 文章目录 题目描述思路及解题方法复杂度Code 题目描述 思路及解题方法 该问题是组合问题的一个变体,可以归纳为元素无重复可复选问题,其代码的实现几乎和组合问题一模一样,由于在组合问题中我们只需要利用一个变量在递…

汽车电子与软件架构概述

汽车电子与软件架构概述 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣扎,出门靠自己…

C语言 数据在内存中的存储

目录 前言 一、整数在内存中的存储 二、大小端字节序和字节序判断 2.1.练习一 2.2 练习二 2.3 练习三 2.4 练习四 2.5 练习五 2.6 练习六 三、浮点数在内存中的存储 3.1 浮点数存的过程 3.2 浮点数取的过程 总结 前言 数据在内存中根据数据类型有不同的存储方式,今…

jvm调优实战操作

1.什么是jvm jvm就是lava虚拟机,他是java运行环境的一部分,它虚构出来的一台计算机,在通过在实际的计算机上仿真模拟各种计算机功能来实现Java应用程序,有JVM从软件层面屏蔽了底层硬件、指令层面的细节让他兼容各种系统 2.我们调…

【matlab】如何批量修改图片命名

【matlab】如何批量修改图片命名 (●’◡’●)先赞后看养成习惯😊 假如我的图片如下,分别是1、2、3、4、5的命名 需求一:假如现在我需要在其后面统一加上_behind字符串,并且保留原命名,同时替换掉原先的图片,也就是不copy新的一份,直接在原文件夹中处理,我们可以进行…

设计模式 — — 单例模式

一、是什么 单例模式只会在全局作用域下创建一次实例对象,让所有需要调用的地方都共享这一单例对象 二、实现 // 单例构造函数 function CreateSingleton (name) {this.name name;this.getName(); };// 获取实例的名字 CreateSingleton.prototype.getName func…

MyBatis是纸老虎吗?(三)

上篇文章——《MyBatis是纸老虎吗?(二)》——梳理了MyBatis的执行流程,这篇文章想详细聊聊MyBatis的解析过程。当我把这个想法讲个同事时,他不可置信的说道:“这有什么好梳理的?难道你要介绍xml…

WorkPlus Meet局域网视频会议软件的领先解决方案

局域网视频会议软件在现代企业中发挥着重要的作用,而在众多选项中,为何选择WorkPlus Meet作为局域网视频会议软件? 选择局域网视频会议软件时需要考虑到企业的需求。WorkPlus Meet提供了稳定、高效的局域网视频会议功能,能够满足…

粤嵌6818嵌入式开发入门教程

学习目标 1.了解嵌入式开发 2.开发环境的搭建 3.Linux操作系统的基本操作 一、了解嵌入式开发 以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 1.嵌入式可以干…

面部表情参考图

创造表情形变 | Character Creator | Reallusion 皮笑肉不笑?读取情绪的AI说:我太难了_面部

Vue.js+SpringBoot开发农家乐订餐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户2.2 管理员 三、系统展示四、核心代码4.1 查询菜品类型4.2 查询菜品4.3 加购菜品4.4 新增菜品收藏4.5 新增菜品留言 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的农家乐订餐系统&#xff0c…

详细分析Java中的BeanCopier属性复制(附Demo)

目录 前言1. 基本知识2. 同属性Demo3. 不同属性Demo4. 实战场景 前言 基本知识推荐阅读: 浅拷贝和深拷贝的深度理解java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)【Java项目】实战CRUD的功能整理(持续更新&…

PHP魔术方法详解

php魔术方法是一些特殊的方法&#xff0c;由特定的环境来进行触发。 这些魔术方法让开发者能够更好地控制对象的行为&#xff0c;特别是在处理不常见的操作或者需要自动化处理某些任务时非常有用。 1、_construct()构造函数&#xff1a; <?php highlight_file(__FILE__);…

小白DB补全计划Day1-LeetCode:SQL基本操作select

前言&#xff1a;找工作&#xff08;主人&#xff09;的任务罢了 链接&#xff1a;1757. 可回收且低脂的产品 - 力扣&#xff08;LeetCode&#xff09; 584. 寻找用户推荐人 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 对DB篇的SQL章不太知道怎么写…

2023年蓝桥杯省赛——幸运数字

目录 题目链接&#xff1a;0幸运数字 - 蓝桥云课 (lanqiao.cn) 解法 思路 高级思路 总结 题目链接&#xff1a;0幸运数字 - 蓝桥云课 (lanqiao.cn) 解法 首先是我写了差不多一个小时的解法&#xff0c;裂开了&#xff0c;为什么我如此废物 思路 寻找第2023个在二进制、八…

每日一题——LeetCode2789.合并后数组中的最大元素

方法一 倒序遍历&#xff1a; 将数组倒序过来看&#xff0c;就是从最后一个数开始&#xff0c;如果它前面一个数小于等于它就可以把前面一个数吃掉同时加上前一个数的值形成一个新的数&#xff0c;如果碰到一个更大的数就吃不动了&#xff0c;那么就换那个更大的数去继续吃前面…