目录
当一个类有多个对象时,编译器是如何值知道每个对象所对应的数据的?
什么是面向过程?什么又是面向对象?
我们手洗衣服会经历以下步骤:拿盆子——放水——放衣服——放洗衣服——手搓——换水——手搓——拧干——晾衣服等步骤。而这一系列步骤就是我们用手洗衣服的过程,我们需要通过很多的步骤才能完成洗衣服这个任务。
用洗衣机洗衣服:我们只需要把衣服和洗衣粉放如洗衣机即可。我们不需要关注洗衣服的过程,只需要把它放入洗衣机就可以完成洗衣服这个任务。
用手洗衣服我们可以理解为是面向过程,我们需要完成洗衣服的每个步骤。
用洗衣机洗衣服可以理解为面向对象,我们只需要把衣服放入洗衣机即可,不需要关注具体是怎么洗衣服的。
什么是类?如何定义类?
什么是类?
类是用来对一个实体对象进行描述的。
每个类别都有自己的属性,和功能(行为)。
比如洗衣机,在java中可以将其看成一个类别。
属性:品牌,颜色,型号,尺寸,重量
功能:洗衣,脱水,烘干。
根据类自身属性和功能内容不同,一个类可以有多个具体的实例(对象)。
比如现在有俩台洗衣机,一台是海尔品牌的,白色,又洗衣和脱水的功能。另一台是美的品牌的,黑色,有洗衣,脱水,和定时功能。这样我们就从一个抽象的类,具体到俩个实例(对象)了。
如何定义类?
// 创建类
class ClassName{ field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法 }
class WashMachine{
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double lenght; // 长
public double weidth; // 宽
public double height; // 高
public String color; // 颜色
public void WashClothes(){// 洗衣服
System.out.println("洗衣功能"); }
public void dryClothes(){ // 脱水
System.out.println("脱水功能"); }
public void SetTime(){ // 定时
System.out.println("定时功能"); } }
我们再来定义一个学生类:
class Student{
//属性 - 成员变量
public String name;//名字
public String gender;//年级
public int age;//年龄
public double score;//成绩
//行为-成员方法
public void doClass(){}//听课
public void doHoemwork(){}//做作业
public void exame(){}//考试
public void output(){//输出姓名,年龄,分数
System.out.println(name+" "+age+" "+score);
}
}
有了类之后如何产生对象?
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
}
当成员变量没有初始化的时候,默认值就是对应的初始值。
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
System.out.println(student1.name);
}
如何访问对象中的属性和方法?
使用 . 来访问对象中的属性和方法.
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "zhangsan";
student1.age = 18;
student1.score = 99.5;
student1.output();
}
定义一个TestDate类
public class TestDate {
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);
}
}
设置TestDate里面的成员变量。
1.通过.号访问成员变量设置。
public static void main(String[] args) {
TestDate data1 = new TestDate();
data1.year = 2022;
data1.month = 8;
data1.day = 06;
data1.printDate();
}
通过访问类里面的方法设置:
2.通过.号访问TestDate里面的方法setDay设置
public static void main(String[] args) {
TestDate data1 = new TestDate();
data1.setDay(2022,8,06);
data1.printDate();
}
当形参名和成员变量名相同时,成员变量会被赋值吗?
把上面的代码setDay里面的内容改成:
public void setDay(int year,int month ,int day){
year = year;
month = month;
day = day;
}
这时候我们再用访问setDay的方式来改变成员变量:
public static void main(String[] args) {
TestDate data1 = new TestDate();
data1.setDay(2022,8,06);
data1.printDate();
}
结果会是默认值,也就是说month,year,day,并没有被赋值。
这是为什么呢?
原因是局部变量优先:此时的形参名和成员变量名相同,形参的year,month,day是局部变量,所以认为这里的2022,8,06是赋值给了形参。
简单来说就是 year = year;的左右俩边都是形参。而之前 year = y;左边year是成员变量,右边y是形参。
当一个类有多个对象时,编译器是如何值知道每个对象所对应的数据的?
public static void main(String[] args) {
TestDate data1 = new TestDate();
TestDate data2 = new TestDate();
data1.setDay(2022,8,06);
data2.setDay(2022,8,05);
data1.printDate();
data2.printDate();
}
1.通过.号前面被访问的对象
2. 通过方法默认的隐藏参数
每个方法的第一个参数都隐藏了一个this
比如这里的setDay方法
public void setDay(TestDate this,int y,int m ,int d)
this可以理解为:当前对象的引用,谁调用这个方法,谁就是this。
比如这里的data1.setDay(TestDate this,int y,int m,int d),这里的this指的就是data1。
再回到之前形参名和成员变量名相同,形参会给形参赋值。如何解决这个问题?
我们只需要加上this:
public void setDay(int year,int month ,int day){
this.year = year;
this.month = month;
this.day = day;
}
访问setDay的方式来改变成员变量:
public static void main(String[] args) {
TestDate data1 = new TestDate();
data1.setDay(2022,8,06);
data1.printDate();
}
原因:this指当前对象的引用,那么 这里的this指的就是data1。
也可以看成 data1.year = year,左边是当前成员变量的year。而右边是形参year。
初始化对象:
1.默认初始化:
在创建成员变量的时候不给它赋值。
public int year;
public int month;
2.就地初始化:
在创建成员变量的时候给他一个值
public int year = 2022;
public int month = 8;
构造方法
(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且 在整个对象的生命周期内只调用一次。
特性
1. 名字必须与类名相同
2. 没有返回值类型,设置为void也不行
这里就写了一个带参数的构造方法,和一个不带参数的构造方法。
如何调用构造方法?
用Student类创建了一个student对象,此时自动调用不带参数的构造对象。
当构造方法调用完成之后,对象才实际上产生了。
如何调用一个带参数的构造方法?
在创建对象时,由编译器自动调用
编译器自动生成的构造方法:
此外,当我们没有提供任何的构造方法的时候,编译器会帮我们提供一个不带参数的构造方法。
也就是说:即使我们类里面没有写构造方法,编译器会自动提供一个不带参数的构造方法。在创建对象时,也会自动调用这个由编译器自动生成的不带参数的构造方法。
但是如果定义了一个构造方法(无论有参或者无参),此时编译器不会自动提供不带的构造方法,如果定义了一个有参数的构造方法,创建对象时,要写上参数,否则会报错。
![](https://img-blog.csdnimg.cn/0faeb0bd58884657b8dd6e43e33c23fb.png)
不能形成循环。
形成了环,永远调不完,这是错误的!