《Java高级编程-面向对象高级话题.ppt》由会员分享,可在线阅读,更多相关《Java高级编程-面向对象高级话题.ppt(58页珍藏版)》请在三一办公上搜索。
1、第一周周一内容,面向对象高级主题,本节内容,类的组成对象,对象相等?(=与equals)封装、继承和多态抽象类与接口面向接口编程类或对象关系,代码复用关键字static、final、abstract等内部类,枚举类,1、类的组成,请举例,如Car类,请尽你的理解给出一个类可以有哪些要素组成,可以将现实生活中的对象经过抽象,映射为程序中的对象。对象在程序中是通过一种抽象数据类型来描述的,这种抽象数据类型称为类(Class)。,1、类的组成,定义类的语法格式:修饰符 class 类名.类体.类体可以由多个属性、方法、构造器组成。注意:类的修饰符可以是public、final 或省略这两个以及abs
2、tract。类名只要是合法的标识符.一个类里可以包含三种最常见的成员:构造器、属性、方法。,1、类的组成,定义属性的语法格式:修饰符 属性类型 属性名=默认值;修饰符可以是访问权限:public:可被任何类访问。protected:被类自身,子类及同一包中的类访问。default:也称友好,被类自身和同一包中的类访问。private:只能被类自身访问。其他:transient声明一个暂时性变量,对象存档时不必保存该变量;final声明一个常量,程序不能改变其值,通常用大写;voltatile用于声明一个共享变量,用于多个并发线程共享;static:表示类成员。,成员变量和局部变量,成员变量指的
3、是在类范围里定义的变量;局部变量指的是在一个方法内定义的变量。不管是成员变量还是局部变量都遵守相同的命名规则。成员变量分为类属性和实例属性.对于类属性无论通过类还是对象来访问都是访问同一个对象,只要一个对象改变了类属性,那么其他对象对应的类属性也改变了.成员变量不用显式初始化,只要定义了一个类属性或实例属性,系统默认进行初始化。,局部变量,局部变量可分为三种:形参方法局部变量代码块局部变量.与成员变量不同的是除了形参外,其他局部变量都必须显式地初始化,Java 里允许局部变量和成员变量重名。这样局部变量会覆盖成员变量,这时通过this 来调用实例的属性.,成员变量的初始化,当类被加载时,类成员
4、就在内存中分配了一块空间。当对象被创建时,实例成员就在内存中分配了内存空间。实例变量与实例共存亡;类变量与类本身共存亡。,局部变量的运行机制,局部变量仅在方法内有效。当方法执行完成时,局部变量便会自动销毁。,1、类的组成,定义方法的语法格式:修饰符 方法返回值类型 方法名(形参列表).方法体.方法中的修饰符可以是public,protected,private,static,final,abstract,其中访问控制符只能出现一个,abstract,final 只能出现其一.返回值类型可以是基本类型和引用类型,如果无返回值,要用void 来声明形参列表,可以由零到多组组成,参数之间用逗号(“,
5、”)隔开.static 是一个特殊的关键字,译为”静态”,所有有static 修饰的叫类属性,类方法,类成员.,1、类的组成,定义方法的语法格式:修饰符 方法返回值类型 方法名(形参列表).方法体.方法的调用:,1、类的组成,定义方法的语法格式:修饰符 方法返回值类型 方法名(形参列表).方法体.方法的重载就是在同一个类中允许同时存在一个以上的同名函数,只要它们的参数个数或类型不同即可。如:public class Testpublic static void main(String args)int isum;double fsum;isum=add(3,5);isum=add(3,5,6)
6、;fsum=add(3.2,6.5);public static int add(int x,int y)reutrn x+y;public static int add(int x,int y,int z)return x+y+z;public static double add(double x,double y)return x+y;,修饰词访问权限:public:protected:private:default:其他abstract修饰的为抽象方法,必须被重写,抽象类不一定包含abstract方法,但如果一个类包含abstract方法,该类必须声明为抽象类;final修饰的方法不能再
7、被类重写;native用于将java代码和其他语言的代码集成起来;synchronized用来控制多个并发线程对共享数据的访问。static:类方法。,不同限定词的访问权限,public类,缺省修饰的类,P41,方法的重载,Java 允许在一个类里定义多个同名方法,只要形参列表不同即可.所以方法的重载只要满足两个条件(两同一不同):1.同一个类中,方法名相同;2.形参不同。和返回值类型无关.所以在调用这些方法时要传入不同的参数值.,方法的参数传递基本数据类型的参数传递,方法的参数传递引用数据类型的参数传递,方法的参数传递-值传递,形参长度可变的方法,如果在定义方法时,在最后一个参数的类型后增加
8、三点,则表明该形参接受多个参数值,多个参数值被当成数组传入.长度可变的形参只能位于最后一个参数,并一个方法里只能有一个可变长度的参数.,1、类的组成,定义构造器的语法格式:修饰符 构造器名(形参列表)修饰符可以是public protected private 构造器必须和类名相同,形参和方法的形参一样.,构造函数的定义与作用,构造器是一种特殊的方法,构造对象并对其初始化。例:Date类的构造器叫DatenewDate()-构造一个新对象,且初始化当前时间.构造器可以有0个,一个或多个参数构造器和类有相同的名字一个类可以有多个构造器构造器没有返回值构造器总是和new运算符一起使用.如果没有声明
9、构造器,则系统默认提供一个无参的构造器;如果自己声明了构造器,系统则不再默认提供。,构造方法的重载,和一般的方法重载一样,重载的构造方法具有不同个数或不同类型的参数,编译器就可以根据这一点判断出用new 关键字产生对象时,该调用哪个构造方法了。产生对象的格式是:new 类名(参数列表);重载构造方法可以完成不同初始化的操作,如:p3=new Person(“Tom”,18);语句,会做这样几件事:创建指定类的新实例对象,在堆内存中为实例对象分配内存空间,并调用指定类的构造方法,最后将实例对象的首地址赋值给引用变量p3。,构造方法的一些细节,在java每个类里都至少有一个构造方法,如果程序员没有
10、在一个类里定义构造方法,系统会自动为这个类产生一个默认的构造方法,这个默认构造方法没有参数,在其方法体中也没有任何代码,即什么也不做。由于系统提供的默认构造方法往往不能满足编程者的需求,我们可以自己定义类的构造方法,来满足我们的需要,一旦编程者为该类定义了构造方法,系统就不再提供默认的构造方法了。声明构造方法,如无特殊需要,应使用public关键字,在我们前面例子中,可以使用private访问修饰符吗?,this是什么?,如果func2方法被调用,一定是事先已经有了一个存在的对象,func2被作为那个对象的方法被使用。在func2内部能引用别的对象,同样也能引用func2所属的那个对象。在fu
11、nc2中,自己所属的那个对象的引用名称是什么呢?this关键字在java程序里的作用和它的词义很接近,它在函数内部就是这个函数所属的对象的引用变量。,this引用句柄的存放位置,每个成员方法内部,都有一个this引用变量,指向调用这个方法的对象,类中的成员方法与this之间的关系如图,this引用句柄的应用,一个类中的成员方法可以直接调用同类中的其他成员,其实我们在一个方法内部使用“this.其他成员”的引用方式和直接使用“其他成员”的效果是一样的,那this还有多大的作用呢?在有些情况下,我们还是非得用this关键字不可的:让类的成员变量名和对其进行赋值的成员方法的形参变量同名是必要的,这样
12、的代码谁看了都能明白这两个变量是彼此相关的,老手看到函数的定义,就能揣摩出函数中的代码,大大节省了别人和自己日后阅读程序的时间。假设我们有一个容器类和一个部件类,在容器类的某个方法中要创建部件类的实例对象,而部件类的构造方法要接收一个代表其所在容器的参数。构造方法是在产生对象时被java系统自动调用的,我们不能在程序中象调用其他方法一样去调用构造方法。但我们可以在一个构造方法里调用其他重载的构造方法,不是用构造方法名,而是用this(参数列表)的形式,根据其中的参数列表,选择相应的构造方法。,3、对象相等?(=与equals),什么是对象相等?如何让两辆车相等?,对象的比较,“=”运算符与eq
13、uals()方法的区别怎样比较两个数组对象的内容是否相等,对象的产生,Person p1=new Person();执行完后的内存状态,对象的产生,当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值。除了基本数据类型之外的都是变量类型都是引用类型,如上面的Person及前面讲过的数组。,1、对象的生成:包括声明、实例化。声明:声明并不为对象分配内存空间,而只是分配一个引用空间;对象的引用类似于指针,是32位的地址空间,它的值指向一个中间的数据结构,它存储有关数据类型的信息以及当前对象所在的堆的地址,而对于对象所在的实际的内存地址是不可操作的,这就保证了安全性。如:Circle c
14、le;,Circle,实例化:运算符new为对象分配内存空间,它调用对象的构造方法,返回引用;一个类的不同对象分别占据不同的内存空间。如:cle=new Circle();或 cle=new Circle(10,20,5);,0 xAB12,Circle,对象的引用,对象实体,Point p1=new Point(12,16);Point p2=new Point(6,18);,0 xAB10,p1,0 xDD12,p2,p1=p2;,0 xDD12,p1,0 xDD12,p2,对象的使用,创建新的对象之后,我们就可以使用“对象名.对象成员”的格式,来访问对象的成员(包括属性和方法)class
15、 TestPersonpublic static void main(String args)Person p1=new Person();Person p2=new Person();p1.age=-30;p1.shout();p2.shout();程序运行的内存布局如下图,2、对象的使用通过运算符.可以实现对变量的访问和方法的调用。变量和方法可以通过设定访问权限来限制其它对象对它的访问。调用对象的变量格式:objectReference.variableobjectReference是一个已生成的对象,也可以是能生成对象的表达式例:p.x=10;tx=new Point().x;调用对象的
16、方法格式:objectReference.methodName(paramlist);例如:p.move(30,20);new Point().move(30,20);,对象的生命周期,与基本类型的生命周期一样,3、对象的清除当不存在对一个对象的引用时,该对象成为一个无用对象。Java的垃圾收集器周期性的自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。也可以调用System.gc();进行垃圾回收。,3、封装、继承和多态,请举例说明你的理解,如上述的Car类,请分别说明封装、继承和多态类的字段有多态吗?,4、抽象类与接口,如何定义抽象类,作用是什么?如何定义接口类,作用是什么
17、?它们的相似之处是什么?区别是什么?,3.接口,“对实现我的类,看起来都应该是我的样子”接口规定了一个类的基本形式:自变量,方法名,返回类型.但不规定方法的主体.接口的数据类型:都默认为static,final只是一种形式,不涉及细节,3.接口定义的形式,public interface interfaceName extends SuperInterfaceList/常量定义和方法定义,接口(interface)作为特殊形式的抽象类,和类(class)在使用上具有类似的约束。一个public接口只能定义在同名的.java文件中,3.类对接口的实现,用implements子句来表示一个类实现某
18、个接口。在类体中可以使用接口中定义的常量,而且必须实现接口中定义的所有方法。利用接口可实现多重 继承,即一个类可以实现多个接口,在implements子句中用逗号分隔。接口的作用和抽象类相似,只定义原型,不直接定义方法的内容。接口中的方法和变量都必须是public的。,5、类或对象关系,代码复用,类或对象有哪些关系?以Dog或Car为例如狗Dog是一种动物,狗有一个项圈(NeckIdentier),狗有四条腿(Leg),狗汪汪叫(WangWang),狗用棍子(Stick-工具,谁都可以用)追打老鼠(Cat)?,6、面向接口编程,假设你做的一个关于不同车的游戏,在这个游戏中,你可以选择宝马X6、
19、比亚迪F6、哈佛H6等,它们可以越野模式,也可以运动模式前行,请你设计一下车这个类,然后让它一会越野模式一会运动模式前行!如果你是车的司机,从对象调用的角度讲,谁是调用者,谁是服务者,你是怎样看你的车的行为的?,4、7、回顾关键字final修饰一个类:该类不能被继承修饰一个方法:该方法不能被重载修饰一个变量:该变量是常量abstract修饰一个类:该类是抽象类,不能实例化,必须被继承才能创建对象。修饰个方法:该方法必须被重写。含有abstract方法的类必定是抽象类。,static用static声明类方法和类变量。this可以出现在类的实例方法中,代表使用该方法的当前对象。this一般可以省略
20、。但当成员变量与局部变量名字相同时,若要访问成员变量,this不能省略。this方法不能出现在类方法中,因为类方法可以通过类名直接调用,此时,可能还没有任何对象诞生。,static关键字用static声明类方法和类变量。实例变量和类变量 不同对象的实例变量被分配不同的内存空间;但所有对象的类变量都分配相同的内存空间。,如果一个类被加载,在没有创建对象时,实例变量不会分配内存,但类变量被分配了内存,直到程序推出才释放其所占有的空间;可以通过类名直接访问非private修饰的类变量。类名.类变量,内存模型:class Takecare static int x;int y;public void
21、op()Takecare A1=new Takecare();Takecare A2=new Takecare();,Static修饰变量注意事项:实现各实例间的通信。可以跟踪创建的实例数相当于某些语言中的全局变量非private的静态成员变量可采用类名直接访问。,实例方法与类方法类的字节码被加载到内存后,类的实例方法没有被分配入口地址。当类创建第一个对象后,才会分配相应的入口地址。以后创建的对象共享该入口地址。对象都消失时,该入口地址被取消。只要类被加载,即使没有创建对象,类方法也会被分配入口地址。直到程序退出才取消该入口地址。可以通过类名调用非private修饰的类方法。两种方法中的局部变
22、量都是在执行时才分配内存空间。,前面讲过,类方法不能操作实例变量和实例方法,请思考一下原因。,因为,类创建对象之前,实例成员变量还没有分配内存,实例方法也没有入口地址。,class A int a;static int b;void f(int x,int y)a=x;/合法.b=y;/合法.static void g(int z)b=23;/合法.a=z;/非法.,变量操作,class Member static int classVar;int instanceVar;static void setClassVar(int i)classVar=i;/instanceVar=i;/类方法不
23、能访问实例变量static int getClassVar()return classVar;void setInstanceVar(int i)classVar=i;/实例方法不但可以访问类变量,也可以实例变量instanceVar=i;int getInstanceVar()return instanceVar;public class MemberTestpublic static void main(String args)Member m1=new member();Member m2=new member();m1.setClassVar(1);m2.setClassVar(2);
24、System.out.println(m1.classVar=+m1.getClassVar()+m2.ClassVar=+m2.getClassVar();m1.setInstanceVar(11);m2.setInstanceVar(22);System.out.println(m1.InstanceVar=+m1.getInstanceVar()+m2.InstanceVar=+m2.getInstanceVar();,实例成员与类成员,包package,包是Java一个有效管理类的机制,把一个或多个类收集在一起成为一组,称作包,以便于组织任务,标准Java库分为许多.java.langjava.util等,包是分层次的所有的java包都在java和javax包层次内。打包的理由所有的程序员可以容易地决定哪些类和接口是相关的所有的程序员知道哪里可以找到与图形相关函数的类和接口。类的名字不会与其它包中的名字冲突,因为每个包创建了一个新的名空间。你可以允许在包的类有无限制的访问以及包外的类的有限制访问。,8、内部类、枚举类,QA,交流问题作业,