【JavaSE】类和对象——上

news2024/11/28 22:56:48

文章目录

  • 1. 类的定义
    • 1.1 什么是类
    • 1.2 如何定义类
  • 2. 类的实例化
  • 3. this关键字
    • 3.1 this访问成员变量和成员方法
    • 3.2 构造方法及this()
      • 我们给类初始化的方法有:
      • 3.2.1 就地初始化
      • 3.2.2 使用 set 方法赋值
      • 3.2.3 使用构造方法
  • 4. 如何便捷的打印对象中属性

1. 类的定义


1.1 什么是类

类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性,哪些功能(用来干啥)。同时类是用户自定义的数据类型,包括属性和行为。在类里方法外定义的属性和方法分别称为成员变量和成员方法。


1.2 如何定义类

在这里插入图片描述
当然 class 前也可以加修饰访问限定符,并且一个 java 文件中只能有一个被 public 修饰的类我们这里先不用管。

class Dog {
	 //狗的属性
    public String name;
    public int age;
    public String variety;
    //狗的行为
    public void bark() {
        System.out.println("汪汪汪");
    }
}

在上面的狗类中,狗有名字、年龄、品种等属性,也会执行叫等行为。

注意:

  1. 一个 java 文件中最好只定义一个类,但为了方便讲解本章节我们写在一起。
  2. 先不用管 public 是什么意思照着写先,后面会讲解。

2. 类的实例化


  1. 定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型。
  2. 用类类型创建对象的过程,称为类实例化,在 java 中通过 new 关键字来实例化对象
  3. 类就相当于一个模板,通过这个模板可以实例化出多个对象。如我们定义了一个狗类我们就可以通过这个狗类实例化出多个狗对象,如二哈、中华田园犬、金毛等等。

在这里插入图片描述

实例化方法:
在这里插入图片描述
这里的类名是一个自定义数据类型,也可看成 类类型 变量 = new 类类型()

如我们对上面的狗类进行实例化,一个 java 文件最好只定义一个类,但为了方便讲解我们写在一起。

class Dog {
    public String name;
    public int age;
    public String variety;

    public void bark() {
        System.out.println("汪汪汪");
    }
    //打印
    public void print() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",种类:" + variety);
    }

}
public class TestDemo1 {
    public static void main(String[] args) {
        Dog dog1 = new Dog();//实例化对象,存放地址的变量叫引用
        dog1.name = "小毛"; //通过 引用.属性 访问进行赋值
        dog1.age = 4;
        dog1.variety = "哈士奇";
        dog1.print();
        dog1.bark(); //通过 引用.方法 进行访问

        Dog dog2 = new Dog();
        dog2.name = "土狗";
        dog2.age = 5;
        dog2.variety = "中华田园犬";
        dog2.print();
        dog2.bark();
    }
}

在这里插入图片描述通过上面我们可以看出,一个类可以实例化出多个对象,它们的品种、姓名等不一样。

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

当实例化一个对象时,会在堆中先开辟一块内存空间,我们画出上面的两个对象内存的分布。
在这里插入图片描述
dog1 和 dog2 引用存放的是对象的地址

以下语句中 dog5 = dog1; 代表什么:

class Dog {
    public String name;
    public int age;
    public String variety;

    public void bark() {
        System.out.println("汪汪汪");
    }
    //打印
    public void print() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",种类:" + variety);
    }

}
public class TestDemo1 {
    public static void main(String[] args) {
        Dog dog1 = new Dog();//实例化对象,存放地址的变量叫引用
        dog1.name = "小毛"; //通过 引用.属性 访问进行赋值
        dog1.age = 4;
        dog1.variety = "哈士奇";
        Dog dog5 = new Dog();
        dog5 = dog1; //dog5这个引用 指向/引用了 dog1 引用所指向/引用的对象
    }
}

就是 dog5 存放了 dog1 引用 所引用对象的地址,即 dog5 和 dog1 存放一样的地址。

当我们没有赋值时,打印成员变量时,打印的是其类型对应的 0 值。引用类型是 null, boolean类型是false

class Dog {
    public String name;
    public int age;
    public String variety;

    public void bark() {
        System.out.println("汪汪汪");
    }
    public void print() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",种类:" + variety);
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
		Dog dog3 = new Dog();
        dog3.print();
}

在这里插入图片描述


3. this关键字


3.1 this访问成员变量和成员方法

当我们想要实现一个日期类时。

class MyDate {
    public int year;
    public int month;
    public int day;
    //通过setMyDate()方法赋值
    public void setMyDate(int myYear, int myMonth, int myDay) {
        year = myYear;
        month = myMonth;
        day = myDay;
    }
    public void print() {
        System.out.println(year + "年" + month + "月" + day + "日");
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        MyDate date = new MyDate();
        date.setMyDate(2022, 11, 5);
        date.print(); //通过print方法打印
    }
}

在这里插入图片描述

那当我们把 setMyDate() 方法改成以下后。

    //通过setMyDate()方法赋值
    public void setMyDate(int year, int month, int day) {
        year = year;//形参等于形参
        month = month;
        day = day;
    }

这个方法中,year = year 的意思是形参等于形参,并没有对该对象的属性进行赋值。

在这里插入图片描述

当我们使用 this 引用访问时可以避免此问题。

class MyDate {
    public int year;
    public int month;
    public int day;
    //通过setMyDate()方法赋值
    public void setMyDate(int year, int month, int day) {
        this.year = year; //访问成员变量
        this.month = month;
        this.day = day;
        this.print(); //访问成员方法,打印
    }
    public void print() {
        System.out.println(year + "年" + month + "月" + day + "日");
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        MyDate date = new MyDate();
        date.setMyDate(2022, 11, 5);
    }
}

在这里插入图片描述



1. this代表当前对象的引用。即谁调用就是谁的对象属性。
如: 在这里插入图片描述当前 this.year 即为 date.year

如果再加以下语句

MyDate date2 = new MyDate();
date2.seMyDate(2014, 11, 11);

此时的 this.year 相当于 date2.year。


2. this.成员变量/方法,只能在方法中使用,但不能在静态方法中使用

3. 在类的方法中,属于该类的属性最好在前面加 this ,用来防止形参和成员变量冲突时,没有赋值上。

package testdemo1;

class MyDate {
    public int year;
    public int month;
    public int day;
    //通过setMyDate()方法赋值
    public void setMyDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        this.print();
    }
    public void print() {
        System.out.println(this.year + "年" + this.month + "月" + this.day + "日");
    }

}
public class TestDemo2 {
    public static void main(String[] args) {
        MyDate date = new MyDate();
        date.setMyDate(2022, 11, 5);
    }
}

4. this 实际上是一个隐式的参数。
我们进行调试
在这里插入图片描述实际上是长这个样子的:
在这里插入图片描述

在这里插入图片描述

java编译器给每个“成员方法“增加了一个隐藏的引用类型参数,该引用参数指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问 。只不过所有的操作对用户是透明 的,即用户不需要来传递,编译器自动完成

总结:

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


3.2 构造方法及this()

我们给类初始化的方法有:

3.2.1 就地初始化

class Student {
    public String name = "张三";
    public int age = 20;
    public String sex = "男";
    public int score = 99;
    public void doClass() {
        System.out.println(this.name + "正在上课");
    }
}

这样的初始化方式不好。

3.2.2 使用 set 方法赋值

在讲 this.访问成员变量和成员方法时说过,可以往回看。


3.2.3 使用构造方法

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。

1. 构造方法使用方法:
在这里插入图片描述

当我们实例化一个对象时需要:(必须有这两步,但不一定只有这两步)

  1. 为对象分配内存
  2. 调用合适的构造方法 (说明一个类中可以多个构造方法)

在这里插入图片描述

那么问题来了,之前我们没有调用构造方法为什么没报错呢?
那是因为当我们不写构造方法时,编译器会默认帮我们生成一个不带参数的构造方法。
当我们写构造方法后,编译器就不会帮我们提供不带参数的构造方法

在这里插入图片描述
2. 当类中有多个构造方法时。

package testdemo1;

class Student {
    public String name;
    public int age;
    public String sex;
    public int score;

    public Student() {
        System.out.println("不带参数的构造方法");
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("带2个参数的构造方法");
    }

    public Student(String name, int age, String sex, int score) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.score = score;
        System.out.println("带4个参数的构造方法");
    }

    public void doClass() {
        System.out.println(this.name + "正在上课");
    }
}
public class TestDemo3 {
    public static void main(String[] args) {
        Student student1 = new Student();//调用不带参数的构造方法
        
        Student student2 = new Student("张三", 22, "男", 99);//调用带四个参数的构造方法
    }
}

我们可以看到当有多个构造方法时,调用合适的构造方法

在这里插入图片描述

3. 使用 this() 调用本类中的其他构造方法

class Student {
    public String name;
    public int age;
    public String sex;
    public int score;

    public Student() {
        this("张三", 19); //调用带两个参数的构造方法
        System.out.println("不带参数的构造方法");
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("带2个参数的构造方法");
    }
}
public class TestDemo3 {
    public static void main(String[] args) {
        Student student1 = new Student();//调用不带参数的构造方法
    }
}

在这里插入图片描述在这里插入图片描述

4. 使用 this() 不能形成环

在这里插入图片描述

总结:

  1. 构造方法是没有返回值的方法,方法名和类名是一样的。
  2. 构造方法不止一个,可以有多个,多个构造方法之间,构成了重载。
  3. 当我们写了一个类之后,没有写构造方法的时候,编译器会帮我们默认生成一个不带参数的构造方法。
  4. 当我们写了任何一个构造方法之后,编译器不再为我们,提供不带参数的构造方法。
  5. 一个类至少会有1个构造方法就算你没有写。
  6. 构造方法本质就是来实例化对象的时候调用。1、分配内存2、调用合适的构造方法。
  7. this可以用来调用本类中其他的构造方法【构造方法当中使用】。必须放到第一行!!!所以,只能在当前构造方法当中,调用一个。

4. 如何便捷的打印对象中属性

当我们实例化对象后,想要打印该对象的属性时,可以这么写:

package testdemo1;

class Student {
    public String name;
    public int age;
    public String sex;
    public int score;
    public Student(String name, int age, String sex, int score) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.score = score;
        System.out.println("带4个参数的构造方法");
    }
    public void doClass() {
        System.out.println(this.name + "正在上课");
    }
    public void print() {
        System.out.println("[姓名:" + this.name
                            + ",年龄:" + this.age
                            + ",性别:" + this.sex
                            + ",成绩:" + this.score
                            + "]");
    }
}
public class TestDemo3 {
    public static void main(String[] args) {
        Student student2 = new Student("张三", 22, "男", 99);
        student.print();
    }
}

在这里插入图片描述
当然也可以在主方法利用 引用.成员变量 进行打印,这里就不写出了。

当我们直接使用 System.out.println(); 打印一个对象时:

class Student {
    public String name;
    public int age;
    public String sex;
    public int score;
    
    public Student(String name, int age, String sex, int score) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.score = score;
    }
    public void doClass() {
        System.out.println(this.name + "正在上课");
    }
}
public class Test1 {
    public static void main(String[] args) {
        Student student1 = new Student("张三", 22, "男", 99);
        System.out.println(student1);
    }
}

在这里插入图片描述

打印的是一个地址。我们跳转到 println 的源码看看

System.out.println(student1);
打印不同的东西 println() 采用不同的写法

在这里插入图片描述

  • 所以当我们想要打印成员属性时,通过对象的引用变量进行打印(System.out.println(student1);),我们可以自己在 Student 类中写一个 toString() 方法,编译器会调用类中的 toString() 方法,因为当打印 student1对象时,如果student1 不为 null ,编译器会在该对象中看看有没有 toString() 方法,有则调用,没有则默认调用上面说到的toString() 方法。

写法如下


class Student {
    public String name;
    public int age;
    public String sex;
    public int score;
    public Student(String name, int age, String sex, int score) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.score = score;
    }
    public void doClass() {
        System.out.println(this.name + "正在上课");
    }
    //toString()方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", score=" + score +
                '}';
    }
}
public class Test1 {
    public static void main(String[] args) {
        Student student1 = new Student("张三", 22, "男", 99);
        System.out.println(student1);
    }
}

在这里插入图片描述

idea可使用快捷键直接写出

在这里插入图片描述

那么当 Student student1 = null 时呢

在这里插入图片描述

在这里插入图片描述
打印的是 null。

好的,到这里本章节就结束了,如发现有错误,请各位大佬及时指出。

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

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

相关文章

【Pytorch Lighting】第 1 章:PyTorch Lightning adventure

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

数据中心通识

文章目录一 数据中心定义特点二 机房定义内部物品物理环境三 服务器定义外型分类与PC相比的优点超线程技术固态硬盘和机械硬盘四 网络定义OSI模型局域网的拓扑结构TCP/IP协议常见端口号IP地址介绍、格式、分类、子网掩码DNS三层交换机五 存储格式化缓存RAID技术存储体系架构IP-…

二叉树的前中后序遍历(递归与迭代)

作者:~小明学编程 文章专栏:Java数据结构 格言:目之所及皆为回忆,心之所想皆为过往 目录 简介 前序遍历 递归法 迭代法 中序遍历 递归法 迭代法 后序遍历 递归法 迭代法 简介 前面学习二叉树的时候,已经学过…

渗透测试 | 域名信息收集

0x00 前言 信息收集可以说是在渗透测试中最重要的一部分,上文对 IP 信息收集做了一个简要的叙述,认识了 CDN 技术和网络空间搜索引擎。但是很多网站的主站因为访问流量过大的原因通常会使用 CDN 技术,同时也可以有效防止 DDOS 攻击。在域名信…

前端面经 强缓存与协商缓存

前端面经 强缓存与协商缓存 图片多来自第三方平台 文章目录前端面经 强缓存与协商缓存适用场合浏览器缓存的过程缓存规则强缓存(本地缓存)协商缓存缓存分为两种:强缓存和协商缓存,根据响应的header内容来决定 获取资源形式状态码…

【C++】二叉搜索树

前言 hi~大家好呀,欢迎点进我的C学习笔记~ 我的前一篇C笔记链接~ 【C】多态_柒海啦的博客-CSDN博客 本篇需要用到的基础二叉树C语言实现链接~ 用c语言实现一个简单的链表二叉树_柒海啦的博客-CSDN博客_c语言建立二叉树链表 我们知道,查找一个数据会有很多…

数据库基本操作

目录 数据库操作 创建数据库 查看数据库 选择数据库 删除数据库 注释 数据表操作 创建数据表 查看数据表 查看数据表 查看数据表的相关信息 修改数据表 修改数据表名称 修改表选项 查看表结构 查看数据表的字段信息 查看数据表的创建信息 查看数据表结构 修…

linux进程间通信之共享内存

目录 一,共享内存原理 二,创建共享内存 1,shmget创建共享内存 2,shmat挂接共享内存 3,shmdt取消挂接共享内存 4,shmctl删除共享内存 三,代码使用 1,com.hpp 2,ipc_client.c…

Allegro基本规则设置指导书之Physical Region

Allegro基本规则设置指导书之Physical Region 下面介绍基本规则设置指导书之Physical Region 空白的地方创建一个Region 给新建的Region匹配一个规则,所有区域里面的Physical相关的都按照Region的规则来 当部分网络想按照本身的规则来匹配,可以创建region-Class 然后匹配…

目标检测算法——医学图像开源数据集汇总(附下载链接)

关注”PandaCVer“公众号 深度学习Tricks,第一时间送达 目录 1.血细胞图像数据 2.眼病深度学习数据集 3.皮肤病数据集 4.膝关节 X 射线图像数据集 小海带整理不易,小伙伴们记得一键三连喔!!! >>>一起交流…

VisualSVN 是 Visual Studio 的专业级 Subversion 集成插件

用于 Visual Studio 的 VisualSVN 专业且无缝的 Subversion 集成。 专业级 Subversion 集成 VisualSVN 是 Visual Studio 的专业级 Subversion 集成插件。 VisualSVN 的主要优点是: 无与伦比的可靠性: Visual Studio 永远不会因为 VisualSVN 而崩溃或挂…

保护鲸鱼动物网页设计作业 静态HTML宠物主题网页作业 DW鲸鱼网站模板下载 大学生简单动物网页作品代码 个人网页制作 学生个人网页

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

2022阿里云栖大会,顶尖科技趋势峰会和全链路元宇宙体验

2022年的11月3日-5日是阿里巴巴云栖大会的日子,地点在云栖小镇,本人有幸报名参加了5日那场,因为5日是周六。秉着打工人工作日需要搬砖,因为“公司离不开我”,哈哈哈,实际上是每天满满的工作量。所以只能选择…

一文彻底搞懂协程(coroutine)是什么,值得收藏

什么是协程 我们可以简单的认为:协程就是用户态的线程,但是上下文切换的时机是靠调用方(写代码的开发人员)自身去控制的。 同时,协程和用户态线程非常接近,用户态线程之间的切换不需要陷入内核&#xff0…

NYIST(计科ACMTC)第三次招新赛题解

A题 原文, 原比赛B题 牛客练习赛104【出题人题解】 - 知乎 直接输出 输入的数 就可以了 B题 C题 找到分别处理"无留陀的化身"坐标轴的x轴和y轴, 组合成无留陀的坐标, 再遍历求纳西妲的坐标, 相减即可 /* ⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿…

ROS小工具学习与使用

ROS小工具学习与使用 rqt的使用 rqt_bag工具 rqt_bag <your bagfile> #使用rqt_bag查看你的rosbag例如&#xff1a;可以查看第一帧GPS的rawdata信息&#xff0c;如下图&#xff1a; 参考文献&#xff1a; 1、http://wiki.ros.org/rqt_bag 2、rosbag与rqt_bag的常用 rq…

Nacos学习笔记

视频学习指路&#xff1a; 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 Nacos nacos注册中心的搭建 1.下载nacos的安装包&#xff0c;github地址&#xff1a;https://github.com/alibaba/nacos&…

Tkinter保姆级教程(上)

目录 什么是GUI Tkinter用法详解 第一个Tkinter程序 常用控件和属性 主窗口 Label标签控件 Button按钮控件 Entry输入控件 基本属性 Text 文本控件 列表框(ListBox)和组合框(Combobox) 单选框(Radiobutton)和多选框按钮(Checkbutton) 什么是GUI 图形用户界面&#x…

运算放大器正反馈负反馈判别法

---------------------------------------------------------------------------------------------------------------- 反馈可分为负反馈和正反馈。前者使输出起到与输入相反的作用&#xff0c;使系统输出与系统目标的误差减小&#xff0c;系统趋于稳定&#xff1b;后者使输出…

java面向对象(上)

一、java面向对象学习的三条主线1.java类以及类的成员&#xff1a;属性、方法、构造器&#xff1b;代码块、内部类。2.面向对象的三大特征&#xff1a;封装性&#xff0c;继承性&#xff0c;多态性&#xff0c;&#xff08;抽象性&#xff09;。3.其他关键字&#xff1a;this&a…