【Java 学习】初识类和对象、this引用
认识类和对象
- 1. 什么是面向过程?什么是面向对象?
-
- 1.1 面向过程
- 2.2 面向对象
- 1.2 优点和缺点
- 1.3 再谈 Java
- 2. 类和对象
-
- 2.1 什么是类?
- 2.2 什么是对象?
- 2.3 Java 中类的定义格式
- 2.4 使用类
- 2.5 类的实例化
- 3. this 关键字
-
- 3.1 引入 this
- 3.2 this 关键字
- 3.3 认识隐藏的 this
- 3.4 this引用的特性
1. 什么是面向过程?什么是面向对象?
1.1 面向过程
面向过程:侧重的是过程(比如,实现代码的详细步骤)
拿做饭举例:
这是一个传统的方式,你需要买菜、洗菜、洗锅、切菜等等,每个步骤都需要自己完成。
按照该种方式来写代码,将来扩展或者维护起来会比较麻烦。
2.2 面向对象
面向对象:侧重的是对象(比如,把机器人比作一个对象,你直接命令机器人,然后机器人进行工作,你不需要关注机器人内部的程序是怎么执行的)。
上述过程一共有四个对象:人,菜, 锅,火
以面向对象的方式处理:人,菜, 锅,火 四个对象交互完成的,人不需要关注机器人是怎么洗菜,开火的,点击机器人的做饭按钮,然后机器人就开始工作。
经典的例子:一次的春晚小品中宋丹丹曾说过一句话,把大象塞进冰箱只需要三步,打开冰箱,把大象塞进去,关冰箱门。
面向对象其实就是只使用,不关注使用过程。
1.2 优点和缺点
面向过程:
- 优点:简单易懂
- 缺点:代码扩展性差,维护成本高,代码复用率低。
面向对象:
- 优点:可扩展性非常强,维护成本低。
- 缺点:新手上手难
1.3 再谈 Java
Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。
2. 类和对象
2.1 什么是类?
同学们是否还记得 int
和 String
,其实 String
就是一个类
看一看这两者的初始化。
int n = 1;String s1 = \"Hello World !\"; String s2 = new String(\"Hello World !\");
是不是很相似呢?
类其实就相当于一个数据类型,只不过这个数据类型中包装了很多的方法和变量。String
类是一个简单的类,但是System
类是一个复杂的类,我们常用System.out.println()
来打印数据。
解释System.out.println()
:
- System:预定义的类,提供访问系统资源的方法。
- out:System 类的静态成员变量,也为 PrintStream类的对象,代表标准输出流。
- println():PrintStream 类的方法,用于在输出流中打印一行文本,并在末尾添加一个换行符。
PrintStream
和 out
有什么联系呢?
// 不用管括号里面是什么东西 PrintStream out = new PrintStream(System.out);
也就是说,out
是PrintStream
类的对象,printfln()
是对象out
的方法。
总之,类相当于是很多方法和变量的集合,但是类还有很其他的特性。
2.2 什么是对象?
类既然是数据类型,那么初始化类的时候就需要设置变量,类的变量名字叫做引用变量。
为什么叫做引用变量呢?
答:对象是类实例化出来的一块内存空间,引用变量储存的是对象的地址。
用String
类举例,我们new
出多个对象:
注: s1,s2,s3存储的是对应空间(对象)的引用,通过引用可以找到对象的地址。也就是说,通过 s1,s2,s3可以间接的找到对应的空间地址。
形象的说,类其实是房子的设计图,对象就是盖出的房子,引用变量就是存储盖出的房子的具体位置:
类是怎么定义的,对象就会有什么样的功能;换言之,设计图是怎么设计的,房子就会盖成什么样子。
2.3 Java 中类的定义格式
类的定义格式:
[修饰符] class 类名 { // 成员变量(属性) [修饰符] 数据类型 变量名; // 方法 [修饰符] 返回类型 方法名([参数列表]) { // 方法体 } }
图解:
类中的内容为成员,所以,变量称为成员变量、方法称为成员方法。
为什么说Java一切为类呢?
因为创建的任何java文件都 相当于是一个类。所有的代码(除了顶级类声明和导入语句)都必须放在类中。
创建一个以Dog
命名的文件:
当我们创建好后可以很容易得发现,Dog
是类的名字,这也是文件名为什么和第一个类名相同的原因。
2.4 使用类
创建一个Dog
类,然后定义属性和会做什么事。
换言之,就设计一个Dog
类,用成员变量存储狗的属性(如:毛色,体格大小,名字),用成员方法设计狗的会干什么事(如:会吃饭,会汪汪叫)。
示例:
public class Dog { // 狗的属性 public String name; //名字 public String color; //颜色 public String size; //大小 // 会汪汪叫 public void bark(){ System.out.println(\"汪汪~\"); } // 吃饭 public void eat(){ System.out.println(\"吃饭饭~\"); }}
图解:
这就是一个简单的类,里面包装的有成员变量和成员方法。
注意事项:
- 一般一个文件中只定义一个类
- main方法所在的类一般要使用
public
修饰(注意:Eclipse默认会在public修饰的类中找main方法) public
修饰的类必须要和文件名相同- 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改(给同学演示)。
2.5 类的实例化
定义了一个类,就相当于在计算机中定义了一种新的类型,与int
,double
类似,只不过int
和double
是 Java 语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:Dog
类。它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
怎么创建对象呢?
答:main
函数是程序的入口,需要写main
函数,在main
函数中创建对象。
示例:
public class Dog { // 狗的属性 public String name; public String color; public String size; // 会汪汪叫 public void bark(){ System.out.println(\"汪汪~\"); } // 吃饭 public void eat(){ System.out.println(\"吃饭饭~\"); } //程序的入口 public static void main(String[] args){ //创建对象,用dog1来接收 Dog dog1 = new Dog(); //设置属性 dog1.name = \"大黄\"; dog1.color = \"黄色\"; dog1.size = \"大\"; System.out.println(dog1.name+\" \"+ dog1.color+\" \"+ dog1.size); // 使用功能 dog1.bark(); dog1.eat(); }}
图解:
注:dog1,dog2 存储的是对应空间(对象)的引用,通过引用可以找到对象的地址。也就是说,通过 dog1,dog2 可以间接的找到对应的空间地址。
解释:
- new 关键字用于创建一个对象的实例。
- 引用变量用来存储对象的地址。
- 引用变量的名字 + ’ . ’ 来访问对象中的属性和方法。
- 同一个类可以创建多个实例。
总结,类实例化出来的是一块空间,也就是实体(对象),总要有一个标识符指定某个对象进而使用对象,即引用变量存储变量的地址(指定某个对象)。
3. this 关键字
3.1 引入 this
其实我们在类中创建的成员方法和普通的方法几乎一样,成员方法也可以传参,然后进行改变成员变量。
如果想用一个成员方法来改变狗的名,我们可以这样写:
public class Dog { // 狗的属性 public String name; public void alter_name(String name){ name = name; }// 程序的入口 public static void main(String[] args){ // Dog dog3 = new Dog(); dog3.name = \"小白\"; dog3.alter_name(\"白狗\"); System.out.println(dog3.name); }}
同学们可以猜一下打印的是什么?
其实,打印的是:小白。
这是为什么呢?
public void alter_name(String name){ name = name
这个方法的参数含有name
,但时会根据就近原则, name = name;
这行命令的name
都是方法的参数name
,而没有使用类的成员变量的name
。
如下:
public void alter_name(String name){ //参数 参数 name = name;
所以,没有修改类中成员变量的name
,有什么方法可以标明使用的是类的name
吗?
答: 当然有,使用this
关键字来区分成员变量和方法参数。
3.2 this 关键字
this关键字
也叫做this引用
指向当前对象(调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过这些操作没有显示的写出,不需要用户来传递,编译器自动完成。
那么怎么正确写修改姓名的成员方法呢?
答:用this
引用类的成员变量。
public void alter_name(String name){ //成员变量 参数 this.name = name; }
说明: this.name
是类的成员变量。name
是方法的参数。
全部的代码示例:
public class Dog { // 狗的属性 public String name; public String color; public String size; // 会汪汪叫 public void bark(){ System.out.println(\"汪汪~\"); } // 吃饭 public void eat(){ System.out.println(\"吃饭饭~\"); } public void alter_name(String name){ //成员变量 参数 this.name = name; } //程序的入口2 public static void main(String[] args){ // Dog dog3 = new Dog(); dog3.name = \"小白\"; dog3.alter_name(\"白狗\"); System.out.println(dog3.name); }}
3.3 认识隐藏的 this
日期类:
public class Date { public int year; public int month; public int day; public void setDay(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.setDay(2024, 12, 15); d2.setDay(2024, 12, 16); d3.setDay(2024,12,17); // 打印日期中的内容 d1.printDate(); d2.printDate(); d3.printDate(); }}
以上代码定义了一个日期类,然后main方法中创建了三个对象,并通过Date
类中的成员方法对对象进行设置和打印,代码整体逻辑非常简单,没有任何问题。
但是细思之下有个疑问:
三个对象都在调用setDate
和printDate
函数,但是这两个函数中没有任何有关对象的说明,setDate
和printDate
函数如何知道打印的是那个对象的数据呢?
this
引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
public class Date { public int year; public int month; public int day; public void setDay(Date this,int y, int m, int d){ this.year = year; this.month = month; this.day = day; }}public void printDate(){ System.out.println(this.year + \"/\" + this.month + \"/\" + this.day);}
注意:this引用的是调用成员方法的对象。
3.4 this引用的特性
- this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
- this只能在\"成员方法\"中使用
- 在\"成员方法\"中,this只能引用当前对象,不能再引用其他对象
- this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收在代码层面来简单演示—>注意:下图右侧中的Date类也是可以通过编译的