• JavaSE => 类和对象 (一)


    作者 :ふり

    专栏 :JavaSE

    格言 : I came ; I saw ; I conquer
    在这里插入图片描述


    一、面向对象的初步认知

    1.1 什么是面向对象

    Java是一门纯面向对象的语言(Object Oriented Program,继承OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好

    1.2 面向对象与面向过程

    • 面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。
    • 面向对象方式来进行处理,就不关注过程,就像洗衣机洗衣服具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关心,只需要将衣服放进洗衣机,导入洗衣粉,启动开关即可,通过对象之间的交互来完成的。

    二、 类定义和使用

    2.1 简单认识类

    • 类是用来对一个实体(对象)来进行描述的

    2.2 类的定义格式

    • 在java中定义类时需要用到class关键字
    // 创建类
    class ClassName{
      field; // 字段(属性) 或者 成员变量
      method; // 行为 或者 成员方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    class为定义类的关键字,ClassName为类的名字,{ }中为类的主体。

    • 类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类具有哪些功能,称为类的成员方法。
    public class Animal{
        //字段
        public String name;
        public int age;
        
        //行为方法
        public void eatHabit(){
            System.out.println("吃饭");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注意事项

    • 类名注意采用大驼峰定义
    • 方法名采用小驼峰
    • 成员前写法统一为public,后面会详细解释
    • 此处写的方法不带 static 关键字. 后面会详细解释
    • 定义一个狗类
    public class PetDog{
        //字段
        public String name;
        public String color;
    
        //行为方法
        public void barks(){
            System.out.println(name+"汪汪叫");
        }
        public void vag(){
            System.out.println(name+"摇尾巴");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意事项:

    1. 一般一个文件当中只定义一个类
    2. main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
    3. public修饰的类必须要和文件名相同
    4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改

    三、类的实例化

    3.1 什么是实例化

    • 定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,
      比如上述的:PetDog类和Student类。
      它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
    • 用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象
    public class PetDog {
        //字段
        public String name;
        public String color;
    
        //行为方法
        public void barks() {
            System.out.println(name + " 汪汪叫");
        }
    
        public void wag() {
            System.out.println(name + " 摇尾巴");
        }
    }
        public class Main {
            public static void main(String[] args) {
                PetDog petdog = new PetDog();
                petdog.name = "黄桃";
                petdog.color = "黑色";
                petdog.barks();
                petdog.wag();
                System.out.println(petdog.name);
                System.out.println(petdog.color);
            }
    }
    
    
    //黄桃 汪汪叫
    //黄桃 摇尾巴
    //黄桃
    //黑色
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注意事项

    • new 关键字用于创建一个对象的实例.
    • 使用 . 来访问对象中的属性和方法.
    • 同一个类可以创建对个实例.

    3.2 类和对象的说明

    1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
    2. 类是一种自定义的类型,可以用来定义变量.
    3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
    4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

    四、this引用

    4.1 为什么要有this引用

    先看一个日期类的例子:

    public class TestDate {
        //字段
        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 printDate(){
            System.out.println(year+" - "+month+" - "+day);
        }
        public static void main(String[] args) {
            TestDate testDate = new TestDate();
            
            //法一
             /*testDate.year = 2022;
            testDate.month = 8;
            testDate.day = 7;*/
            
            //法二
            testDate.setDate(2022,8,7);
            
            testDate.printDate();;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 形参名不小心与成员变量名相同
      在这里插入图片描述
      那我们应该怎么做呢???
      在这里插入图片描述
    • 一切让this引用来揭开这层神秘的面纱

    4.2 什么是this引用

    • this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。.
    public class TestDate {
        //字段
        public int year;
        public int month;
        public int day;
    
        //行为方法
        public void setDate(int year,int month ,int day) {
            this.year = year;
            this.month = month;
            this.day = day;
        }
        public void printDate(){
            System.out.println(year+" - "+month+" - "+day);
        }
        public static void main(String[] args) {
            TestDate testDate = new TestDate();
            testDate.setDate(2022,8,7);
            testDate.printDate();;
        }
    }
    
    
    //2022 - 8 - 7
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    4.3 this引用的特性

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

    五、 对象的构造及初始化

    5.1 如何初始化对象

    通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败

    注意事项:

    • 成员变量没有初始化时,默认值就是其相对应的值
    • 引用类型 =》 null
    • int ==> 0
    • float ==> 0.0f
    • boolean ==> false
    • char ==> '\u0000'

    5.2 构造方法

    5.2.1 概念

    • 构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次
    • 介绍构造方法
    public class TestDate {
        //字段
        public int year;
        public int month;
        public int day;
    
        public TestDate() {
            this.year = year;
            this.month = month;
            this.day = day;
            System.out.println("不带参数的构造方法");
        }
    
    	// 构造方法:
     	// 名字与类名相同,没有返回值类型,设置为void也不行
    	// 一般情况下使用public修饰
    	// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
        public TestDate(int year,int month ,int day) {
            System.out.println("带2个参数的构造方法");
            this.year = year;
            this.month = month;
            this.day = day;
        }
       
        public void printDate(){
            System.out.println(year+" - "+month+" - "+day);
        }
        public static void main(String[] args) {
        
            // 此处创建了一个Date类型的对象,并没有显式调用构造方法
            TestDate testDate = new TestDate(2022,8,7);// 输出Date(int,int,int)方法被调用了
            testDate.printDate();//2022 - 8 - 7
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 由此还可以得出,构造方法可以被重载

    • 有参数的构造方法使用
    public class TestDate {
    
        public int year;
        public int month;
        public int day;
    
        public TestDate(int year,int month ,int day) {
            System.out.println("带2个参数的构造方法");
            this.year = year;
            this.month = month;
            this.day = day;
        }
        public void printDate(){
            System.out.println(year+" - "+month+" - "+day);
        }
        public static void main(String[] args) {
            TestDate testDate = new TestDate(2022,8,7);
            testDate.printDate();;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间


    5.2.2 特性

    1. 名字必须与类名相同
    2. 没有返回值类型,设置为void也不行
    3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
    4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)

    • 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的
    public class Date {
        public int year;
        public int month;
        public int day;
        public void printDate(){
            System.out.println(year + "-" + month + "-" + day);
        }
        public static void main(String[] args) {
            Date d = new Date();
            d.printDate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    上述Date类中,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。

    • 注意:一旦用户定义,编译器则不再生成。
    public class Date {
        public int year;
        public int month;
        public int day;
        public Date(int year, int month, int day) {
            //构造方法中,可以通过this调用其他构造方法来简化代码
            this.year = year;
            this.month = month;
            this.day = day;
        }
        public void printDate(){
            System.out.println(year + "-" + month + "-" + day);
        }
        public static void main(String[] args) {
    		// 如果编译器会生成,则生成的构造方法一定是无参的
    		// 则此处创建对象是可以通过编译的
    		// 但实际情况是:编译期报错
            Date d = new Date();
            d.printDate();
        }
    } 
            /*
            Error:(26, 18) java: 无法将类 extend01.Date中的构造器 Date应用到给定类型;
            需要: int,int,int
            找到: 没有参数
            原因: 实际参数列表和形式参数列表长度不同
            */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    • 构造方法中,可以通过this调用其他构造方法来简化代码
    public class TestDate {
    
        public int year;
        public int month;
        public int day;
      
        public TestDate() {
            //必须放在构造方法里面第一行
          this(2022,8,7);
          System.out.println("不带参数的构造方法");
      }
        public TestDate(int year,int month ,int day) {
            System.out.println("带2个参数的构造方法");
            this.year = year;
            this.month = month;
            this.day = day;
        }
    
        public void printDate(){
            System.out.println(year+" - "+month+" - "+day);
        }
        public static void main(String[] args) {
            TestDate testDate = new TestDate();
            testDate.printDate();;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    注意:

    • this(…)必须是构造方法中第一条语句
    • 不能形成环
        public Date(){
            this(1900,1,1);
        }
        public Date(int year, int month, int day) {
            this();
        } /
            * 无
            参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
            编译报错:Error:(19, 12) java: 递归构造器调用
            */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.3 默认初始化

    上面提及,为什么局部变量在使用时必须要初始化,而成员变量可以不用呢?

    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(2022,8,4);
     }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    对象空间被申请好之后,对象中包含的成员已经设置好了初始值:

    数据类型初始值
    byte0
    char‘\u0000’
    short0
    int0
    long0L
    booleanfalse
    float0.0f
    double0.0
    referencenull

    5.4 就地初始化

    在声明成员变量时,就直接给出了初始值。

    public class TestDate {
    
        public int year = 2022;
        public int month = 8;
        public int day = 7;
        
        public void printDate(){
            System.out.println(year+" - "+month+" - "+day);
        }
        public static void main(String[] args) {
            TestDate testDate = new TestDate();
            testDate.printDate();;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。


  • 相关阅读:
    佳易王会员管理系统软件如何下载,基本功能有哪些
    【译】ASP.NET Core 6 中的性能改进
    python 中面向对象编程:深入理解封装、继承和多态
    Spark在爱奇艺的应用实践
    paddleDetection训练自己的模型
    前端需要去了解的nodejs知识(fs文件处理)
    【第一章:Java开发岗:基础篇】
    搭建STM32F407的Freertos系统(基于STM32CubeMX)
    Leetcode 151. 反转字符串中的单词 JS版两种方法(内置API,双指针)有详细讲解 小白放心食用
    基于Springboot外卖系统09:员工信息编辑+员工信息保存
  • 原文地址:https://blog.csdn.net/qq_55694452/article/details/126183308