一、是什么是面向对象
面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事。
例如:将大象放进冰箱这个经典的例子。
\
在学习C语言时,我们主要关注的是如何将大象放入冰箱的过程,怎么打开冰箱,怎么将大象放入冰箱的过程,以及怎么关上冰箱的过程,对其进行实现。
而面向对象这一语言的特点是,我们只需要关注对象有哪些即可,它的实现的过程我们不需要关系。而对象有哪些呢,在这个例子中的对象是冰箱和大象,通过对象之间的交互来实现。
总的来说,什么是对象,在Java的世界里,一切皆为对象。如生活中真实存在的事物都可以称之为对象。
二、类的定义和使用
2.1 类的认识
类就是用来描述一个实体(对象)的。这个实体(对象)所具有的属性和功能。
例如在C语言中,我们经常对一个学生进行描述,自定义一个结构体。而类的定义与其或有不同。C语言中只能定义学生的属性,如姓名、年龄等,而类不仅可以定义学生的属性还能在类中定义学生所具有的“功能”,如上课,吃饭等行为。
2.2 类的定义及使用
class Student {
//字段/属性/成员变量
public String name;
public int age;
//成员方法
public void eat() {
System.out.println("吃东西");
}
}
上面的代码中,Student就是类名,name和age是该类的成员变量,eat()是该类的成员方法。
注意事项:
- 类名需要采用大驼峰定义
- 在当前的学习阶段统一为public,后续会讲解,如果对其已经学习过的可忽略。
- 此处写的成员方法暂时不用static关键字,后续会讲解,如果对其已经学习过的可忽略。
- 成员变量会有一个默认值,引用类型默认为null,基本数据类型默认为对应的0值。
我们可以再举一个例子,留给大家自己思考,自己动手写一写代码。写一个动物类,如狗,它的名字、姓名等成员变量,吃东西等行为的成员方法。
三、类的实例化
3.1 什么是实例化
定义了一个类,就相当于在计算机中定义了一个新的类型。用类的类型创建对象的过程就叫实例化。在Java中用new关键字,配合类名来实例化对象。
class Student {
public String name;
public int age;
public void eat() {
System.out.println("吃东西");
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.name = "zhangsan";
System.out.println(student.name);
student.age = 3;
System.out.println(student.age);
student.eat();
}
}
输出结果如下
3.2 类和对象的说明
- 类一个模型,用来对一个实体(对象)进行描述,限定了这个类有哪些成员。
- 类是一种自定义的类型,可以用来定义变量
- 一个类可以实例化多个对象
- 实例化出的对象才能储存数据,占用物理空间
四、this引用
我们先来看一下这个段代码
class Date {
int year;
int month;
int day;
public void setDate(int year,int month,int day) {
year = year;
month = month;
day = day;
}
public void getDate() {
System.out.println(year + "/" + month +"/" + day);
}
}
public class Test1 {
public static void main(String[] args) {
Date date = new Date();
date.setDate(2003,2,2);
date.getDate();
}
}
运行结果如下
在setDate方法中,在赋值=的两端,year,month,day到低是指成员变量,还是指形参呢?
为什么给参数赋值输出的结果还没有改变呢?这是因为在方法类,year、month、day都是局部变量,此时局部变量会优先使用,相当于,形参给形参自己赋值,而并没有修改到对象当中的year,month,day。
这个问题的解决方法就是在赋值的左边加上this.就可以了。
public void setDate(int year,int month,int day) {
this.year = year;
this.month = month;
this.day = day;
}
那this关键字到底代表什么呢?this代表了当前对象的引用。
哪个对象的引用调用了该方法,this就代表哪个对象的引用,而这个this就是该方法的一个隐藏参数。在方法中也建议加上this(虽然可以不加)
标准的代码过程如下
public class Date {
int year;
int month;
int day;
public void setDate(int year,int month,int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void getDate() {
System.out.println(this.year + "/" + this.month +"/" + this.day);
}
}
public class Test1 {
public static void main(String[] args) {
Date date = new Date();
date.setDate(2003,2,2);
date.getDate();
}
}
运行结果如下
4.1 this的特性
- this的类型:对应类型引用,即哪个对象调用就是哪个对象的引用类型
- this只能在“成员方法”中使用
- 在“成员方法”中,this只能引用当前对象,不能再引用其他对象
- this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收
4.2 this的三种用法
- 通过this访问当前对象的成员变量
- 通过this访问当前对象的非静态的成员方法
- 通过this访问当前对象的其他构造方法
五、对象的构造及初始化
5.1 如何初始化对象
在Date类中增加getter和setter方法(快捷键alt+insert ->Getter and Setter)初始化对象
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public class Test1 {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date.getYear());
date.setYear(2004);
System.out.println(date.getYear());
}
}
5.2 构造方法
5.2.1 概念
构造方法是一个特殊的成员方法,名字必须和类名相同,在不能有返回值,void也不行,在整个对象的生命周期内只调用一次。
构造方法的作用是对对象中的成员进行初始化,并不负责给对象开辟空间。
若没有自定义构造方法,Java会提供一个默认的不带参数的构造方法,一旦自定义了构造方法,Java就不会再提供任何构造方法。
在一个类中可以有多个构造方法,产生方法的重载。
可以借助IDEA 自动生成 构造方法(alt +intsert ->Constructor)
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public Date(int year) {
this.year = year;
}
public Date(int year, int month) {
this.year = year;
this.month = month;
}
public class Test1 {
public static void main(String[] args) {
Date date = new Date(2004,1,1);
date.getDate();
Date date1 = new Date(2004);
date1.getDate();
Date date2 = new Date(2004,2);
date2.getDate();
}
}
运行结构如下
若在Test类中再实例化一个构造方法没有参数的对象时,编译器会报错。
在构造方法中,通过this可以调用其他构造方法来简化代码
public Date() {
this(2003,1,1);
}
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public class Test1 {
public static void main(String[] args) {
Date date3 = new Date();
date3.getDate();
}
}
要注意的是this(...)必须是构造方法的第一条语句,并且不能让构造方法之间形成环形,会造成构造器的递归编译错误。
5.3 默认初始化
Date date = new Date(2021,1,1)
在程序层面只是简单的一条语句,在JVM层需要做很多事,如下:
- 检测对象对应的类是否加载了,如果没有加载则加载:加载是指将字节码文件加载到JVM中解析成Class对象。
- 为对象分配内存空间
- 处理并发安全问题
- 初始化所分配的空间:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,boolean:false 其余基本类型为其对应的0值,如double:0.0 引用类型默认为null,如String:null。
- 设置对象头信息
- 调用构造方法,给对象中各个成员赋值
5.4 就地初始化
在声明变量时,直接给出了初始值
public class Date {
public int year = 2001;
public int month = 2;
public int day = 10;
}
public class Test1 {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date.year);
System.out.println(date.month);
System.out.println(date.day);
}
}
注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。
下章预告
封装、static关键字、代码块