类与对象.docx
《类与对象.docx》由会员分享,可在线阅读,更多相关《类与对象.docx(14页珍藏版)》请在冰点文库上搜索。
类与对象
1、课程名称:
类与对象
2、知识点
2.1、上次课程的主要知识点
1、面向对象是模块的设计;
2、面向对象的主要特点:
封装、继承、多态。
2.2、本次预计讲解的知识点
1、类与对象的定义;
2、对象的产生与内存划分;
3、初步认识对象的引用传递。
3、具体内容(★★★★★)
3.1、类与对象基本概念
在现实生活之中,类指的就是具备某一共性的群体集合。
而对象是一种个性的描述。
如果要想进行更简单的理解,对象包含的是具体的信息内容,例如:
陶先生、李先生、Java开发。
对象所能够具备的操作行为实际上是由类来定义的,也就是说要想使用类那么必须有一个具体的描述对象,而对象的操作完全由类来定义。
对象是可以明确使用的,而类是不能够直接使用的。
真实存在的可以使用的就是对象,而定义概念的就是类。
3.2、类与对象的定义(重点)
在开发之中一定要记住,是先有类,再有对象。
在Java中如果要定义类,则可以使用class关键字来描述,而在类中的组成主要有两种:
属性(变量)、方法(此方法不是在主类中定义,不由主方法直接调用,所以不加static)。
范例:
定义一个类
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
类本身不能够直接使用,所有的类必须通过对象才可以使用。
由于类属于引用数据类型(内存关系),所以对象的定义语法现在有两种:
·声明并实例化对象:
类名称对象名称=new类名称();
·分步进行:
|-声明对象:
类名称对象名称=null;
|-实例化对象:
对象名称=new类名称()。
引用数据类型在使用前必须开辟空间,而基本数据类型可以直接赋值,那么开辟空间的关键字就是new。
那么一旦有了对象之后,就可以利用对象来实现类中属性和方法的调用,使用原则:
·调用属性:
实例化对象.属性名称;
·调用方法:
实例化对象.方法()。
范例:
定义对象并使用
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
Personper=newPerson();//声明并实例化对象
per.name="张三";//对象.属性=内容
per.age=30;//对象.属性=内容
per.tell();//通过对象调用类中的方法
}
}
整个的代码操作就是根据一个类产生出对象,而后设置对象的属性内容,并且打印信息。
但是如果说此时没有设置属性内容呢?
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
Personper=newPerson();//声明并实例化对象
//per.name="张三";//对象.属性=内容
//per.age=30;//对象.属性=内容
per.tell();//通过对象调用类中的方法
}
}
没有设置属性内容时出现的就是默认值,String是引用类型,所以默认值是null,而int是基本类型,默认值为0。
3.3、对象产生分析
类本身属于引用数据类型,所以对于引用数据类型就必须为其进行内存分析,那么在分析之前,首先给出两块内存空间的定义:
·堆内存空间(Heap):
保存的是对象中具体的属性信息;
·栈内存空间(Stack):
是保存的堆内存的地址数值,所以现在可以简化一点,假设保存在栈内存中的是对象名称,一个栈内存只能够保存一块对应的堆内存空间地址。
所以现在按照以上的分析,就可以得出如下的内存关系图。
范例:
分析代码
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
Personper=newPerson();//声明并实例化对象
per.name="张三";//对象.属性=内容
per.age=30;//对象.属性=内容
per.tell();//通过对象调用类中的方法
}
}
引用数据使用与C语言是完全一样的,所以这个是Java的灵魂存在。
实际上对象的产生格式本次只使用了一种,还有另外一种分步的方式完成。
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
Personper=null;//声明对象
per=newPerson();//实例化对象
per.name="张三";//对象.属性=内容
per.age=30;//对象.属性=内容
per.tell();//通过对象调用类中的方法
}
}
注意:
关于引用数据类型操作存在的重要问题。
理论上当对象开辟堆内存(实例化对象)那么属性才会进行内存的分配,那么如果说使用了没有实例化的对象呢?
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
Personper=null;//声明对象
//per=newPerson();//实例化对象
per.name="张三";//对象.属性=内容
per.age=30;//对象.属性=内容
per.tell();//通过对象调用类中的方法
}
}
相当于此时只是声明了对象,但是并没有进行对象的实例化操作,这个时候程序编译没有任何问题。
但是程序执行。
那么此时返回的是“NullPointerException”异常,翻译就是空指向异常。
这个异常只有引用数据类型会出现,出现的原因只有一点:
使用了没有开辟堆内存空间的引用对象。
现在既然已经可以开辟一个对象了,那么也就可以开辟两个对象。
范例:
开辟两个对象操作
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
PersonperA=newPerson();//实例化对象
PersonperB=newPerson();//声明并实例化对象
perA.name="张三";//对象.属性=内容
perA.age=30;//对象.属性=内容
perB.name="李四";
perB.age=10;
perA.tell();//通过对象调用类中的方法
perB.tell();
}
}
3.4、初步分析引用传递
引用传递是在引用数据类型上所所用的一个操作定义,其是Java的精髓,其操作的性质与C语言的指针是相同的,进行内存的操作。
换到程序中,那么就是一块堆内存空间可以同时被多个栈内存所指向。
范例:
引用传递
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
PersonperA=newPerson();//实例化对象
perA.name="张三";//对象.属性=内容
perA.age=30;//对象.属性=内容
PersonperB=perA;//引用传递
perB.name="李四";
perA.tell();//通过对象调用类中的方法
}
}
以上是采用了声明对象的方式进行了引用数据类型的接收,那么如果说此时两个对象都已经明确实例化并设置内容了呢?
范例:
观察引用传递
classPerson{//现在定义了一个类
//定义类中的两个属性
Stringname;//表示人的姓名
intage;//表示人的年龄
publicvoidtell(){
System.out.println("姓名:
"+name+",年龄:
"+age);
}
}
publicclassTestDemo{//另外一个类
publicstaticvoidmain(Stringargs[]){
PersonperA=newPerson();//实例化对象
PersonperB=newPerson();//实例化对象
perA.name="张三";//对象.属性=内容
perA.age=30;//对象.属性=内容
perB.name="王五";
perB.age=10;
perB=perA;//引用传递
perB.name="赵六";
perA.tell();//通过对象调用类中的方法
}
}
通过以上的分析应该可以发现几点:
·使用关键字new永恒可以开辟新的堆内存空间,堆内存空间保存的就是属性;
·栈内存只能够保存一块堆内存的使用地址;
·引用传递的本质在于同一块堆内存空间可以被不同的栈内存所指向;
·在发生引用传递时,如果操作的栈内存原本有堆内存指向,那么改变堆空间就意味着改变内存指向;
·如果某一块堆内存没有被任何的栈内存所指向,那么此空间将成为垃圾空间,所有的垃圾空间会自动的被GC(垃圾收集器,GarbageCollector)回收并且释放。
由于垃圾回收是不确定的执行时间,所以最好的做法是尽量少产生垃圾空间。
如果要想产生垃圾,除了改变引用之外,也可以设置为null。
perB=null;
那么就表示perB将放弃原本的指向,变为一个没有指向的栈内存。
4、总结
1、清楚类与对象的定义格式;
2、熟练掌握对象的内存分配,以及内存图的描述。