类和对象(Java)

目录

1.面向对象的认识

1.1什么是面向对象

1.2面向对象和面向过程

2.类的定义和使用

2.1认识类

2.2类的定义

3.类的实例化

3.1什么是实例化

3.2类和对象的说明

4.this引用

4.1为什么要有this 引用

4.2什么是this引用

5.对象的初始化及构造

5.1对象的初始化

5.2构造方法

6.封装

6.1封装的概念

6.2访问限定符

7.static成员

7.1static修饰成员变量

7.2static修饰成员方法

8.代码块

8.1普通代码块

8.2构造代码块

8.3静态代码块

8.4总结


1.面向对象的认识

1.1什么是面向对象

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

1.2面向对象和面向过程

举个例子,我们就拿洗衣服来说。以前我们在手搓衣服的时候,都要经历准备洗衣服的盆子->放水->放衣服->放洗衣粉->手搓->换水->手搓->拧干->晾衣服等过程。这种传统的方式,注重的是洗衣服的过程。但是对于不同衣服,我们要洗的方式,时间以及怎么拧干都不同,处理起来比较麻烦,如果按照这种方式来写我们的代码,对于之后的扩展和维护都会很麻烦。

所以现在大家普遍都使用洗衣机洗衣服,我们只需将衣服放进洗衣机,加入洗衣粉,启动洗衣机,然后洗衣机就能完成洗衣服的工作并脱水。这一系列是由:人、衣服、洗衣粉、洗衣机,四个对象之间交互完成的。而我们并不需要关心洗衣机到底是怎么洗衣服的,又是如何甩干的,只需将衣服和洗衣粉放进洗衣机,再启动开关即可,是通过对象之间的交互来完成的

我们所说的传统手搓衣服就是面向过程,而用洗衣机洗衣服就是面向对象了。

面向过程的编程主要关注的是过程,面向对象的编程是指对象与对象之间协作完成,关注的是对象。

不过需要注意的是:面向过程和面向对象并不是一门语言,而是解决问题的方法,没有好坏之分,都有其专门的应用场景。

2.类的定义和使用

2.1认识类

类是用来描述对象的。我们上述提到的洗衣机,它的某个品牌在java中可以看作是一个类别,而每台洗衣机都会有品牌、型号、功率、容量等这些属性,还有它洗衣服的功能。对洗衣机属性的描述,我们把这个过程称为对洗衣机对象(实体)进行抽象,就像开发人员可以采用某种面向对象的编程语言来进行描述,比如:java。

2.2类的定义

在java中定义类要用到关键字:class

一个类中可以包含:字段(属性/成员变量),成员方法

字段:一般定义在类中,方法的外面。

我们定义一个狗类来作为例子:

class Dog {
    public String name;
    public int age;

    public void bark() {
        System.out.println(name + "在汪汪叫");
    }
}

这段代码中class是定义类的关键字,Dog是类的名字,{}中是类的主体。name和age是字段,bark()是成员方法

类可以理解为自定义类型。

注意:

  • 类名必须采用大驼峰
  • 成员前写法统一为public
  • 此处写的方法不带static
  • 一般一个文件中只定义一个类
  • main方法所在的类一般要用public修饰
  • public修饰的类必须要和文件名相同
  • 不要随便修改public修饰类的名称

3.类的实例化

3.1什么是实例化

由类生成对象的过程叫作实例化。java中使用关键字new对对象进行实例化。

那我们来对上面我们创建的狗类进行实例化:

public class test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.name = "小黄";
        dog1.age = 3;
        dog1.bark();

        Dog dog2 = new Dog();
        dog2.name = "小黑";
        dog2.age = 4;
        dog2.bark();
    }
}

输出的结果是:

注意:

  • new关键字用于创建一个对象的实例
  • 使用“ . ”来访问对象中的属性和方法(通过对象的引用可以访问对象的成员变量,同时也可以访问对象的成员方法)
  • 同一个类可以创建多个实例

3.2类和对象的说明

  • 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员
  • 类是一种自定义的类型,可以用来定义变量
  • 一个类可以实例化多个对象,实例化出的对象占用实际的物理空间,存储成员变量

4.this引用

4.1为什么要有this 引用

首先我们先创建一个Date类:

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 getDay() {
        System.out.println(year + "/" + month + "/" + day);
    }
}

第一个方法中我们采用形参赋值的方式给对象进行初始化,此时我们的形参是y, m, d,那么如果我们把形参改成和成员变量名相同的year, month, day会怎样呢?

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

很显然最后运行出来肯定不可能按照我们的预期完成日期的初始化,那这是什么原因呢?

  • 当成员方法中形参和成员变量名相同,形参自己给自己赋值,并没有修改对象中的值。是因为此时在方法内,形参都是局部变量,局部变量优先使用。

那么如果我们非要让形参和成员变量名相同,这个时候就需要用到this引用

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

此时就可以正常对对象进行初始化了。

那么当我们在实例化多个对象的时候,date1和date2两个对象都在调用setDay和getDay方法,如下:

    public static void main(String[] args) {
        Date date1 = new Date();
        Date date2 = new Date();
        date1.setDay(2005, 06, 06);
        date1.getDay();

        date2.setDay(2000, 02, 14);
        date2.getDay();
    }

 那么问题来了,这么多对象都调用了同一个setDay方法,该怎么区分是哪个对象调用的setDay方法中的year, month, day

这个时候就需要this来解决这个问题了。

4.2什么是this引用

this代表当前对象的引用,哪个对象的引用调用了该方法,this就代表哪个对象。

上述date1调用了setDay方法,此时该方法里的this就代表了date1对象。

那么this是如何传递的呢?

其实this就是隐藏的第一个参数。

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

this的三种用法

  • 可以通过this访问 当前对象的成员变量
  • 可以通过this访问 当前对象的非静态的成员方法
  • 可以通过this访问 当前对象的其他构造方法

注意

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

5.对象的初始化及构造

5.1对象的初始化

我们先来简单定义一个变量a:

    public static void main(String[] args) {
        int a;
        System.out.println(a);
    }

直接输出得到的结果是:

可见局部变量不进行初始化无法通过编译。

那么我们再来看下一段代码:

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

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

    public void getDay() {
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
}
public class test2 {
    public static void main(String[] args) {
        Date date = new Date();
        date.getDay();
    }
}

我们在不给成员变量赋任何初始值的情况下输出的结果是:

我们可以得到:成员变量会有一个默认的初始值,可以不进行初始化,而局部变量必须先初始化

5.2构造方法

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

普通方法和构造方法的区别:

以上述Date类为例,构造方法为:

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

实例化对象的时候可以调用构造方法对对象进行初始化,如:

    public static void main(String[] args) {
        Date date = new Date(2005, 06, 06);
    }

在实例化对象的时候一定会调用构造方法。

上面提到可以通过this引用访问当前对象的其他构造方法,需要注意的是this( ),必须在第一行!!如:

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public Date() {
        this(2005, 06, 06);
    }

注意

  • 构造方法名字必须与类名相同
  • 没有返回值类型,设置为void也不行
  • 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
  • 构造方法是可以发生重载的,可以有多个构造方法(名字相同,参数列表不同就可以构成方法的重载)
  • 当没写任何构造方法的时候,Java会提供一个不带参数的构造方法,但一旦有其他构造方法,就不会提供了
  • 构造方法中,可以通过this调用其他构造方法来简化代码且this(…)必须是构造方法中的第一条语句。不能形成环!!(两个构造方法中不能互相用this来调用对方)
  • 绝大多数情况下使用public来修饰,特殊情况下会被private修饰

6.封装

6.1封装的概念

面向对象的程序三大特征:封装、继承、多态。类和对象阶段主要研究封装。封装就是将数据和操作数据的方法有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互

简单来说封装就是对外隐藏类内部的实现细节

6.2访问限定符

java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。如下:

说明:

  • protected主要用在继承中
  • default即什么都不写,为默认权限
  • 访问权限除了可以限定类中的成员的可见性,也可以控制类的可见性

注意一般情况下成员变量设置为private,成员方法设置为public

7.static成员

7.1static修饰成员变量

static修饰的成员变量,称为静态成员变量。静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的

静态成员变量的特性:

  • 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
  • 既可以通过对象访问,也可以通过类名访问,一般更推荐使用类名访问
  • 静态成员变量也叫类变量,存储在方法区中
  • 生命周期伴随类的一生(随类的加载而创建,随类的卸载而销毁)

代码示例:

class Students {
    public String name;
    public String gender;
    public int age;
    public static String classRoom = "B03";

    public Students(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }
}
public class student {
    public static void main(String[] args) {
        Students stu1 = new Students("xiaoyi", "female", 19);
        Students stu2 = new Students("xiaoming", "male", 20);
        Students stu3 = new Students("huahua", "female", 19);
        //被static修饰,可以直接通过类名访问
        System.out.println(Students.classRoom);
    }
}

7.2static修饰成员方法

java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。如:

class Students {
    public static String classRoom = "B03";

    public static String getClassRoom() {
        return classRoom;
    }
}

静态方法特性:

  • 不属于某个具体的对象,是类方法
  • 可以通过对象调用,也可以通过类名.静态方法名()方式调用,更推荐后者
  • 不能在静态方法中访问任何非静态成员变量
  • 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用

总结:在静态方法中不能直接使用任何非静态的成员变量和成员方法。要想使用,要通过new对象,然后通过对象的引用访问。但是在非静态成员方法中,可以直接使用静态的成员方法或静态的成员变量

8.代码块

8.1普通代码块

定义在方法中的代码块,如:

    public static void main(String[] args) {
        {
            int a = 10;
            System.out.println("a = " + a);
        }
    }

8.2构造代码块

定义在类中的代码块,也叫实例代码块。构造代码块一般用于初始化实例成员变量。如:

class Cat {
    public String name;
    public int age;
    //实例代码块
    {
        this.name = "xiaoming";
        this.age = 4;
    }
}

8.3静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量

class Students {
    public static String classRoom;
    //静态代码块
    static {
        classRoom = "A06";
    }
}

8.4总结

多个代码块同时存在时,运行顺序静态代码块>实例代码块(和定义顺序无关)

同一代码块的运行结果与定义顺序有关。

注意

  • 静态代码块不管生成多少个对象,其只会执行一次
  • 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
  • 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行
  • 实例代码块只有在创建对象时才会执行
  • 16
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值