类与对象

类与对象的基本概念

在现实生活之中,类指的是具备某一共性的群体的集合。而对象是一种个性的描述。简单的可以理解成对象包含的是具体的信息内容,对象所能够具备的操作行为实际上是由类定义的,也就是说要想使用类,那么必须有一个具体的描述对象,而对象的操作完全有类来定义,对象是可以明确使用的,而类是不可以直接使用的。
真实存在的可以使用的就是对象,而定义概念的就是对象

类与对象的定义(重点

在开发之中,先有类,再有对象。在Java中如果要定义类,则可以使用class关键字来描述,而在类中的组成主要有两种:属性(变量)、方法(此方法不在主类中定义,不由主方法直接调用,所以不加static)。
范例:定义一个类

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}

类本身不能直接使用,所有的类必须通过对象才能使用。由于类属于引用数据类型(内存关系),所以对象的定义语法有两种:

  • 声明并实例化对象:类名称 对象名称=new 类名称();
  • 分步进行:
  • 声明对象:类名称 对象名称=null;
  • 实例化对象:对象名称= new 类名称().
    引用数据类型在开始使用之前必须开辟空间,而基本数据类型可以直接赋值,那么开辟空间的关键字就是new。一旦有了对象之后,就可以利用对象实现类的属性和方法的调用,使用原则:
  • 调用属性:实例化对象.属性名称;
  • 调用方法:实例化对象.方法();

范例:定义对象并使用

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person per = new Person();//声明并实例化对象
		per.name="sue";//对象.属性=内容
		per.age=18;//对象.属性=内容
		per.tell();//通过对象调用类中的方法
	}
}

类与对象
整个代码的操作就是根据一个类产生对象,设置对象属性值并打印对象的属性值。但是如果此时没有设置属性值呢?

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person per = new Person();//声明并实例化对象
		per.tell();//通过对象调用类中的方法
	}
}

类与对象
没有设置属性内容时,出现的就是默认值,String是引用型,默认值是null,int是基本型,默认值是0;

对象内存分析

类本身属于引用数据类型,所以对于引用数据类型就必须为其进行内存分析,那么在分析之前,首先给出两块内存空间的概念:

  • 堆内存空间(Heap):保存的是对象中具体的属性信息;
  • 栈内存空间(Stack):保存的堆内存的地址数值,所以现在可以简化一点,假设栈中保存的是对象的名称,一块占内存只能保存一块对应的堆内存地址。
    所以按照以上分析,可以得出如下的内存关系图。
    范例:分析代码
class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person per = new Person();//声明并实例化对象
		per.name="sue";//对象.属性=内容
		per.age=18;//对象.属性=内容
		per.tell();//通过对象调用类中的方法
	}
}

类与对象
引用数据的使用与C语言是完全一样的,所以这个是Java的灵魂所在。
实际上对象的产生格式本次只使用了一种 ,还有另外一种分步的方式完成。

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person per = null;//声明对象
		per = new Person();//实例化对象
		per.name="sue";//对象.属性=内容
		per.age=18;//对象.属性=内容
		per.tell();//通过对象调用类中的方法
	}
}

只要有new,就开辟堆内存空间。
类与对象
类与对象
注意:关于引用数据类型操作存在的类型
理论上当对象开辟堆内存(实例化对象),属性才会进行内存的分配,那么如果使用了没有实例化的对象呢?

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person per = null;//声明对象
		//per = new Person();//实例化对象
		per.name="sue";//对象.属性=内容
		per.age=18;//对象.属性=内容
		per.tell();//通过对象调用类中的方法
	}
}

相当于此时只是声明了对象 ,但是并没有进行对象的实例化操作,这个时候程序编译没有问题,但是执行时会出现如下错误:
类与对象
那么此时返回的是NullPointerException"异常,即空指向异常。这个异常只有引用数据类型会出现,出现的原因只有一点——使用了没有开辟堆内存空间的引用对象。
现在既然可以开辟一个对象了,那么也就可以开辟两个对象。
范例:开辟两个对象

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person perA = new Person();//声明并实例化对象
		Person perB = new Person();//声明并实例化对象
		perA.name="sue";//对象.属性=内容
		perA.age=18;//对象.属性=内容
		perB.name="lee";//对象.属性=内容
		perB.age=16;//对象.属性=内容
		perA.tell();//通过对象调用类中的方法
		perB.tell();//通过对象调用类中的方法
	}
}

类与对象
类与对象

初步分析引用传递

引用传递是在引用数据类型上所用的一个操作定义,是Java的精髓,其操作的性质与指针是相同的,进行内存的操作。在程序中指的是一块堆内存空间可以同时被多个栈内存所指向。
范例:引用传递

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person perA = new Person();//声明并实例化对象
		perA.name="sue";//对象.属性=内容
		perA.age=18;//对象.属性=内容
		Person perB =perA;//引用传递
		perB.name="lee";//对象.属性=内容
		perA.tell();//通过对象调用类中的方法
	}
}

类与对象
类与对象
以上采用了声明对象的方式进行了引用数据类型的接收,那么如果此次两个对象都已经实例化了呢?
范例:观察引用传递

class Person{
	String name;
	int age;
	public void tell(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class Hello {//另外一个类
	public static void main(String args[]){
		Person perA = new Person();//声明并实例化对象
		Person perB = new Person();//声明并实例化对象
		perA.name="sue";//对象.属性=内容
		perA.age=18;//对象.属性=内容
		perB.name="lee";//对象.属性=内容
		perB.age=16;//对象.属性=内容
		perB =perA;//引用传递
		perB.name="Fan";
		perA.tell();//通过对象调用类中的方法
	}
}

类与对象
类与对象
通过以上分析,可以发现:

  • 使用关键字new,永恒可以开辟一个新的堆内存空间,堆内存空间保存的就是属性;
  • 栈内存空间只能够保存一块堆内存的试用地址;
  • 引用传递的本质在于同一块堆内存空间可以被不同的栈内存所指向;
  • 在发生引用传递时,如果操作的栈内存原本有堆内存指向,那么改变堆空间就意味着改变内存指向;
  • 如果某一块内存没有被任何的栈内存所指向,那么此空间会成为垃圾空间,所有的垃圾空间会自动的被GC(垃圾收集器,Garbage Collector)回收并释放,由于垃圾回收的时间不确定,所以最好的做法是尽量少产生垃圾空间。如果想产生垃圾,除了改变引用之外,也可以设置为null。
perB=null;

那么就表示perB将放弃原本的指向,变成一个没有指向的栈内存。

总结

  • 清楚类与对象的定义格式;
  • 熟练掌握对象的内存分配,以及内存图的描述。