一、面向对象和面向过程
- 面向过程
优点: 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗
资源;比如单片机、嵌入式开发、 Linux 等一般采用面向过程开发,性能是
最重要的因素。
缺点: 没有面向对象易维护、易复用、易扩展 - 面向对象
优点: 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特
性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点: 性能比面向过程低
二、类和对象
类是一种抽象,而对象是类的实例,对象可以被多次创建
/**
*定义一个宠物狗类
*
*/
class PetDog {
public String name;//名字
public String color;//颜色
// 狗的属性
public void barks() {
System.out.println(name + ": 旺旺旺~~~");
}
public void wag() {
System.out.println(name + ": 摇尾巴~~~");
}
}
public class Test {
public static void main(String[] args) {
//对象的构造和初始化
PetDog petDog = new PetDog();
petDog.color = "red";
petDog.name = "汪汪";
petDog.barks();
petDog.wag();
}
}
一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
✅对象实体和对象引用的区别?
new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向 0 个或 1 个对象 ;一个对象可以有 n 个引用指向它。
三、this引用
this表示当前对象的引用,(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问,
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
/**
* 1.this。成员变量
*/
this.year = year;
//this.year=year语句表示一个赋值语句,等号左边的this.year是指当前对象具有的变量year,等号右边的year表示参数传递过来的数值。
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(this.year + "/" + this.month + "/" + this.day);
}
public void changeDate(int year,int month,int day){
/**
* 2.this.成员方法
*/
this.printDate();
System.out.println("开始修改");
this.year = year;
this.month = month;
this.day = day;
}
}
- this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用
- this只能在"成员方法"中使用
- 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
四、构造方法
构造方法(也称为构造器)是一个特殊的成员方法
- 名字与类名相同,没有返回值类型,设置为void也不行
- 一般情况下使用public修饰
- 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
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)方法被调用了");
}
/**
*3.this.构造方法
*/
public Date(){
this(2003,8,9);
System.out.println("调用无参的构造方法");
}
public static void main(String[] args) {
Date d1 = new Date(); //构造方法已被重载,原有的构造方法不能再使用
Date d2 = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
}
}
/**
*解决方法
*public Date(){}
*再增加一个无参的构造方法
*/
//上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载
上述Date类中,没有定义任何构造方法,编译器会默认生成一个不,带参数的构造方法。
- 注意:一旦用户定义,编译器则不再生成。
- this(...)必须是构造方法中第一条语句,不能形成环
五. 对象初始化
成员变量在定义时,并没有给初始值, 为什么就可以使用呢?
Student s = new Student():
在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:
- 检测对象对应的类是否加载了,如果没有加载则加载
- 为对象分配内存空间
- 处理并发安全问题 , 比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
- 初始化所分配的空间 即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,如下表
- 设置对象头信息(关于对象内存模型后面会介绍)
- 调用构造方法,给对象中各个成员赋值
数据类型 | 默认值 |
---|---|
byte | 0 |
char | '\u0000' |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |
就地初始化
public class Date {
public int year = 1900;
//定义时即赋值
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}