文章目录
java学习之类与对象(上)
一.面向对象的初步认知
1.1什么的面向对象
Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆对象,面向对象是解决问题的一种思想,主要依靠对象之间的交互来完成一件事。
1.2面向对象和面向过程
这里我们用洗衣机来举例
1.面向过程
传统的洗衣过程如下
传统的方式注重的是过程,少一步都不行
2.面向对象
现代的洗衣过程
人→衣服→洗衣粉→洗衣机
整个过程主要是人、衣服、洗衣粉,洗衣机这几个对象之间交互完成的,至于过程我们则不关注。
二.类的定义和使用
在上述我们提到的人,衣服,洗衣机都是对象,那我们如何拿到对象,这就需要先定义类,什么是类,如何定义类
这里我们拿人来举例
在Java中定义类时需要用到class关键字
//创建一个类
class Person{
String name;//字段属性(成员变量)
double height;
char sex;
public void eat(){//成员方法
System.out.println(name+"在吃饭");
}
public void play(){
System.out.println(name+"打篮球");
}
}
三.类的实例化
定义了一个类,就相当于在计算机中创建了一个新的类型,用类创建对象的过程称为类的实例化。
public class Text {
public static void main(String[] args) {
Person person=new Person();//通过new实例化对象
person.name="张三";//通过“.”来访问类的成员变量和成员方法
person.height=1.83;
person.play();
}
}
总结:
1.通过new关键字实例化对象
2.通过.来访问类的成员变量和成员方法
3.一个类可以实例化为多个对象
这就好比类是一张房屋的图纸,而对象则是根据图纸建造的房屋。
四.this引用
首先我们会想为什么要有this引用呢?
下面我们用代码进行说明
public class DateUtil {
public int year;
public int month;
public int day;
public void setDate(int y,int m, int d){
year=y;
month=m;
day=d;
}
public void show(){
System.out.println("年: "+year+" 月: "+month+" 日: "+day);
}
public static void main(String[] args) {
DateUtil dateUtil=new DateUtil();
dateUtil.setDate(2022,11,10);
dateUtil.show();
}
}
以上定义了一个日期类,然后在main方法中创建了一个对象,并通过Date类中的成员方法对对象进行设置和打印,代码整体逻辑简单,没有任何问题。
但细思下则有一个疑问
*形参名和成员变量名不小心相同的
`
public class DateUtil {
public int year;
public int month;
public int day;
public void setDate(int year,int month, int day){
year=year;
month=month;
day=day;
}
public void show(){
System.out.println("年: "+year+" 月: "+month+" 日: "+day);
}
public static void main(String[] args) {
DateUtil dateUtil=new DateUtil();
dateUtil.setDate(2022,11,10);
dateUtil.show();
}
}
`*
当我们运行的时候会发现,运行结果为0,这是为什么呢?
因为这里的year, month, day都是形参,都是局部变量(局部变量优先),相当于自己给自己赋值,而不是给成员变量赋值。这个我们可以加上this来表示对该对象的引用
4.1什么是this引用
this引用指向当前对象(成员方法时调用该成员方法的对象),在成员方法中所有成员变量的操作都是通过this去访问的。 只不过所有的操作对用户都是透明的,即用户不需要传递,编译器自动完成。
public void setDate(int year,int month, int day){
this.year=year;
this.month=month;
this.day=day;
}
this代表对当前对象的引用
上面是this的第一个用法,接下来我们再介绍两种用法
this的其他两种用法
1.this访问构造方法
2.this访问成员方法
五.构造方法
通过上述this的讲解,我们发现,如果我们要对对象的成员变量初始化时,都得调用setData方法设置日期,比较麻烦,这时,用构造方法就显得十分简单了。
那么什么是构造方法呢?
5.1构造方法的概念
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象(即new对象)时,由编译器自动调用,并且在对象的整个生命周期只调用一次
public class DateUtil {
public int year;
public int month;
public int day;
public DateUtil(){
System.out.println("不带参数的构造方法");
}
public DateUtil(int year,int month, int day){
this.year=year;
this.month=month;
this.day=day;
System.out.println("带三个参数的构造方法");
}
public void setDate(int year,int month, int day){
this.year=year;
this.month=month;
this.day=day;
}
public void show(){
System.out.println("年: "+year+" 月: "+month+" 日: "+day);
}
public static void main(String[] args) {
DateUtil dateUtil1=new DateUtil();
dateUtil1.setDate(2022,11,10);
dateUtil1.show();
DateUtil dateUtil2=new DateUtil();
dateUtil2.setDate(2022,11,11);
dateUtil2.show();
DateUtil dateUtil3=new DateUtil();
dateUtil3.setDate(2022,11,12);
dateUtil3.show();
}
}
通过代码我们可以看出,在new对象的时候就会调用构造方法,并且只调用一次。
这里我们有个疑问,之前我们没写构造方法的时候也能正常运行,这是为什么呢?
注:
这是因为如果我们没有写任何构造方法,Java会帮我们提供一个默认的,不带任何参数的构造方法,写了,则调用我们自己的,且只调用一次
同时,在上面的代码我们写了两个构造方法,这样呢就构成了重载,
重载:方法名必须相同,参数列表不同,返回值没有影响
总结:
1.构造方法名字必须与类名相同
2.没有返回值类型,即使是void也不行
3.创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
4.构造方法可以构成重载
public DateUtil(int year,int month, int day){
this.year=year;
this.month=month;
this.day=day;
System.out.println("带三个参数的构造方法");
}
这里我们发现了一个矛盾点,在上述我们提到this是对当前对象的引用,但当我们调用完构造方法,对象才生成,那么我们怎么能在这里用this的呢?
在这里我们可以理解为,一个对象的生成分为以下步骤
1.为对象分配内存
2.调用合适的构造方法
5.2this调用构造方法
public class DateUtil {
public int year;
public int month;
public int day;
public DateUtil(){
this(1997,10,21);//调用该对象的其他构造方法,必须放在第一行,只能在构造方法内使用
System.out.println("不带参数的构造方法,这个方法没有写,Java会默认提供");
}
public DateUtil(int year,int month, int day){
this.year=year;
this.month=month;
this.day=day;
System.out.println("带三个参数的构造方法");
}
public void setDate(int year,int month, int day){
this.year=year;
this.month=month;
this.day=day;
}
public void show(){
System.out.println("年: "+year+" 月: "+month+" 日: "+day);
}
public static void main(String[] args) {
DateUtil dateUtil=new DateUtil();
dateUtil.show();
}
}
通过上述代码我们可以发现,通过this(),我们可以调用该对象的其他构造方法
运行结果如下:
这里有个有趣的事情,先看代码
public DateUtil(){
this(1997,10,21);//调用该对象的其他构造方法,必须放在第一行,只能在构造方法内使用
System.out.println("不带参数的构造方法,这个方法没有写,Java会默认提供");
}
public DateUtil(int year,int month, int day){
this();
this.year=year;
this.month=month;
this.day=day;
System.out.println("带三个参数的构造方法");
}
这里就会陷入循环,上面的构造方法引用下面的,下面的又去引用上面的,编译器这里会报错。这里我们就得注意, this引用不能形成环。
注:
this(......)必须是构造方法的第一条语句
5.3this访问成员方法
public DateUtil(int year,int month, int day){
this.show();//与show();一样
this.year=year;
this.month=month;
this.day=day;
this.show();
System.out.println("带三个参数的构造方法");
}
public void show(){
System.out.println("年: "+year+" 月: "+month+" 日: "+day);
}
代码结果如下:
总结:
this.data 访问当前对象的成员变量
this.func() 访问当前对象的成员方法
this() 调用当前对象的其他构造方法
注:
this不能调用静态成员和属性
5.4默认初始化
在之前的学习中,我们知道,局部变量在使用前必须需要初始化,但成员变量为什么不用呢?
public class DateUtil {
public int year;
public int month;
public int day;
public DateUtil(int year,int month, int day){
//成员变量在定义时,没有初始化,为什么可以使用
System.out.println(this.year);
System.out.println(this.month);
System.out.println(this.day);
}
public static void main(String[] args) {
//此处a没有初始化,编译会报错
//java: 可能尚未初始化变量a
// int a;
//System.out.println(a);
}
要搞清楚这个过程,就需要知道new关键字后面的一些事情
Data d=new Data(2022,11,12);
在程序层面只是一条简单的语句,但在JVM层面要做很多事情,这里简单介绍下
1.检测对象对应的类是否被加载了,如果没有加载则加载
2.为对象分配内存空间(上文提到过)
3.处理并发安全问题
比如多个线程同时申请对象,JVM要保证给对象分配的空间不发生冲突
4.初始化所分配的空间
即:对象空间申请好之后,对象中包含的成员已经设置好了初始值,除了char是“/u0000”,boolean是“false”,引用类型的是“null”,其他的初始值都为0.
5.设置对象头信息
6.调用构造方法,给对象的各个成员赋值
这里我们可以发现在调用构造方法之前,对象的成员已经被设置好了初始值,即已经被初始化。所以我们在调用构造方法时可以使用未“初始化”的成员变量。
这里我们就先介绍这么多,欲知后事如何,请听下回分解。