1.1 类与对象

1.1.1 类与对象的关系

在面向对象中,类和对象是最基本、最重要的组成单元。类实际上是表示一个客观世界某类群体的一些基本特征抽象。对象就是表示一个个具体的东西。例如,在显示生活中,人就可以表示一个类,因为人本省属于一种广义的概念,并不是一个具体的。而某一个具体的人,就可以称为对象,可以通过各种信息完整的描述这个具体的人,如这个人的姓名、年龄、性别等信息,这些信息在面向对象的概念中就称为属性;当然人是可以吃饭、睡觉的,这些人的行为在类中就称为方法。也就是说如果要使用一个类,就一定有产生对象, 每个对象之间是靠各个属性的不同来进行区分的,而每个对象所具备的操作就是类中规定红啊的方法。类与对象的关系如图:

 

第十七天 类与对象_类与对象

1.1.2 类的定义

类是由属性和方法组成的。属性中定义类一个个的具体信息,实际上一个属性就是一个变量,而方法是一些操作的行为,但是在程序设计中,定义类也是要按照具体的语法要求完成的,语法如下:

class 类名称{

数据类型 属性;

public 返回值的数据类型 方法名称(参数1, 参数2){

程序语句;

return 表达式;

}

}

下面根据以上的格式定义一个Person类:

class Person{

String name;

int age;

public void tell(){

System.out.println("姓名:" + name + ",年龄:" + age);

}

}

在上面程序中,Person类定义了nameage两个属性,分别表示人的姓名和年龄,然后定义一个tell方法,此方法的功能就是打印这两个属性的内容。

此处的方法并没有加上static关键字,这是因为此时定义的方法将由对象调用,而不像之前那样与主方法定义在一个类中且由主方法直接调用。

类的定义可以用图表示出来:

 

第十七天 类与对象_java学习_02

1.第一层表示类的名称,类的名称要求开头是字母大写。

2.第二层表示属性的的定义,按照“访问权限 属性名称: 属性类型”的格式定义,在本类中因为声明属性处没有写任何的访问权限,所以前面暂时不加任何的符号。

3.第三层表示类中方法的定义,按照“访问权限 方法名称():方法返回值”的格式定义,在本来中方法的声明处加上了public(此为访问权限,表示任何地方都可以访问),所以使用“+”表示。另外,如果方法中有传递参数,则方法定义格式为“访问权限 方法名称(参数名称:参数类型,参数名称:参数类型,…):方法返回值”。

1.1.3 对象的创建及使用

在上面已经创建好了一个Person类,要想使用一个类则必须有对象。对象的创建格式:

类名 对象名称 = null;

对象名称 = new 类名();

用以上格式产生对象分为声明对象和实例化对象两步。

当然可以直接通过类名 对象名称 = new 类名();

创建具体范例:

class ClassDemo01{

public static void main(String[] args) {

Person p = new Person();

}

}

以上程序在主方法中实例化了一个Person对象,对象名为p。与前面的数组开辟空间一样,对象的实例化也是要划分堆、栈空间的,具体的内存分配如图:

 

第十七天 类与对象_java学习_03

所有的对象名称都在栈内存中保存,而对象的具体内容则保存在对应的堆内存之中,必须使用new关键字才能开辟堆内存空间,此时,因为p对象刚刚被实例化,所以对象中的属性内容都是默认值,字符串的默认值为null,整数的默认值为0

访问对象中的属性或方法:

访问属性:对象名称.属性名

方位方法:对象名称.方法名()

为对象的属性设置内容,同时调用tell方法把内容输出:

class ClassDemo03{

public static void main(String[] args) {

Person p = new Person();

p.name = "张三";

p.age = 12;

p.tell();

}

}

运行结果:

姓名:张三,年龄:12

属性赋值完成之后的内存如图:

 

第十七天 类与对象_java学习_04

对象使用前必须实例化。

1.1.4 创建多个对象

创建两个对象:

class ClassDemo04{

public static void main(String[] args) {

Person p1 = new Person();

p1.name = "张三";

p1.age = 12;

p1.tell();

Person p2 = new Person();

p2.name = "李四";

p2.age = 13;

p2.tell();

}

}

运行结果:

姓名:张三,年龄:12

姓名:李四,年龄:13

程序分别实例化了两个Person对象,那么也就一味着p1p2对象分别指向各自的堆内存空间,如图:

 

第十七天 类与对象_java学习_05

类属于引用数据类型,而且从数组的使用上也可以发现,引用数据类型就是指一段堆内存空间可以同时被多个栈内存指向。

引用传递的简单范例:

class ClassDemo05{

public static void main(String[] args) {

Person p1 = null;

Person p2 = null;

p1 = new Person();

p2 = p1;

p1.name = "张三";

p1.age = 12;

p2.age = 13;

p1.tell();

p2.tell();

}

}

运行结果:

姓名:张三,年龄:13

姓名:张三,年龄:13

两个对象的输出内容是一样的,实际上所谓的引用传递,就是将一个堆内存空间的使用权给多个栈内存空间,每个栈内存空间都可以修改堆内存的内容,内存如图:

 

 

第十七天 类与对象_java学习_06 第十七天 类与对象_java学习_07

从图中可以发现内存空间的堆、栈指向的变化,程序最后由per2age的值修改为13,所以最终结果per1中的age属性值也是13

class ClassDemo06{

public static void main(String[] args) {

Person p1 = new Person();

Person p2 = new Person();

p1.name = "张三";

p1.age = 12;

p2.name = "李四";

p2.age = 13;

p2 = p1;

p1.tell();

p2.tell();

}

}

运行结果:

姓名:张三,年龄:12

姓名:张三,年龄:12

内存变化图:

 

第十七天 类与对象_类与对象_08

关于垃圾空间的释放:

Java本身提供垃圾收集机制(Garbage CollectionGC),会不定期地释放不用的内存空间,只要对象不使用了,就会等待GC释放空间。

一个栈内存空间只能指向一个堆内存空间,如果要想再指向其他的堆内存空间,则必须先断开已有的指向才能分配新的指向。