Java宝典-类和对象

Java宝典更新啦!今天我们学习类和对象

1.面向对象

在介绍类和对象之前,我们先了解一下什么是面向对象

1.1 面向过程与面向对象

面向对象编程又称Object Oriented Programming,简称OOP,我们听说过的Java,c++都是一门面向对象编程语言.面向过程更注重一件事完成的过程,而面向对象往往会省略一些细节.
举个例子:
如何把大象放进冰箱?面向过程会关心:大象这么大怎么把它塞进去;面向对象则是:第一步:打开冰箱门,把大象塞进冰箱,关掉冰箱门,至于如何把大象塞进去,我们并不关心.

2. 类的定义和使用

类是用来描述一个对象的,例如建筑图纸,它可以描述一栋房子的属性(面积,建筑高度等),

2.1 如何定义类

Java中定义类的语法如下:

class 类名{
成员属性//成员变量
成员方法/行为
}

举个例子:
定义一个狗狗的类:

class Dog{
	public String name;
	public int age;
	public void eat(){
		System.out.println("吃饭");
	}
}

在上述类中,name和age就是Dog这个类的属性/成员变量,狗狗有自己的名字,年龄.除了有这些属性以外,狗狗也有吃饭这个行为,所以eat方法也叫成员方法或者行为.
需要注意的是:

方法名建议采用大驼峰定义
public和static是啥意思我们后续介绍,目前先按照这个方式写~

3.类的实例化

定义了类相当于定义了一个新的类型,与intf,loat这些内置类型有些类似.有了内置类型我们就可以定义一些变量,有了这些自定义的类类型我们就能很好的描述一个对象.用类类型创建对象的过程就叫做类的实例化.就比如说,光有建筑图纸怎么呀!我们得造一个真正的房子!那么如何实例化一个对象?很简单!通过new关键字:

类名 对象名 = new 类名();

我们拿上面的狗狗类举例:

Dog dog1 = new Dog();

创建好了一个对象,可以通过点号访问该对象的成员变量和成员方法.

4.this引用

想象一个场景:创建一个日期类,成员变量有年,月,日,成员方法setDate的功能是通过参数传递来设置日期,printDate打印我们设置的日期.
如下代码:

class Date {
    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);
    }
}

在main方法中调实例化一个对象,

    public static void main(String[] args) {
        Date d1 = new Date();
        d1.setDate(2024, 3, 1);
        d1.printDate();
    }

运行结果:
在这里插入图片描述
假如我们把printDate的形参名改成和成员变量名一样会怎么样呢?
我们再次运行:
在这里插入图片描述

可以发现,结果并不是我们想要的!这是为何?回答这个问题前,我们先得了解Java程序是如何运行的,以及Java虚拟机对内存的划分.
首先:Java程序的运行时,代码需要加载到内存当中,某些数据也需要存放在内存中,而我们的Java虚拟机可以帮我们完成这个工作!
Java虚拟机将内存划分了五个区域,如图
在这里插入图片描述
目前我们只需要了解两点:

  1. 虚拟机栈:方法调用时会在栈上开辟栈帧,栈帧中会保存局部变量
  2. 堆:new创建的对象是在堆上保存
    由此我们能知道通过Date创建的对象d1的内存布局
    在这里插入图片描述
    当调用setDate方法时,会在栈上开辟栈帧,如果形参名和成员变量名重复,局部变量优先原则,
    下面代码中的year,month,day都表示形参
year = year;
month = month;
day = day;

那么,我们就是想让形参名和成员变量名重复,并且还要表示成员变量,怎么做?加上this点号!
改正之后的代码就是:

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

代码中加了this.的year代表的是成员变量,不加this.的year就代表形参year
原理:我们在类中定义的方法,参数列表会有隐藏的参数this,只是我们看不到而已
完整的参数应该是这样的:

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

我们实例化对象时,编译器会自动帮我们把对象的引用传递过去让this接收,无需手动.所以this也表示当前对象的引用,一般情况下我们不会让形参和成员变量同名,所以不加this也是可以的,但是我们建议要习惯加上this.

5.构造方法

5.1 什么是构造方法

构造方法是一个特殊的成员方法,该方法名字必须和类名相同,构造方法没有返回值,在创建对象时,编译器会自动调用构造方法

5.2 构造方法的特点

  1. 名字与类名相同
  2. 没有返回值,void也不行
  3. 构造方法可以重载,用户可以自己提供带一个或者多个参数的构造方法
  4. 如果用户不提供构造方法,编译器会默认提供一份不带参数的构造方法,如果用户自己提供了构造方法,编译器则不会再提供不带参数的构造方法
  5. 如果构成重载,可以通过this(…)在某个构造方法中调用其他构造方法,但是this(…)必须在第一条语句中,并且不能成环调用
    拿Date类举例:
//不带参数的构造方法
    public Date() {
        this(2024);//调用带一个参数的构造方法
    }

    //带1个参数的构造方法
    public Date(int year) {
    	//this();会报错,因为不带参数的构造方法已经调用过本方法,而本方法又调用不带参数的构造方法,形成环
    }

    //带2个参数的构造方法
    public Date(int year, int month) {
		
    }

    //带3个参数的构造方法
    public Date(int year, int month, int day) {

    }

6.包

为了更好地管理类,把多个相关联的类整理在一起的组合称为包,类似文件夹,一个文件夹中有很多个相关联的文件

6.1 导包

通过import可以导入某个包里面的类,例如:使用Arrays类,可以使用import java.util.Arrays;来导入Arrays类

6.2 自定义包

用户可以自定义包,在IDEA中自定义包的步骤
在这里插入图片描述
自定义包在文件中第一行最好加上package语句声明该代码在哪个包,不过没关系~ IDEA会自动添加!

7.封装

封装,继承,多态是面向对象的三大特性.类和对象主要研究的是封装.封装可以简单理解为:将数据和操作数据的方法有机结合,隐藏对象的属性和实现细节,只提供公开的接口来和对象进行交互.在Java中通过访问权限来实现封装

8.访问限定符

Java中有三种访问限定符,四种访问权限
访问限定符有:private,protected,public.private表示私有访问权限,public表示公开访问权限,如果什么都不加表示默认的权限,protected主要运用在继承中,后续介绍.
在这里插入图片描述

9.static

9.1 static修饰的成员变量

被static修饰的变量叫做静态成员变量,被static修饰之后,该变量也就不属于某个具体的对象了,而是属于类(也称类变量),所有对象都共享,类变量储存在方法区中.

class Student {
    public String name;
    public int age;
    public static String classname;
}

访问static修饰的变量一般通过类名访问,通过对象也是可以的,但是推荐使用类名访问

public static void main(String[] args) {
        Student stu1 = new Student();
        Student.classname = "Java1班";
        System.out.println(Student.classname);
    }

输出结果:
在这里插入图片描述
需要注意的是:即使不创建对象,也能访问static修饰的成员变量,这更加说明了静态变量不属于某个具体的对象,而是属于类

9.2 static修饰的成员方法

被static修饰的方法称为静态成员方法,和静态成员变量一样,它不属于某个具体的对象,而是类方法,它也可以通过对象调用,也可以通过类名调用,更推荐使用类名调用.
注意:静态成员方法不依赖于对象,不能在静态方法中访问非静态的成员,也不能使用this

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

    public static void staticFunc() {
         Student.classname = "Java1班";
         System.out.println(classname);
//        System.out.println(this.age);//错误
        System.out.println("静态方法");
    }
}
public static void main(String[] args) {
        Student.staticFunc();
        Student stu1 = new Student();
        stu1.staticFunc();
    }

输出结果:
在这里插入图片描述

10.代码块

用{}定义的一段代码叫代码块,代码块分为以下几种:

  • 普通代码块
  • 构造代码块
  • 静态代码块
  • 同步代码块(目前接触不到,学习多线程时介绍)

10.1 普通代码块

普通代码块就是定义在方法中的代码块.

public class Main {
    public static void main(String[] args) {
        {
            System.out.println("普通代码块");
        }
    }
}

10.2 构造代码块

构造代码块就是定义在类内部,方法外部并且不加修饰符的代码块,也叫实例代码块

class Student {
    public String name;
    public int age;

    {
        System.out.println("构造/实例代码块");
    }

    public void func() {
        //.......
    }
}

构造代码块一般用于初始化实例成员变量(非静态),实例代码块在创建对象时才会执行

10.3 静态代码块

在类中用static修饰的变量叫静态代码块
,一般用于初始化静态成员变量

class Student {
    public String name;
    public int age;

    {
        System.out.println("构造/实例代码块");
    }

	static{
        System.out.println("静态代码块");
    }
    public void func() {
        //.......
    }
}

注意事项:

  1. 不管生成多少个对象,静态代码块都只执行一次
  2. 如果包含多个静态代码块,编译器会按代码书写顺序执行
  3. 静态代码块在jvm加载类时开辟空间并且初始化

未完待续…

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值