目录
一、什么是类,什么是对象
二、类和对象的关系
三、学习类和对象的目的
四、怎样创建一个类
4.1 语法形式
4.2 创建示例
示例一:日期对象
示例二:小狗对象
示例三:学生对象
4.3 注意事项
4.4 修改public修饰的主类名
示例一:Java文件中只有一个类
示例二:Java文件中有多个类
五、怎样示例化一个对象
5.1 语法格式
5.2 内存分析
5.3 对象的引用如何去访问非静态成员变量/方法
六、非静态方法中的隐藏参数this
6.1 问题引入
6.2 介绍this
6.3 this特性
七、非静态成员变量的初始化方式
方式一:就地初始化非静态成员变量
方式二:在方法中使用对象的引用初始化非静态成员变量(注意一下,非静态成员被什么修饰了)
方式三:自己写一个成员方法初始化非静态成员(这个成员方法得写成非静态的,不然初始化不了非静态的成员变量)
方式四:构造方法初始化非静态成员(一般采用这种方式初始化!!!,构造方法别用static修饰!!!)
方式五:构造代码块初始化非静态成员(后面会讲什么是Java中的代码块)
八、构造方法
8.1 概念
8.2 特点
九、写个代码简单总结一下
一、什么是类,什么是对象
一切实体皆可称为对象,例如:你、我、他、小狗、冰箱等。
类是用来描述对象的引用数据类型,它和C语言中的结构体类型类似。
二、类和对象的关系
① 类和int、double、boolean等一样,是一种数据类型,并不占用实际的内存空间。只有当用类实例化对象后,对象才会占用实际的内存空间,这些内存空间用于存放该对象的非静态成员变量。
② 一个类可以实例化多个对象。
三、学习类和对象的目的
学习类和对象的目的是为了更好的面向对象编程。
埋坑:什么是面向过程编程、什么是面向对象编程,它们分别有哪些特点和优缺点?
四、怎样创建一个类
4.1 语法形式
说明:
① 创建类要用到关键字class。
② 类名采用大驼峰的命名方式。
③ 类中一般会描述对象的两个方面:对象的属性 和 对象的行为(我们可以根据实际的需求自定义这两个方面是否写完整)。
4.2 创建示例
示例一:日期对象
class Date {
public int year;
public int month;
public int day;
public void setDate() {
System.out.println(year + "年" + month + "月" + day + "日");
}
}
示例二:小狗对象
class Dog {
public String name;
public int age;
public String color;
public void setDog() {
System.out.println(name + " " + age + " " + color);
}
}
示例三:学生对象
class Student {
public String name;
public int age;
public int classroom;
public void setStudent() {
System.out.println(name + " " + age + " " + classroom);
}
public void learn () {
System.out.println(name + " 正在学习...");
}
}
4.3 注意事项
0. Java文件名采用大驼峰的方式命名。
1. 此处先用采用public修饰成员变量和成员方法,各修饰限定符的具体作用后面会细致讲。
2. 类只能被public修饰或不被修饰,不被修饰的类只具有包访问权限。
3. 一个Java文件中最多只能有一个public修饰的类,这个类称为主类(除主类外,其他的类都不能被public修饰,否则会报错)。主类的类名要与Java文件名保持一致。
4. 通常在一个Java文件中我们只会写一个类。使用ideal创建一个Java文件后,编译器会在该Java文件中自动生成主类。
5. 不要轻易修改public修饰的主类的类名,如果非要修改,可以通过开发工具修改(具体操作见下面的4.4)。
6. 成员变量在没有初始化之前会有一个默认值(也就是说成员变量被直接使用时,不会因为未被初始化而报错,不过我们通常会在创建类时写构造方法去初始化成员变量):基本数据类型除boolean类型的变量默认值是false外,其余类型的变量默认值都是0值;引用数据类型的默认值都是null。
7. 关于main方法的补充说明:main方法是程序的入口,只能放在被public修饰的类中使用。main方法的书写规范:public static void main(String[] args) { //... };(为什么main方法要用static修饰?答:JVM在运行Java应用程序时,首先会调用main方法,调用时并不会自动实例化这个类的对象,而是通过类名直接调用main方法,因此需要用static修饰。)
4.4 修改public修饰的主类名
使用开发工具修改主类名称的注意事项:使用开发工具只能修改只存在一个类的Java文件中主类的名称,因为如果一个Java文件中有多个类,编译器不知道要改哪个类的类名(它并不会主动识别哪个是主类)。
示例一:Java文件中只有一个类
示例二:Java文件中有多个类
五、怎样示例化一个对象
5.1 语法格式
如果类被public修饰,则可以在任意的方法中,使用:类名 + 变量名 = new + 类名();即可创建一个对象。
如果类没有被任何修饰,则可以在该类所在的包下的任意方法中,使用:类名 + 变量名 = new + 类名();即可创建一个对象。
5.2 内存分析
上面代码在main方法中分别用new关键字实例化了两个Dog类型的对象,分别是dog1和dog2(它们是引用数据类型的变量,简称引用),它们里面存的是其所指向对象的地址,且dog1和dog2引用由于在方法中,故它们是局部变量,局部变量的内存在栈中开辟空间 (注意:成员变量和局部变量的生命周期、作用域是不同的)。Java中给对象所开辟的空间在堆区,用于提供对象存放非静态成员变量的数据。每个对象都有自己独有的非静态成员变量,但并没有自己独有的成员方法,因为方法是用来调用的,并不需要开辟空间存放。综上有了如下所示的内存分布。
5.3 对象的引用如何去访问非静态成员变量/方法
对象的引用+(.)+非静态的成员变量/方法。
六、非静态方法中的隐藏参数this
6.1 问题引入
问题一:在上文5.2中,我们知道了每个对象只有自己独有的静态成员变量,并没有自己独有的成员方法,因为方法并不需要开辟内存空间来存储,只需要调用即可。下图中第2、3个红色方框框起来的部分,dog1、dog2对象都在调用setDog这个非静态成员方法,而这个静态成员方法中并没有说明name,age,color到底是哪个对象的非静态成员变量,在执行代码的过程中编译器怎么知道name,age,color是哪个对象的非静态成员变量呢?
问题二:下图中第1、2个红色方框框起来的部分,dog1、dog2对象都在调用value这个非静态成员方法用于初始化非静态成员变量。当我们按照预期运行代码后,在屏幕上打印出来的结果,为什么会出现给非静态成员变量赋值并没有成功的情况?
6.2 介绍this
1. 在所有的非静态成员方法的参数列表中其实都隐藏了一个形参this,这个this和当前调用这个非静态成员方法的引用指向着同一个对象。
2. 我们在非静态成员方法中对所有非静态成员变量/方法的调用,都是通过this去访问的。也就是说6.1中的问题二,在执行代码的过程中编译器是通过非静态成员方法参数列表中隐藏的形参this知道的name,age,color是哪个对象的非静态成员变量的。
3. 在非静态成员方法中this可以省略不写,编译器会自动补上。但这样特别容易出现6.1中的问题二出现的问题,即由于当非静态成员方法的形参名与非静态成员变量名不小心相同时,编译器采用局部变量优先的原则,value方法中所有的name、age、color代表的都是形参name、age、color而没有代表非静态成员变量中的name、age、color的,所以造成了赋值并没有成功。因此建议,只要在非静态成员方法中调用非静态成员变量/方法时,都给非静态成员变量/方法前加一个this,相当于明确说明了非静态成员变量是哪个对象的,非静态成员方法是哪个引用在调用(这个this和当前调用这个非静态成员方法的引用指向着同一个对象)。
4. 总之:非静态成员变量/方法在被调用时,得指明是谁在调用 (对象的引用/this)。
6.3 this特性
1. this的类型:哪个引用调用的非静态成员方法this就和哪个引用的类型一致。
2. this只能在非静态成员方法中使用,静态成员方法中的参数列表中并没有隐藏参数this。
3. 在非静态的成员方法中,this引用只能找到所指向对象的成员变量/方法(但并不推荐去找静态的成员变量/方法,因为静态的成员变量/方法并不依赖于对象,这种找法合法但不合理),不能找到其他对象的成员变量/方法。
4. this引用是非静态成员方法的第一个隐藏的形式参数,在非静态成员方法执行时,编译器会负责将调用非静态成员方法的引用所指向的对象的地址传递给形参this。
5. 代码层面来简单演示--->注意:下图右侧中的Date类也是可以通过编译的。
七、非静态成员变量的初始化方式
方式一:就地初始化非静态成员变量
方式二:在方法中使用对象的引用初始化非静态成员变量(注意一下,非静态成员被什么修饰了)
方式三:自己写一个成员方法初始化非静态成员(这个成员方法得写成非静态的,不然初始化不了非静态的成员变量)
方式四:构造方法初始化非静态成员(一般采用这种方式初始化!!!,构造方法别用static修饰!!!)
方式五:构造代码块初始化非静态成员(后面会讲什么是Java中的代码块)
八、构造方法
8.1 概念
1. 方法:返回类型 + 方法名称 + 参数列表 { //方法体... };
构造方法:方法名称(和所在类的类名一致) + 参数列表 { //方法体... };
2. ① 一般情况下使用public修饰构造方法,特殊场景下会被private修饰(后序讲单例模式时会遇到)。
② 构造方法的名字与所在类的类名一致,没有返回值类型,设置为void也不行。
③ 构造方法在实例化对象时由编译器自动调用,并且在每一个对象的生命周期中只会调用一次。
④ 构造方法是一种特殊的成员方法,构造方法的作用就是对对象中的成员变量进行初始化(静态成员变量也可以,只要该构造方法没有被static修饰),注意它不负责给对象开辟空间。
8.2 特点
① 构造方法可以重载(我们可以根据自己的需求创建出拥有不同参数个数的构造方法)
ps:我们可以使用开发工具生成所有可能构成的构造方法,步骤如下图。
② 如果没有显示定义构造方法,则编译器会在实例化对象时调用系统自动生成的一个没有参数的构造方法,所以没有显示定义构造方法就运行代码时,编译器并不会报错。
③ 如果已经显示定义了构造方法,则编译器不会再提供系统生成的不带参数的构造方法(编译器只救急不救穷!!!),如果此时想使用不带参数的构造方法就得自己去写了。例如,下图中自己已经定义了带参数的构造方法,在示例化对象时,new的后面如果没有给构造方法传参数,就会报错,因为此时类中只显示定义了带参数的构造方法,并没有定义不带参数的构造方法,编译器也没有提供不带参数的构造方法。
④ 可以通过this(...);在一个构造方法中调用其他的构造方法来简化代码。
注意1:this(...)所在的地方必须是构造方法中第一条语句。
注意2:使用this();不能形成环,否则会报错。
九、写个代码简单总结一下
本篇文章已完结,谢谢支持哟 ^^ !!!