类和对象
# 类和对象
- 面向对象的两个要素:类和对象。
- 类(Class)和对象(Object)是面向对象的核心概念。
- 类是对一类事物的描述,是抽象的、概念上的定义
- 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
- “万事万物皆对象”
可以理解为:类 = 抽象概念的人;对象 = 实实在在的某个人
面向对象程序设计的重点是类的设计
类的设计,其实就是类的成员的设计
# Java类及类的成员
现实世界的生物体,大到鲸鱼,小到蚂蚁,都是由最基本的细胞构成的。同理,Java代码世界是由诸多个不同功能的类构成的。
现实生物世界中的细胞又是由什么构成的呢?细胞核、细胞质、… 那么,
Java中用类class
来描述事物也是如此。常见的类的成员有:
- 属性:对应类中的成员变量 =
field
= 域、字段 - 行为:对应类中的成员方法 = 函数 =
method
# 类的语法格式
修饰符 class 类名{
属性声明;
方法声明;
}
2
3
4
修饰符public
:类可以被任意访问。
类的正文要用{ }括起来,{}就是作用域。
==注意:类名第一个字母要大写才符合规范==
# 创建Java自定义类
步骤:
定义类(考虑修饰符、类名)
编写类的属性(考虑修饰符、属性类型、属性名、初始化值)
编写类的方法(考虑修饰符、返回值类型、方法名、形参等)
比如:
package oopTest;
public class Person {
int age;
String name;
int gender;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 类的创建和使用
创建对象语法: 类名 对象名 = new 类名();
使用对象名.对象成员的方式访问对象成员(包括属性和方法)
Person p = new Person();
p.name = "张三";
p.age = 18;
p.setGender(1);
int name1 = p.name;
int name2 = p.getName();
System.out.println(p.getAge())
2
3
4
5
6
7
创建对象,在有些地方也叫初始化或者实例化。
注意
如果创建了一个类的多个对象,每个对象都会在堆内存开辟新的空间,内存地址也是独立的,每个对象都独立的拥有一套类的属性。(非static
)
意味着,如果去修改一个对象的属性a,则不影响另一个对象属性a的值。
如果把一个新的引用指向已经存在的对象,通过这个变量改变对象的值时,那么原来的变量访问对象的值时,会发现也改变了,因为2个引用都指向同一个对象的内存地址。
Person p1 = new Person();
p1.setNmae("zhangsan");
p1.setAge(18);
Person p3 = p1;
p3.setAge(10);
Sysout.out.println(p1.age);//会返回10而不是18,因为2个引用指向一个对象,都是同一个内存地址。
2
3
4
5
6
7
什么是引用?
int i;//创建一个引用
int j = 10;//创建一个引用并且把10赋值给这个引用
Person p1;//创建一个引用
Person p2 = new Person();//创建一个引用,并且在堆空间中实例一个对象,这个引用指向这个对象。
2
3
4
如果非要比喻的话:
引用,可以理解为遥控器。
对象,理解为电视机。
引用可以多个,那么遥控器可以多个,也可以独立存在,任意一个遥控器改变了电视频道,就像代码中,使用其中一个引用改变对象的值,那么第二个引用去访问对象时,发现对象的值已经改变了,因为2个引用都指向同一个对象的内存地址。
# 内存解析
堆(
Heap
),此内存区域的唯一目的就是==存放对象实例==,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。通常所说的栈(
Stack
),是指==虚拟机栈==。虚拟机栈用于==存储局部变量==等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。==方法执行完,自动释放==。方法区(
MethodArea
),用于==存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据==。
# 匿名对象
==匿名对象==就是没有明确的给出名字的对象。一般匿名对象只使用一次,而且==匿名对象==只在堆内存中开辟空间,而不存在栈内存的引用。
比如:
new Person().eat();
new Person().sleep();
2
一般匿名对象只使用一次,但是有时也存在一些场景,把匿名对象的内存整数地址传递给另一个方法继续使用。
比如:
House h = new House();
h.in(new Person())
public class House{
public void in(Person person){
System.out.println("他在这个屋子生活了"+person.age+"年");
}
}
2
3
4
5
6
7
8
# 对象与数组
数组的语法格式还记得吗?
数据类型[] 变量名 = new 数据类型[长度]
其实数据类型不止是基本数据类型,对象也是一种数据类型,只不过不属于基本数据类型而已。
比如:
Person[] personArr = new Person[10];
for(int i=0;i<personArr.length;i++){
personArr[i] = new Person();//实例化
personArr[i].setAge(18);
}
2
3
4
5
本质意义上其实和数组一样使用,而且如果复制数组不能直接赋值。具体可以回去数组章节中查看。