第四章类、包和接口本章主要内容类:★域、方法★构造方法、方法的重载★类的继承包:★package语句★访问控制符接口:★定义★实现§1类、域和方法Java程序类类域1域2方法1方法2一、定义类中的域和方法修饰符class类名称{域定义;方法定义;}UML类图类名域方法例:classPerson{stringname;intage;voidsayHello(){System.out.println(“Hello!”);}}域方法成员1、域(field)①对应类的静态属性②属性③变量④定义语法:类型名域名;例如:intage;⑤系统默认值(参见P35,表3-1)2、方法(method)①类的动态特性②具有的功能和操作③定义语法:修饰符返回值类型方法名(形参列表){…}④返回值⑤return语句BooleanisOlderThan(intanAge){booleanflg;if(ageanAge)flg=trueelseflg=false;returnflg;}形参返回类型返回语句二、构造方法与对象的创建1、构造方法(constructor)▲与类同名的方法▲无返回值,不写void▲主要完成对象的初始化工作▲不用显式调用,用new来调用▲对象创建时会自动调用构造方法Person(Stringn,inta){name=n;age=a;}2、默认构造方法①如果没有定义任何构造方法,系统会自动产生一个构造方法②默认构造方法不带参数,并且方法体为空,Person(){}3、创建对象②创建对象变量名=new构造方法(参数);p=newPerson(“zhang”,28)①声明变量类名变量名;Personp;③合并类名变量名=new构造方法(参数)Personp=newPerson(“zhang”,28);④new:它以类为模板,开辟空间并执行相应的构造方法。⑤对象变量:是引用型变量ReferencePReference28NameAgezhang三、使用对象1、对象.域,对象.方法。2、只能通过对象变量来访问对象的域或方法。例如:p.sayHello();四、方法的重载(overloading)1、方法的名字相同,参数不同。2、参数个数不同,或参数类型不同,或者参数类型顺序不同.例:4-2,P76voidsayHello()voidsayHello(Personanother)3、构造方法的重载:可以让用户用不同的参数来构造对象。例:P76Person(Stringn,inta)Person(Stringn)2、作用①使用this访问域及方法②使用this解决局部变量或参数与域同名的问题③在构造方法中,用this调用另一个构造方法,必须放在第一句。五、this的使用1、表示对象本身普通方法中表示调用该方法的对象在构造方法中表示新创建的对象3、注意▲可以引用该类中的成员,也可引用父类成员▲不能通过this引用类(static)变量、类(static)方法在所有非static方法中都可以使用this,但是在static方法中不能使用this§2类的继承一、概述1、父类(superclass):基类,被继承的类。2、子类(subclass):衍生类、派生类,由继承得来的类。3、类派生:子类与父类间的继承动作称为类派生。4、类层次:类的继承关系所形成的结构。5、Java中,所有的类都是通过直接或间接地继承java.lang.Object得到的。Ⅰ分类的角度1、分类就是一个抽象化的过程,低层次分类都具备高层次分类的特性。2、一般化特殊化Ⅱ遗传角度后代的特征或多或少都来自于父母的遗传,但后代还具有自己特有的特征。基类与衍生类之间就具有遗传的关系,其成员一部分继承于基类,而衍生类本身所具有的其它特性,则在定义衍生类时,再增加与修改。基类的特性基类的一些特性衍生类增加的特性衍生类修正的特性Ⅲ继承对系统开发的意义1、使用继承的优点:①便于管理系统中的对象:基类的修改直接反映到子类上②系统的扩充更加容易:从基类继承即可2、程序代码的重用(softwarereuse)加快开发速度减少程序错误二、派生子类1、语法:修饰符classAextendsB{}2、A类继承B类,A类是B类的直接子类3、如果没有extends子句,则该类默认为java.lang.Object的子类Person+name:String+age:int+birthDate:Date+getInfo():StringStudent+school:String箭头表示子类与父类的关系1、域的继承子类继承父类的所有非私有域。2、域的隐藏子类重新定义一个与父类域变量相同的变量。3、域的添加定义子类时,加上新的域变量。三、域的继承与隐藏、添加A类的成员(子类)A类的成员B类的成员(父类)B类的一些成员(父类)A类增加的成员1、方法的继承子类继承父类的所有非私有方法2、方法的覆盖(overriding)子类可以重新定义与父类同名的方法(应与父类有完全相同的方法名,返回值和参数类型列表.)3、方法的重载(区别?)一个类中可以有几个同名的方法4、方法的添加子类可以增加新方法四、方法的继承、覆盖与添加1、使用super访问父类的域和方法2、使用父类的构造方法使用时,super()必须放在第一句3、使用super的注意事项①可以访问直接父类的成员,还可以访问间接父类的成员。②不能访问静态成员五、super的使用:1、this可以访问本类的域和方法,也可以访问父类的域和方法;super只能访问父类的域和方法。2、当覆盖父类的同名方法的同时,又要调用父类的方法,就必须用到super。3、构造方法不能继承,但是子类可以通过super调用父类的构造方法。六、父类与子类对象的转换1、子类对象可以被视为其父类的一个对象Personp=newstudent();2、父类对象不能当作其某一个子类的对象studentp=newPerson();3、形参为父类对象,实参可以是子类对象4、如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以强制转换为子类对象的引用。例:4-3,P85Personp=newstudent();students=(student)p;§3包简介:①同名类可能发生冲突②包用来管理类名空间③一般不要求处于同一包中的类具有明确的相互关系④同一包中的类在默认情况下可以互相访问⑤一起工作的类放在一个包里一、package语句1、Java源程序的第一条语句2、指明该文件中定义的类所在的包3、语法:packagepkg1.pkg2.pkg3…4、全值类名:pkg1.pkg2.pkg3.classname5、包与文件系统的目录对应Packagejava.awt.image;java/awt/image包层次的根目录由classpath来确定6、缺省情况为无名包(不能有子包)二、import语句1、importpkg1.pkg2….classname|*;●一个包中引用多个类可以用*代替●*只代表本层所有类,不包含子层下的类。2、java.lang自动被引入3、包被import后,使用时直接使用类名4、包没有被import,则使用时要用全名(包.类)importjava.util.*//importjava.util.DateclassMyDateextendsDate{}classMyDateextendsjava.util.Date{}三、编译和运行包中的类1、编译①在当前目录生成TestPkg.classjavacTestPkg.java②在当前目录下生成pk\TestPkg.classjavac–d.TestPkg.javajavac–dpk建立目录.java文件所在目录③编译后的类名为pk.TestPkg2、运行javapk.TestPkg(类名)在CLASSPATH+pk目录下寻找TestPkg.class例:4-4(TestPkg),P86四、Classpath1、包层次的根目录由classpath来确定2、编译时可以由-classpath选项指明①退回到根目录②java–classpathe:\javademo\ch04pk.TestPkgCLASSPATH包名寻找类文件的路径类文件名§4访问控制符目的:①为了更好的控制类及其域、方法的存取权限。②更好的实现封装和隐藏。p1P1.class1P1.class2P1.class3P1.class4p2P2.class1P2.class2P2.class3一、成员的访问控制符1.public:适用于完全公开的成员2.private:适用于类中不易公开的成员3.protected:半公开性质的成员4.无修饰符:包访问控制例:4-5(OriginalAccessControl),P88无修饰符protectedprivatepublic子类其它类子类其它类不同包同一包同一类存取等级二、类的访问控制符1、public:该类可以被其它包所访问2、默认:该类只能被包中的类访问三、setter与getter1、封装要求所有的域为private2、要想访问部分域怎么办?用setXXX和getXXX来访问属性:•学号•姓名•专业方法:•取姓名•取学号•取专业•设置姓名•设置学号•设置专业其他对象X3、优点:①体现封装性②可以利用方法进行合法性检查③可以利用方法进行计算④可以利用方法完成其它必要工作⑤提供getXXX不提供setXXX,可以保证域只读。classPerson2{privateintage;publicvoidsetAge(intage){if(age0&&age200)this.age=age;}publicintgetAge(){returnage;}}•JavaBean–一个特殊的Java类–没有任何公共变量–变量名首字母必须小写,例如name–通过getter/setter方法来读/写变量的值,例如getName()–实现serializable接口•将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;按值将对象从一个应用程序域发送至另一个应用程序域–用途:主要用于在页面之间传递一个被封装的数据对象•例子:–User类四、构造方法的隐藏1.默认在同一包内的其他类中可以创建该类对象。2.Public在所有其他类中都能够创建该类对象。3.Private在所有其他类中都不能创建该类对象。§5非访问控制符一、static1、类域①静态的、非实例的、类的。②静态域属于类不属于任何具体实例③对于类的任何一个具体对象,静态域是一个公共的存储单元。④可以通过类名直接访问,也可以通过对象来访问。2、类方法①类方法的本质是该方法是属于整个类的。非static的方法是属于某个对象的方法,在这个对象创建的时候,对象的方法在内存中有自己专用的代码段。而static方法在内存中的代码段将随着类的定义而进行分配和装载,不被任何一个对象专有。②类方法中不能操纵对象成员,只能操作类成员。③类方法中,不能访问实例变量;类方法中不能使用this或super。④可以通过类名直接访问,也可以通过对象来访问。例:4-6(StaticAndInstance),P93注意:main()方法必须用static修饰。3、静态初始化器①Static引导的一对{}括起来的语句组②作用与类的构造方法相似对类自身进行初始化不能由程序来调用,是在所属的类加载入内存时由系统调用执行不是方法(没有方法名,返回值和参数列表)不能访问实例域和实例方法classperson{staticlongtotalNum;static{totalNum=(long)52e8;System.out.println(“人类总人口:”+totalNum);}}二、final1、final类final类不能被继承一般是用来完成某种标准功能的类将一个类定义为final则可以将它的内容和属性及功能固定下来,与它的类名形成稳定的映射关系,从而保证引用这个类时所