Java学习之类与对象(上)

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.调用构造方法,给对象的各个成员赋值

这里我们可以发现在调用构造方法之前,对象的成员已经被设置好了初始值,即已经被初始化。所以我们在调用构造方法时可以使用未“初始化”的成员变量。
这里我们就先介绍这么多,欲知后事如何,请听下回分解。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值