JAVA中类和对象

发布于:2022-11-09 ⋅ 阅读:(11) ⋅ 点赞:(0) ⋅ 评论:(0)

目录

面向对象

类与对象

类的定义

类的实例化

讨论

this引用

为什么要有this引用

问题1:参数名与变量名如果不小心相同

问题2:同样都是调用类中的方法,date1,date2,有什么不同呢?如何知道是对哪个对象进行操作实现?

 什么是this引用

this引用的特性

 对象的构造及初始化

构造方法


面向对象

java是一门面向对象的语言,那什么是面向对象,我们直接进入主题

 举一个栗子,正常洗衣服过程需要一下过程

 而这些过程少一步都完成不了这个洗衣服这件任务

然而当我们有了对象就可以让对象来洗,当然这个对象并不是真的对象,在java中叫object,按上面的例子来阐述对象

我们将以上的程序流程可以变为四个对象,衣服洗衣粉洗衣机

 我们可以通过人,来操作衣服,洗衣粉,放到洗衣机里,在洗衣机中来完成洗衣服这个任务,而不需要去关心洗衣机是如何运行的,对于第一种方法来说不同衣服洗的方式,时间长度,拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另 一种放方式。 按照第二种方式来写代码,将来扩展或者维护起来会比较容易。

类与对象

认识对象后那么我们该怎样去创建一个对象,这时我们就需要认识一下,概括来说,类是对象的模板,对象是类的实例,在以下例子中我们阐述创建了一个“PetDog”的对象,对于宠物狗来说,会有不同的名字,颜色,品种和动作,那么对于不同的宠物狗来说就是一个类

class PetDog {
    public String name;//名字
    public String color;//颜色
    // 狗的属性
    public void barks() {
    System.out.println(name + ": 旺旺旺~~~");
    }
    // 狗的行为
    public void wag() {
    System.out.println(name + ": 摇尾巴~~~");
    }
}

类的定义

类中包含有属性(成员变量,在类的内部成员方法的外部)与对应的功能(成员方法

类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类 具有哪些功能,称为类的成员方法。

class为定义类的关键字,class后紧接着是类的名字,{}中为类的主体。

类的实例化

定义了一个类,就相当于在计算机中定义了一种新的类型,就如在int,double 等类型一样,可以通过他们来创建一个变量,而int,double 等是有java中的内置类型,而类是用户自定义了一个新的类型,用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。

现在我们有了类,便可以通过类来创建一个真正的对象

public class Main{
    public static void main(String[] args) {
        PetDog dogh = new PetDog(); //通过new实例化对象
        dogh.name = "阿黄";
        dogh.color = "黑黄";
        dogh.barks();
        dogh.wag();
        PetDog dogs = new PetDog();
        dogs.name = "赛虎";
        dogs.color = "棕色";
        dogs.barks();
        dogs.wag();
    }
}


输出结果:
阿黄: 旺旺旺~~~
阿黄: 摇尾巴~~~
赛虎: 旺旺旺~~~
赛虎: 摇尾巴~~~
  • new 关键字用于创建一个对象的实例 
  • 使用 . 来访问对象中的属性和方法
  • 同一个类可以创建多个实例

讨论

  1.  类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员
  2. 类是一种自定义的类型,可以用来定义变量
  3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量,而类相当于图纸,在没有实例化,并没有实际存在

this引用

为什么要有this引用

以下举例子说明(创建一个日期类,并对其进行实例化)

//创建日期类
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 printDay() {
        System.out.println(year+"/"+month+"/"+day);
    }
}
//在主函数中去实例化
    public static void main(String[] args) {
        
        Date date1 = new Date();//new一个date1对象
        Date date2 = new Date();//new一个date2对象
        //分别进行初始化
        date1.setDay(2022,11,8);
        date2.setDay(2022,11,9);
        //打印
        date1.printDay();
        date2.printDay();
    }

问题1:参数名与变量名如果不小心相同

public void setDay(int year, int month, int day){
    year = year;
    month = month;
    day = day;
}

那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?

问题2:同样都是调用类中的方法,date1,date2,有什么不同呢?如何知道是对哪个对象进行操作实现?

 什么是this引用

this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

public class Date {
    public int year;
    public int month;
    public int day;
    public void setDay(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void printDate(){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
}

注意:this引用的是调用成员方法的对象。不能对静态方法使用this(在此不做赘述)

this引用的特性

  1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
  2. this只能在"成员方法"中使用
  3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
  4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收

 对象的构造及初始化

在上篇文章中介绍了java中的数据类型必须要初始化,否则会报错,那么对于创建的类该如何进行对象的初始化

在上述日期类中,我们采用了类中的成员方法SetDate来对对象进行初始化,但是每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?

构造方法

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且 在整个对象的生命周期内只调用一次。

public class Date {
    public int year;
    public int month;
    public int day;
    // 构造方法:
    // 名字与类名相同,没有返回值类型,设置为void也不行
    // 一般情况下使用public修饰
    // 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("输出构造方法Date被调用了");
    }
    public void printDate(){
        System.out.println(year + "/" + month + "/" + day);
    }

    public static void main(String[] args) {
        // 此处创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2022,11,9); // 输出构造方法Date被调用了
        d.printDate(); // 2022/11/9
    }
}

特性

  1. 名字必须与类名相同
  2. 没有返回值类型,设置为void也不行
  3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次) 
  4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
  5. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的   注意:一旦用户定义,编译器则不再生成
  6. 构造方法中,可以通过this调用其他构造方法来简化代码
  7. 绝大多数情况下使用public来修饰,特殊场景下会被private修饰(在此不做阐述)
public class Date {
    public int year;
    public int month;
    public int day;
    // 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
    // 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
    // 但是this(1900,1,1);必须是构造方法中第一条语句
    public Date() {
        //System.out.println(year); 注释取消掉,编译会失败
        this(1900, 1, 1);
        //this.year = 1900;
        //this.month = 1;
        //this.day = 1;
    }
    // 带有三个参数的构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

注意:

  • this(...)必须是构造方法中第一条语句
  • 不能形成环
public Date(){
    this(1900,1,1);
}

public Date(int year, int month, int day) {
    this();
}
/*
无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
编译报错:Error:(19, 12) java: 递归构造器调用
*/

 默认初始化

在上面的例子中我们可以发现一个问题,为什么局部变量在使用时必须要初始化,而成员变量可以不用呢?

public class Date {
    public int year;
    public int month;
    public int day;
    public Date(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没有初始化,编译时报错:
    // Error:(24, 28) java: 可能尚未初始化变量a
    // int a;
    // System.out.println(a);
    Date d = new Date(2021,6,9);
    }
}

 要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:

在new的时候JVM在层面需要做很多东西

  1. 检测对象对应的类是否加载了,如果没有加载则加载
  2. 为对象分配内存空间
  3. 处理并发安全问题 比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突 数据类型 默认值 byte 0 char '\u0000' short 0 int 0 long 0L boolean false float 0.0f double 0.0 reference null
  4. 初始化所分配的空间 即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值
  5. 设置对象头信息

在此不做过多得介绍,简单了解


以上就是本文的全部内容,如果对你有帮助的话,期待你的点赞加关注!