类与对象——Java中一切皆对象(第一篇)

在我Java的数据类型与变量的开篇我提到过,面向对象的编程语言真的拥有其独一无二的魅力,那么到底什么是对象?什么是面向对象呢?今天我们就来一探究竟~

面向对象的基本概念

很多编程入门课程在讲述面向对象的概念时,都会用到“洗衣服”这个很“烂”但是又很经典的例子。关于这个例子,老师们会这样讲:
1.传统洗衣服
image.png
传统的方式:注重的是洗衣服的过程,少了一个环节可能都不行。 而且不同衣服洗的方式,时间长度,拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另 一种放方式。
按照该种方式来写代码,将来扩展或者维护起来会比较麻烦。
2.而对于现代洗衣服则是面向对象的
以面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关 心,只需要将衣服放进洗衣机,导入洗衣粉,启动开关即可,通过对象之间的交互来完成的。
image.png
其实一开始听到这个例子的时候,给我脑海里植入的概念完全是相反的——我认为手洗衣服难道不应该是更针对衣服这个对象吗?哈哈~换一种思路去理解这个问题或许就会豁然开朗了:比如说,你的衣服上有一块儿油,如果你用手洗的话,是不是应该先找到这块儿油,然后针对着搓洗,这是不是有先后顺序?这就是面向过程,但如果你用洗衣机(无敌牛逼的那种,一洗就干净),那你把衣服丢进去就不用管了,这就是面向对象!
当然,在这里还是要提一句:面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。

类定义和使用

类是什么东西?

在一门学科里,总是会把一些简单的东西说得高大上,这样才会显得学科更有逼格!简单来说,类就是一个实体对象的属性,用来描述一个对象的特点。比如说一个人的身高,体重,年龄,我们转换成计算机语言以后(用类去描述),计算机就可以成功识别了!

类的定义格式

在Java中定义类时需要用到class关键字~

class ClassName{
    field;
    method;
}

class是定义类的关键字,ClassName为类的名字,{}中为类的主体。
类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量
方法主要说明类具有哪些功能,称为类的成员方法
eg:定义一个dog类

public class blog0402 {
    class Dog {
        public String name;
        public String color;

        public void barks(){
            System.out.println(name+"wolfwolf~~~");
        }
        
        public void wag(){
            System.out.println(name+"摇尾巴~");
        }
    }
}

看看这个简单的小栗子:首先我们使用class关键字创建了一个Dog类,注意奥——类名一定要用大驼峰,所以这里的dog的d要大写。接下来定义的name和color都是我们上面提到的成员属性(成员变量),而下面创建的public void 是不是跟我们创建方法的语句一样呢?这里就是类的成员方法。能够简单的对应起来之后,我们接着往下看吧~

类的实例化

定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:Dog类。这就是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
用类类型创建对象的过程,称为类的实例化,Java中采用new关键字来配合实例化的过程。就好比每次初始化一个变量,我们是不是会写类似 int a = 10;这样的语句?是一样的,只不过现在是在用户自己创建的类型里面实例化你的对象,我们需要约束语法。

  • new关键字用于创建一个对象的实例

用new关键字创建的时候我们其实可以类比Scanner的用法,我们是不是经常会写到下面这几句话:

Scanner sc = new Scanner(System.in);
int a = sc.nextInt();

这其实就是一个实例化的过程,我们用new关键字创建了一个Scanner类的一个新实例,而Scanner类的构造函数接受了一个参数System.in,表示从键盘读入数据。
Scanner sc声明一个Scanner类型的变量sc,并将新创建的Scanner实例赋值给它。

  • 我们一般使用**"** . "来访问对象中的属性和方法(可以类比我们Math.()的用法)
  • 同一个类可以创建多个实例**(就好像可以用相同的图纸造出不完全相同的房子,Dog类里也能创建不同品种的狗狗)**

this引用

this引用指向当前对象,在成员方法中所有成员变量的操作,都是通过该引用去访问。 看一段简单的示例:

public class Date {

    public static void main(String[] args) {
        Date d = new Date();
        d.setDay(2020,9,15);
        d.printDate();
    }
    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.year等就是为了指明:我现在调用的year是类里面的成员变量,而后面那个不加this的year是形式参数。

this类的使用特性

  1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
  2. this只能在"成员方法"中使用
  3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象,这句话的意思就是:
class MyClass {
    void myMethod() {
        MyClass otherObject = new MyClass();
        this = otherObject; // 不能将 this 指向其他对象
    }
}

对象的构造及初始化

通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。那么我们的对象又该如何进行初始化呢?——那就要提到我们的构造方法了。

构造方法

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

看栗子:

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;
        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
    }
}

重点来啦!!!—— 如果用户没有显式定义构造方法,那么编译器会生成一份默认的构造方法,且生成的默认构造方法一定是无参的。 看下面↓

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类中,没有定义任何构造方法,编译器就会默认生成一个不带参数的构造方法Date(),所以我们在实例化Date的时候才能如此顺利。

在一个构造方法中我们还可以用this来调用其他的构造方法,但是注意:this的调用语句必须在构造方法的第一行。

public class Date {
    public int year;
    public int month;
    public int day;

    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;
    }
}

我们在无参的构造方法Date()中用this调用含有三个参数的构造方法。

默认初始化

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

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

其实在我们运用new关键字的时候,在jvm层面进行了很多操作:

  1. 检测对象对应的类是否加载了,如果没有加载则加载
  2. 为对象分配内存空间
  3. 处理并发安全问题
    比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
  4. 初始化所分配的空间
  5. 设置对象头信息
  6. 调用构造方法,给对象中各个成员赋值

这里我们就简单了解一下,总的来说就是在我们进行new关键字操作的时候,对象中包含的成员已经进行了一个默认的初始化操作,也就是已经初始化过了,并不是没有初始化。

这篇文章总体介绍了一下类和对象的基本概念,以及this的使用和构造方法,我们在类与对象的第二篇就来看看封装的概念以及”包“。希望对你有点点的帮助!

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值