前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >类和对象详解

类和对象详解

作者头像
用户11070251
发布2024-04-11 14:58:22
740
发布2024-04-11 14:58:22
举报
文章被收录于专栏:PomathPomath

1.面向对象

1.1什么是面向对象

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

1.2与面向过程的比较

假如我们需要去洗衣服,一般来说有两种方式,即手洗和机洗。手洗的话我们需要放水,添加洗涤剂,然后手搓,发现哪里有污渍,要用更大的力气去搓,以及洗完后用清水漂洗等等过程,而机洗呢,我们只需要把衣服放进去,加入洗涤剂,启动洗衣机即可。两种方式都可以达到衣物清洗干净的目的。手洗我们通常会关心怎么洗,而机洗却不用关心这个问题。虽然说两种方式都可以清洗衣物,手洗虽然费力但是省电省水,机洗虽然轻松,但是会费水费电。不能说哪种方式就一定更好。就像面向过程的语言执行起来效率更高,但是开发难度高,开发时间长,面向对象的语言开发效率高,难度低,但是执行起来很多时候并没有面向过程的语言那么地高效。孰优孰劣,两者并不能一概而论。

2类的定义和使用

2.1简单认识类

类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性,哪些功能。

2.2类的定义格式

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

//创建类 class ClassName { field; //字段(属性)或者成员变量 method; //行为或者成员方法 }

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

类中包含的类容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者成员变量。

方法主要说明类具体有哪些功能,称为成员方法。

代码语言:javascript
复制
class WashMachine {
    public String brand;
    public double weight;
    public double height;
}
public void washClothes() {
    System.out.println("洗衣服的功能");
}
public void dryClothes() {
    System.out.println("脱水的功能");
}

采用Java语言将洗衣机类在计算机中定义完成,经过javac编译后形成class文件,在JVM的基础上计算机就可以识别了。

注意事项

  • 类名注意采用大驼峰定义
  • 成员前写法统一为public
  • 此处方法不带static关键字

2.3类的实例化

2.3.1什么是实例化

定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是Java语言自带的内置类型,而类是用户定义了一种新的类型。有了自定义的类型后,就可以使用这些类来定义实例(对象)。

用类类型创建对象的过程,称为类的实例化,在Java中采用new关键字,配合类名实例化对象。

代码语言:javascript
复制
public class void mian(String[] args) {
    WashMachine n=new WashMachine();
    n.brand1="格力";
    n.wieght=195.3;
    n.height=1.4;
}
class WashMachine {
    String brand;
    double weight;
    double hieght;
}

注意事项

  • new关键字用于创建一个对象的实例
  • 使用.来访问对象中的属性和方法
  • 同一个类可以创建多个实例
2.3.2类和对象的说明
  1. 类只是一个模型一样的东西,用来对一个实体描述,限定了类有哪些成员。
  2. 类是一种自定义类型,可以用来定义变量。
  3. 一个类可以实例化出多个对象,实例化出的对象占用实际物理空间,存储类成员变量
  4. 类实例化就像现实中使用图纸造房子,类就是设计图,只设计出需要什么东西,并没有实体的建筑存在,同样地类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。
2.3.3this关键字
代码语言:javascript
复制
public 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 printDate() {
        System.out.println(year + "/" + month + "/" + day);
    }
public static void main(String[] args) {
    // 构造三个日期类型的对象 d1 d2 d3
    Date d1 = new Date();
    Date d2 = new Date();
    Date d3 = new Date();
    // 对d1,d2,d3的日期设置
    d1.setDay(2020,9,15);
    d2.setDay(2020,9,16);
    d3.setDay(2020,9,17);
    // 打印日期中的内容
    d1.printDate();
    d2.printDate();
    d3.printDate();
    }
}

以上代码定义了一个日期类,然后main方法中创建了三个对象,并通过Date类中的成员方法对对象进行设置和打印。

但是细想一下会发现两个问题

1.形参不小与成员变量名相同

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

那函数到底是在给谁赋值?这是一个说不清的问题了。

2.三个对象都在调用setDate和printDate函数,但是这两个函数中没有任何有关对象的说明,setDate和printDate函数如何知道打印的是哪个对象的数据呢?

所有的一切都需要this引用来解释。

2.3.4什么是this引用

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

代码语言:javascript
复制
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引用的是调用成员方法的对象。

代码语言:javascript
复制
public static void main(String[] args) {
    Date d = new Date();
    d.setDay(2020,9,15);
    d.printDate();
}
2.3.5this引用的特性

1.this的类型:对应类型类型引用,即哪个对象调用就是哪个对象的引用类型

2.this只能在成员方法中使用

3.在成员方法中,this只能引用当前对象,不能再引用其他对象

4.this是成员方法第一个隐藏参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责接收。

在代码层面来简单演示一下(下面右侧中的Date类也是可以通过编译的)

3.对象的构造和实例化

3.1对象的初始化

在Java中,在方法内定义一个局部变量时,必须要初始化,否则会编译失败。

代码语言:javascript
复制
public static void main(String[] args) {
    int a;
    System.out.println(a);
}
// Error:(26, 28) java: 可能尚未初始化变量a

上述的代码要想通过编译只需要给a赋值即可。

但如果是对象的话情况却不一样了。

代码语言:javascript
复制
public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    d.setDate(2021,6,9);
    d.printDate();
}

虽然说可以通过编译,但需要调用前面写的SetDate方法才可以将具体的日期设置到对象中。

4.构造方法

4.1概念

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

代码语言:javascript
复制
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(int,int,int)方法被调用了");
}
public void printDate() {
    System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
    // 此处创建了一个Date类型的对象,并没有显式调用构造方法
    Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
    d.printDate(); // 2021-6-9
    }
}

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

4.2特性

  1. 名字必须与类名相同
  2. 没有返回值类型,设置void也不行
  3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
  4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
代码语言:javascript
复制
public class Date {
    public int year;
    public int month;
    public int day;
    // 无参构造方法
public Date(){
    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;
}
public void printDate(){
    System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    }
}

上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载,

5.如果说用户没有显示定义,编译器会生成一份默认的构造方法,生成默认构造方法一定是无参的。

代码语言:javascript
复制
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();
    }
}

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

注意:用户一旦定义,编译器则不再生成。

代码语言:javascript
复制
public class Date {
    public int year;
    public int month;
    public int day;
    public Date(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 d = new Date();
        d.printDate();
    }
}
/*
Error:(26, 18) java: 无法将类 extend01.Date中的构造器 Date应用到给定类型;
需要: int,int,int
找到: 没有参数
原因: 实际参数列表和形式参数列表长度不同
*/

6.构造方法中,可以通过this调用其他构造方法来简化代码。

代码语言:javascript
复制
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(……)必须是构造方法中的第一句,也不能形成环。

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

7.绝大多数情况下使用public来修饰,特殊场景下会被private修饰

5.默认初始化

我们发现了一个问题,成员变量在定义时,并没有给初始值,为什么可以使用呢?

这就需要我们知道,在这个过程中,new关键字背后所发生的一些事情了。

Date d=new Date(2060,7,5);

在程序层面只是简单的一条语句,在JVM层面需要做很多事情,下面简单介绍一下:

1.检测对象对应的类是否加载了,如果没有就会加载

2.为对象分配内存空间

3.处理并发安全问题

比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突。

4.初始化所分配的空间

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

5.设置对象头信息

6.调用构造方法,给对象中各个成员赋值

6.就地初始化

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

代码语言:javascript
复制
public class Date {
    public int year = 1900;
    public int month = 1;
    public int day = 1;
    public Date(){
    }
    public Date(int year, int month, int day) {
    }
    public static void main(String[] args) {
        Date d1 = new Date(2021,6,9);
        Date d2 = new Date();
    }
}

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.面向对象
    • 1.1什么是面向对象
      • 1.2与面向过程的比较
      • 2类的定义和使用
        • 2.1简单认识类
          • 2.2类的定义格式
            • 2.3类的实例化
              • 2.3.1什么是实例化
              • 2.3.2类和对象的说明
              • 2.3.3this关键字
              • 2.3.4什么是this引用
              • 2.3.5this引用的特性
          • 3.对象的构造和实例化
            • 3.1对象的初始化
            • 4.构造方法
              • 4.1概念
                • 4.2特性
                • 5.默认初始化
                • 6.就地初始化
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档