目录
- 1.面向对象
- 1.1 面向过程与面向对象
- 2. 类的定义和使用
- 2.1 如何定义类
- 3.类的实例化
- 4.this引用
- 5.构造方法
- 5.1 什么是构造方法
- 5.2 构造方法的特点
- 6.包
- 6.1 导包
- 6.2 自定义包
- 7.封装
- 8.访问限定符
- 9.static
- 9.1 static修饰的成员变量
- 9.2 static修饰的成员方法
- 10.代码块
- 10.1 普通代码块
- 10.2 构造代码块
- 10.3 静态代码块
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虚拟机将内存划分了五个区域,如图
目前我们只需要了解两点:
- 虚拟机栈:方法调用时会在栈上开辟栈帧,栈帧中会保存局部变量
- 堆: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 构造方法的特点
- 名字与类名相同
- 没有返回值,void也不行
- 构造方法可以重载,用户可以自己提供带一个或者多个参数的构造方法
- 如果用户不提供构造方法,编译器会默认提供一份不带参数的构造方法,如果用户自己提供了构造方法,编译器则不会再提供不带参数的构造方法
- 如果构成重载,可以通过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() {
//.......
}
}
注意事项:
- 不管生成多少个对象,静态代码块都只执行一次
- 如果包含多个静态代码块,编译器会按代码书写顺序执行
- 静态代码块在jvm加载类时开辟空间并且初始化
未完待续…