Java 类和对象

1. 对象


1.1 什么是对象

        在我们的日常生活中,万事万物都可以被视为对象。例如,猫咪中的"小咪"有着灰白色的毛发,而"小黑"则是黑灰色的毛发,这些都是具体的对象实例。在Java编程中,对象可以通过模板来定义:比如猫这个类别,它具有名字和毛色等属性,还能通过舔毛来清洁自己;同样地,狗这个类别也拥有名字、毛色和年龄等属性,并会通过摇尾巴来表达情绪。正是通过这些特征描述,我们才能准确地定义一个对象。

1.2 什么是面向对

        Java是一门纯面向对象的编程语言(Object Oriented Programming,简称OOP)。在面向对象的世界中,万事万物皆可视为对象。面向对象不仅是一种编程范式,更是一种解决问题的思维方式。其核心在于通过对象之间的交互来解决问题。采用面向对象的方法编写程序,能够显著提升大型项目在架构设计、功能扩展以及后期维护方面的效率与可操作性。

1.3 面向对象与面向过程

面向对象与面向过程的区别可以通过生活中的例子来理解。以洗衣场景为例:

面向对象的流程可分解为:

  1. 拿取衣物
  2. 放入洗衣机
  3. 加入洗衣粉
  4. 操作洗衣机按钮
  5. 等待洗衣完成
  6. 取出衣物

面向过程的流程则为:

  1. 拿取衣物
  2. 放入洗槽
  3. 加水
  4. 放入洗衣粉
  5. 手搓衣物
  6. 换水
  7. 再次手搓
  8. 倒水
  9. 拧干衣物

通过对比可以看出:

  • 在面向对象的方式中,我们不需要了解洗衣机和甩干的具体实现细节,只需通过人、洗衣机、洗衣粉和衣物这四个对象的交互就能完成任务。
  • 而面向过程则需要掌握衣物清洗和甩干的每个具体步骤。

这种差异在编程中同样存在。例如实现两位整数的四则运算:

  • 面向对象只需调用现成的方法/函数并接收返回值
  • 面向过程则需要手动编写算法实现运算功能

2. 类 


2.1 什么是类        

        前面我们详细探讨了对象的概念,而类正是用来定义这些对象的模板 

以手机为例,在Java中我们可以将其抽象为一个类:

属性包括:产品型号、品牌、重量、颜色、电池容量、处理器型号、Cmos规格等。

功能包括:拍照、社交聊天、网络浏览、音频播放、视频播放等。

        那么在Java中是如何进行类的定义的呢? 

2.2 类的定义

        在Java中,进行类的定义需要使用到关键字class,具体语法如下:

class ClassName{
    //字段(属性) 或者 成员变量
    //方法 成员方法
}

其中:

  • class是定义类的关键字
  • ClassName是类名,需遵循大驼峰命名规范
  • 大括号{}是类的主体,可以包含成员变量和成员方法

类中包含的成员分为两类:属性用于描述类的特征,称为成员属性或成员变量;方法用于定义类的功能,称为成员方法。

例如下列描述手机

class Phone{
    public String brand;//品牌
    public String type;//型号
    public double weight;//重量
    public String color;//颜色
    public String cpuType;//处理器型号
    public String cmosType;//相机传感器型号
    public int batteryCapacity;//电池容量

    //功能包括:拍照、社交聊天、网络浏览、音频播放、视频播放

    public void takePhoto() {
        System.out.println(brand + " " + type + " 正在拍照");
    }

    public void chat() {
        System.out.println(brand + " " + type + " 社交聊天");
    }

    public void webSurfing() {
        System.out.println(brand + " " + type + " 正在网络浏览");
    }

    public void mp3Playback() {
        System.out.println(brand + " " + type + " 正在播放音频");
    }
    
    public void mp4Playback() {
        System.out.println(brand + " " + type + " 正在播放视频");
    }
}

3. 类的实例化


3.1 什么是实例化

        当我们定义了一个 ,就相当于在计算机中定义了一种新的类型,定义类相当于在计算机中创建了一种新类型,这与int、double、String等内置类型类似。区别在于,int、double等是语言预定义的基础类型,而允许用户自定义新类型。例如我们之前定义的Phone类,都是这种自定义类型的体现。通过这些自定义类,我们就能创建相应的对象实例

        使用类创建对象就像根据房屋设计图建造一栋房子。图纸定义了房屋的结构,而实际建造出来的房子则是具体的实例

        而使用类 来 创建 对象 的过程就叫做 类的 实例化,在Java中采用关键字 new 来进行类的实例化 , 比如实例化上述的一个Phone 如下:

 Phone phone1 = new Phone();

Phone   就像设计图纸

phone1 是为房子起的名字

new      关键字相当于施工队的开工指令

整个 new Phone() 过程就相当于完整的房屋建造流程

剖析

Phone声明phone1变量时指定为Phone类
phone1对象引用变量,用于指向堆中创建的对象实例
new实例化关键字,在内存中开辟空间,调用类的构造函数并返回对象的内存地址
Phone()执行类中定义的构造方法 Phone(){...},完成对象初始化:
=将创建的堆内存对象地址,存储到 phone1 引用变量中

内存分配:

类可以实例化多个对象,就像可以根据同一张图纸建造多栋房子。

3.2 对象的使用

通过 引用变量名.方法名/成员变量 来使用 如下:

 public static void main(String[] args) {
        Phone phone1 = new Phone();
        phone1.brand = "Xiaomi";
        phone1.type = "14";
        phone1.weight = 220;
        phone1.color = "write";
        phone1.cpuType = "SM8650";
        phone1.cmosType = "OV50H";
        phone1.batteryCapacity = 4800;

        phone1.takePhoto();
        phone1.chat();
        phone1.webSurfing();
        phone1.mp3Playback();
        phone1.mp4Playback();
    }

 运行结果:

Xiaomi 14 正在拍照
Xiaomi 14 社交聊天
Xiaomi 14 正在网络浏览
Xiaomi 14 正在播放音频
Xiaomi 14 正在播放视频

4.this 引用

为什么要有this 引用 以及this引用能干嘛,让我们通过下面的例子来了解:

public class Date {
    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 printDate() {
        System.out.println(year + "年" + month + " 月" + day + "日");
    }
    public static void main(String[] args) {
        Date date = new Date();
        date.setDate(2000,10,1);
        date.printDate();
    }
}

这段代码定义了一个日期类,其中包含设置日期的方法。当运行main方法时,输出结果却显示"0年0月0日"。问题出在setDate方法中:我们直接对形参进行赋值,而没有修改类的成员变量。

观察代码可以发现,setDate方法的形参与成员变量同名,导致赋值操作只修改了局部变量而非成员变量。虽然可以通过修改形参名称来解决,但更简洁的方法是使用this关键字。this引用指向当前对象实例,通过this.year可以明确指定要修改的是成员变量。

修改过后的代码如下:

public class Date {
    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) {
        Date date = new Date();
        date.setDate(2000,10,1);
        date.printDate();
    }
}

再次运行,结果为2000年10 月1日

那么就会产生一个疑问了,为什么使用this就能使其找到成员变量了呢?

不妨将其打印出来试试,我们创建一个简单的Date类来进行验证:

public class Date {
    public void print() {
        System.out.println(this);
    }
    public static void main(String[] args) {
        Date date = new Date();
        date.print();
        System.out.println(date);
    }
}

运行过后结果如下:

Date@7ef20235
Date@7ef20235

不难发现,this传递的就是该对象的地址,那么 答案就呼之欲出了,

this和data变量指向的是同一个对象,所以在方法内部使用this时,实际上就是隐式地传递了当前对象的引用。因此,通过this访问成员变量时,JVM能够准确地找到属于该特定实例的成员变量。

5. 对象的构造以及初始化

5.1对象的初始化

对象的初始化有以下几种方式

  1. 就地初始化
  2. 通过getset等方法初始化
  3. 通过构造方法初始化
  4. 通过代码块初始化

就地初始化: 

// 就地初始化示例  
class Person {  
    private String name = "无名氏";  
}  
 

 通过getset等方法初始化:

public class Student {
    public int age;
    public String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public static void main(String[] args) {
        Student student1= new Student();
        student1.setAge(18);
        student1.setName("lisi");
    }
}

通过构造方法初始化:

public class Student {
    public int age;
    public String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public static void main(String[] args) {
        Student student1= new Student(18,"lisi");
    }
}

 5.2 构造方法

        构造方法(又称构造器)是一种特殊方法,其名称必须与所属类保持一致。当创建对象实例时,编译器会自动调用该方法,且每个对象在其生命周期内仅会被调用一次。

public class Student {
    public int age;
    public String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public static void main(String[] args) {
        Student student1= new Student(18,"lisi");
    }
}

需要注意的是,如果当我们没有写构造方法,那么编译器便会生成一个默认的构造方法用于调用,不过该构造方法参数为空,代码块为空,其结构如下:


    public 类名() {
        //为空
    }
  

 如果当我们写了构造方法,那么系统就不会生成该构造方法

*构造方法一般用于对对象中的成员进行初始化

值得一提的是,构造方法可以重载,如下:

public class Student {
    public int age;
    public String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
        System.out.println("这是一个带有3个参数的构造方法");
    }
    public Student() {
        System.out.println("这是一个不带参数的构造方法");
    }
    public static void main(String[] args) {
        Student student1= new Student(18,"lisi");
    }
}

在构造方法中,可以通过this来调用其他构造方法,如下: 

public class Student {
    public int age;
    public String name;

    public Student(int age, String name) {
        this();
        this.age = age;
        this.name = name;
        System.out.println("这是一个带有3个参数的构造方法");
    }
    public Student() {
        System.out.println("这是一个不带参数的构造方法");
    }
    public static void main(String[] args) {
        Student student1= new Student(18,"lisi");
    }
}

运行结果:

这是一个不带参数的构造方法
这是一个带有3个参数的构造方法

注意:this(...)必须是构造方法中的第一条语句,且不能与其他构造方法形成闭环

public Student(int age, String name) {
        this();
        this.age = age;
        this.name = name;
        System.out.println("这是一个带有3个参数的构造方法");
    }
    public Student() {
        this(19,"lisi")
        System.out.println("这是一个不带参数的构造方法");
    }
//error 形成环了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值