第三章Java面向对象程序设计3.1Java的类和对象3.2域(属性)和方法3.3访问控制符3.4继承3.5方法的继承、覆盖与重载3.6上转型对象3.7接口3.8包3.1Java的类和对象类类是Java语言的最基本概念,是组成Java程序的基本要素类是Java的执行单位,Java运行的就是Java类本身;类封装了该类对象的变量和方法。对象对象是类的实例化,对象的创建是通过对象构造方法来实现的;我们可以生成多个对象,通过消息传递来进行交互,最终完成复杂的任务;消息传递是指激活指定的某个对象的方法,以改变它的状态或使其产生一定的动作。3.1.1类的定义类的一般格式是:class类名{属性(域);方法;}▼3.1.2创建对象与定义构造函数(一)1.创建对象创建对象的一般格式为:类名新建对象名=new构造函数()例如:PhoneCardmyCard=newPhoneCard();创建对象与声明基本数据类型的变量类似,赋值号右边的new是为新建对象开辟内存空间的算符。与变量相比,对象占用的内存空间要大得多,对象是以类为模板创建的具体实例。3.1.2创建对象与定义构造函数(二)以PhoneCard类为例,它定义了五个域和三个方法,它的对象myCard的内存空间保存的域和方法分别为myCard.cardNumbermyCard.password,myCard.balancemyCard.connectNumber,myCard.connnected,myCard.performConnection(),myCard.getBalance()myCard.performDial()。要访问或调用一个对象的域或方法,首先访问该对象,然后用算符“.”连接该对象的域或方法。例如:myCard.balance=50;3.1.2创建对象与定义构造函数(三)2.构造函数构造函数是与类同名的方法,创建对象的语句用new算符开辟了新建对象的内存空间后,将调用构造函数初始化这个新建对象。构造函数是类的一种特殊方法,其特殊性如下:构造函数的方法名与类名相同。构造函数没有返回值。构造函数的作用是对类的对象初始化。在创建一个类的新对象的同时,系统会自动调用该类的构造函数。3.1.2创建对象与定义构造函数(四)例如:定义PhoneCard类的构造函数。PhoneCard(longcn,intpw,doubleb,Strings){cardNumber=cn;password=pw;if(b0)balance=b;elseSystem.exit(1);connectNumeber=s;connected=false;}然后就可以用如下的语句初始化PhoneCard对象:PhoneCardmyCard=newPhoneCard(20010922,342323,50,“200”);3.1.3类的修饰符(一)Java程序定义类时,可在class之前增加若干类的修饰符来限定所定义类的特性。类的修饰符分为*访问控制符*非访问控制符有些修饰符可用来修饰类中的域或方法,本节讨论类的非访问控制符。3.1.3类的修饰符(二)1.抽象类凡是用abstract修饰符修饰的类被称为抽象类,抽象类就是没有具体对象的概念类。例如:“鸟”是一个抽象类,它可以派生出若干子类如“鸽子”、“燕子”、“麻雀”、“天鹅”等,“鸟”仅仅作为一个抽象的概念存在,它代表所有鸟的共同属性,任何一只具体的鸟都是由“鸟”经过特殊化形成的某个子类的对象。3.1.3类的修饰符(三)鸟鹰雕猛禽鸣禽文鸟百灵画眉3.1.3类的修饰符(五)2.最终类如果一个类被final修饰,说明该类不可以有子类了。我们可以把有继承关系的类看成一棵倒长的树,所有类的父类是树根,每个子类是一个分支,声明为final的类的叶结点,且不能再有子类了。被定义为final的类通常是一些有固定作用、用来完成某种标准功能的类,如Java系统定义好的用来实现网络功能的InetAddress、Socket等类都是final类。3.2域和方法域域是类和对象的静态属性,它可以是基本数据类型的变量,也可以是其它类(系统类或用户自定义类)的对象。方法方法是类的动态属性,标志了类所具有的功能和操作。Java的方法与其它语言中的函数或过程类似,是一段完成某种功能的程序段。3.2.1域(一)1.静态域用static修饰的域就是静态域。静态域最本质的特点是:它们是类的域,不属于任何一个类的具体对象,它不保存在某个对象的内存区域中,而是保存在类的内存区域的公共存储单元。换句话说,对该类的具体对象而言,静态域是一个公共的存储单元。任何一个类的对象访问它,得到的都是相同的值;任何一个类的对象修改它,都是对同一内存单元进行操作。3.2.1域(二)下面的程序片段定义了两个静态域:classPhoneCard200{staticStringconnetcNumber=“200”;//所有的200电话卡的接入号码都是“200”staticdoubleaddtoryFee;//所有的200电话卡的电话附加费相同longcardNumber;intpassword;booleanconnected;doublebalance;…}▼3.2.1域(三)2.静态初始化器静态初始化器是由static引导的一对大括号括起来的语句组。它的作用与类的构造函数相似,都是用来完成初始化的工作,但两者也有根本性的不同:构造函数是对每个新创建的对象初始化,而静态初始化器是对类本身进行初始化。构造函数是在用new运算符产生新对象时由系统自动执行的,而静态初始化器则是在它所属的类加载入内存时由系统调用执行的。不同于构造函数,静态初始化器不是方法,没有方法名、参数列表。▼3.2.1域(四)3.最终域程序中经常需要定义各种类型的常量,并为它们取一个类似于变量的标识符名字,这样就可以在程序中用这个名字来引用常量。final就是用来修饰常量的修饰符,一个类的域如果被声明为final,则它的取值在程序的整个执行过程中都不会改变。例如:staticfinalStringconnectNumber=“200”;3.2.2方法(一)方法由方法头和方法体组成,其一般格式如下:修饰符1修饰符2……返回值类型方法名(形式参数列表)throws[异常列表]{方法体各语句;}其中形式参数列表的格式为:形参类型1形参名1,形参类型2形参名2,……例如:publicstaticvoidmain(Stringargs[])throwsException{for(inti=0;iargs.length;i++)Systme.out.println(args[i]);}3.2.2方法(二)1.抽象方法修饰符abstract修饰的抽象方法是一种仅有方法头,而没有具体的方法体和操作实现的方法。例如:在抽象类PhoneCard中定义一个抽象方法:abstractvoidperformDial();使用抽象方法可使所有PhoneCard类的子类对外呈现一个统一的接口,至于方法体的具体实现,则留到当前类的不同子类的类定义中完成。注意:所有的抽象方法,都必须存在于抽象类之中。若一个抽象类的子类不是抽象类,则它必须为父类中的所有抽象方法书写方法体。▼3.2.2方法(三)2.静态方法用static修饰的方法是属于整个类的方法,它的特点如下所示:static方法是属于整个类的方法,它在内存中的代码将随着类的定义而分配和装载,不被任何对象专有;非static方法是属于某个对象的方法,在对象创建时在内存中拥有自己的专用代码段。static不能操作属于某个对象的成员变量,而只能处理属于整个类的成员变量,即:static方法只能处理static域。3.2.2方法(四)例如:在PhoneCard200中需要修改附加费,可以定义一个setAdditory()的静态方法:staticvoidsetAdditory(doublenewAdd){if(newAdd0)additoryFee=newAdd;}3.2.2方法(五)3.最终方法用final修饰的方法是功能和内部语句不能被更改的最终方法。在面向对象程序设计中,子类可把从父类那里继承来的某个方法改写,形成域父类方法同名,解决的问题类似,但具体实现和功能不全一致的新的类方法,这个过程称为重写(覆写overriding)。如果类方法被final修饰了,则该类的子类就不能在重新定义与此方法同名的自己的方法,只能使用从父类继承来的方法。这样,可以防止子类对父类的关键方法的错误的重定义,保证了程序的安全性和正确性。注意:所有被private修饰的方法,以及包含在final类中的方法,都被缺省认为是final的。3.2.2方法(六)4.本地方法native修饰符一般用来声明用其它语言书写的方法。由于native方法是以非Java字节码的二进制代码形式嵌入Java程序的,所以整个Java程序的跨平台性能将受到限制或破坏,因此使用这类方法时应特别谨慎。3.3访问控制符访问控制符是一组限定类、域或方法是否可以被程序里的其它部分访问和调用的修饰符。类的访问符有两个:缺省和public。域和方法的访问控制符有四个:缺省publicprivateprotected3.3.1缺省访问控制符Java的类是通过包来组织。假如一个类没有访问控制符,缺省的认为该类只能被同一个包中的类访问,这种访问特性又称包访问性。同理,类内的域和方法如果没有访问控制符,也说明它们具有包访问性,可以被同一个包中的其它类所访问和调用。3.3.2公共访问控制符public(一)1.类对于处于不同包中的类,缺省的它们是互相之间不可见的。但是,当一个类被声明为public时,它就具有了被其它包中类访问的可能性,只要这些包中的类在程序中使用import语句引入public类,就可访问它了。一个类作为整体可见,并不能代表类中的域和方法也一定可见,除非它们也被声明为public。Java程序中如果有多个类,又有public修饰符,则主类必须是public类,且只能有一个public类。3.3.2公共访问控制符public(二)2.方法被定义为public的方法是这个类对外的接口部分,程序的其它部分通过调用public方法达到与当前类交换信息、甚至影响当前类的目的。如果一个类希望作为公共工具供其它的类和程序使用,则应该把类和方法定义为public。3.3.2公共访问控制符public(三)3.域用public修饰的域被称为公共域,如果一个公共域属于一个公共类,则它可被所有其它类所引用。public修饰符会造成安全性和数据封装性下降,所以一般应减少public域的使用。3.3.3私有访问控制符(一)用private修饰的域或方法只能被该类自身所访问和修改,而不能被任何其它类(包括该类的子类)来获取和引用。private修饰符提供了最高的保护级别。例如:在200电话卡类PhoneCard200中,电话卡的密码password不能允许其它类或对象随意查看或修改,所以这个域可以声明为私有的:privateintpassword;3.3.3私有访问控制符(二)当其它类希望获取或修改私有成员时,需要借助于类的方法来实现。比如可以在类PhoneCard200中定义方法setPassword()来修改密码;从而把password完全包裹保护起来。定义方法getPassword()来获取密码;同时,为保证只有具备一定权限才能查看或修改密码,可在getPassword()方法和setPassword()方法中做必要的安全性检查,满足了一定条件才能获得或修改变量password的数值,从而保证了私有数据的私有性。3.3.4保护访问控制符protected用protected修饰的域和方法可以被三种类引用:该类自身;与它在同一个包中的其