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