JavaOO-08.面向对象高级特性.ppt

上传人:小飞机 文档编号:6509356 上传时间:2023-11-07 格式:PPT 页数:61 大小:705.50KB
返回 下载 相关 举报
JavaOO-08.面向对象高级特性.ppt_第1页
第1页 / 共61页
JavaOO-08.面向对象高级特性.ppt_第2页
第2页 / 共61页
JavaOO-08.面向对象高级特性.ppt_第3页
第3页 / 共61页
JavaOO-08.面向对象高级特性.ppt_第4页
第4页 / 共61页
JavaOO-08.面向对象高级特性.ppt_第5页
第5页 / 共61页
点击查看更多>>
资源描述

《JavaOO-08.面向对象高级特性.ppt》由会员分享,可在线阅读,更多相关《JavaOO-08.面向对象高级特性.ppt(61页珍藏版)》请在三一办公上搜索。

1、第八章,面向对象高级特性,本章要点,static的含义继承的规则子类实例化的过程方法的覆盖final关键字抽象类的特性接口的规范数据类型的转换包和访问权限修饰符包装类和内部类,静态修饰符static,static可以修饰的元素 属性 共享;分配在静态存储区,而不是分配在堆内存中。静态属性描述了该类的所有对象的共同特征,而非静态属性描述的是每个对象独有的特征,静态属性可以不用实例化,可以直接访问。因为访问的都是同一块内存,所以变量的值是一样的。静态属性在该类第一次被加载到JVM时,分配了静态存储区,以后每次运行不再分配空间,仍然使用以前的空间。直到JVM停止之前,静态存储区的变量一直存在,不会失

2、效。方法 访问的方式块 执行的时机只能修饰类成员,不能修饰局部变量。需要注意的问题:静态方法可以直接访问静态变量,如要访问非静态变量必须先实例化。静态方法中不能this。静态方法不能被非静态方法覆盖。,静态属性,所有对象共享也称为类变量两种方式访问:类名.属性;对象名.属性;,0 x8000,0 x3000,200,Circle p,0 x3000,radius,100,radius,Circle q,0 x8000,3.14,pi,静态存储区,静态方法,不需要实例化,可以直接访问;也称为类方法因为该方法对于类的所有对象来说已经是共享的了。两种方式访问:直接访问:类名.方法名();实例化后访问

3、:对象名.方法名();作用:简化方法的使用;比如Math类中的所有方法都是静态的。便于访问静态属性;常提供静态方法访问静态属性。限制:静态方法只能直接访问静态成员(静态属性、静态方法)。因为静态方法在实例化之前就可以被类调用,而此时非静态成员还不存在。静态方法中不能用this;静态方法不能被非静态方法覆盖;,特殊的静态方法main,在类中有一个我们经常使用的静态方法main(),它是程序执行的入口。一般来说,在一个项目中应该有一个类提供了main函数,整个项目从这个main方法开始运行。该方法的格式是固定的,除了括号中的形参名称可以改变,别的都不能改变必须public权限修饰符:保证在任何位置

4、都可以访问它。必须static静态修饰符:无需实例化,可以直接调用。必须返回空值void:main方法仅是程序的启动没必要返回任何值。main函数名不可改变:固定的,注意大小写。String args命令行参数:从程序外部传入的参数。那么,请思考:主函数会被谁调用呢?,主函数main(),一般运行一段程序都是通过Java解释器的。D:javac Circle01.java 进行编译生成字节码;D:java Circle01 进行运行;而不是 D:java Cirlce01.classJava解释器是通过类名找到字节码文件的,再找到该字节码文件中的main函数的,然后执行整个程序。Java要求类

5、名必须和文件名相同也就是这个道理,否则java解释器就找不到字节码文件了。Java解释器在调用main方法时,直接通过类名调用这个静态方法,没有必要先实例化类再通过对象来调用。这样不仅减少程序执行的步骤,还保证程序运行的效率。可以明白,main函数的static 修饰符是非常重要的。,变量初始化的顺序,隐式赋予变量默认值;显式赋予初始值;构造方法体赋予新值;注意:可能有的程序第2、3赋值步骤不存在,但是必定有第1个步骤。见示例PersonVariableOrder.java每实例化一个对象,属性在堆内存中的值,就是如上这3个步骤的结果。所以对于非静态属性,每次实例化时都要按以上步骤赋值。静态的

6、属性就不同,因为它是类属性,不属于任何对象,也可以说它被所有对象共享。它在第一次装载到JVM时被赋值,对象实例化时不需要给静态属性赋值。总之,静态属性的赋值要优先于非静态属性的赋值。而且,静态属性的赋值只有一次,非静态属性的赋值要发生多次。,程序块,静态程序块非静态程序块,类的继承 Inheritance,格式:Java中只能单继承,也就是说每个类只能有一个父类。,修饰符 class 子类名 extends 父类名,生物,植物,动物,人类,猫类,继承 续,子类实际上继承了父类的所有特征,同时子类在父类的基础上还增加了自己的特征。所以,子类和父类相比具有更丰富的功能。其实,在继承关系中我们还能发

7、现一个规律:子类是父类的一种,也可以说“子类就是父类”。如:人类就是动物,动物就是生物。记住这个定律对我们理解继承的概念非常有帮助。但是,反过来看,父类是子类的说法正确吗?见示例 Person.java、Student.java,类的继承(续),父类的别名:基类BaseClass超类SuperClass子类的别名:衍生类Child ClassDerived Class,类继承的规则,子类继承父类的所有属性和所有方法;但是构造器不继承;,Vehicle,typetopSpeed,start()stop(),MotorVehicle,typetopSpeedcylinders,start()sto

8、p(),Car,typetopSpeedcylinders,start()stop()squeal(),Boat,typetopSpeedcylinders,start()stop()sinkBoat(),子类实例化的过程,子类实例化是先实例化其父类,然后实例化子类。要先调用父类的构造器,父类构造器运行完毕,才调用子类的构造器。如果实例化类D,说出构造器执行的顺序。总之,一个类的实例化不仅要调用本类的构造器,还要调用它所有父类的构造器,先完成父类构造器中的代码,最后完成本类构造器中的代码。,A,B,C,D,E,super和this关键字,如果父类Person具有多个构造器重载,那么子类Stud

9、ent实例化时如何选择调用父类的构造器呢?super()作用:调用父类的构造器只能出现在子类的构造器中,且必须是第一行super()中的参数,决定了调用父类哪个构造器如果子类构造器中没有出现super,那么默认super(),即调用父类的空构造器。this()作用:调用本类的构造器只能写在构造器的第一行在同一个构造器中super()和this()不能同时出现,super和this关键字(续),super.指向父类的引用。通过关键字super我们可以指定子类在构造时调用父类的哪个构造器,达到先实例化父类然后实例化子类的目的。子类的构造器默认的调用父类无参构造器,即子类构造器中没有用super指明

10、调用父类哪个构造器的话,实际上编译器会自动的在子类构造器第一行加入代码super();this.我们知道子类在实例化时必须调用父类的构造,实际上有的子类构造也可以先调用本类的其他构造,然后在通过那个构造调用父类的构造无论是调用父类的构造还是子类的构造,最终都是找到最顶级的父类自上而下的实例化。只要中间环节有一个构造没找到,这个子类就无法完成实例化。见示例!指向本类的引用。,方法的覆盖,所谓“覆盖(override)”是在声明子类的成员方法时,其名称和参数都与父类的成员方法的名称和参数一样,在面向对象的程序设计中称为方法的覆盖。,方法覆盖的规则,在父子类之间继承时发生多个方法的名称相同返回值类型

11、必须相同每个方法参数数量和参数类型和顺序相同权限修饰符要求:子类方法的要不小于父类方法的子类方法只能抛出父类方法异常或其异常的子类。方法覆盖如下例所示:父类方法:protected void getArea(int w,int h)throws IOException;子类方法:public void getArea(int x,int y)throws FileNotFoundException;,关键字final,final可以修饰的元素:变量(属性和局部变量):不能被重新赋值;可以在声明的同时赋值,还可以在构造器中赋值,其他的方法中不能够赋值。在程序中经常使用的一些常量,如圆周率,没必要

12、在程序中频繁的修改它那么我们可以:首先把它设置为静态static,多个实例共享该常量,没有必要每个对象保存一份;其次,设置为final类型,赋值以后不能再改变;最后注意遵守常量命名规范,所有字母大写、单词之间用下划线。方法:不能被子类覆盖、重写,即不能修改。类:不能被继承、不能产生子类。,抽象方法,只有方法声明,没有方法实现的方法;抽象方法必须用abstract声明,没有方法体,以“;”结尾。,public abstract void getArea();,抽象类,含有抽象方法的类必须声明为抽象类;用abstract声明class。,public abstract class Rectangl

13、e public abstract void getArea();,抽象类的规则,注意:抽象类不能被实例化;因为即使实例化以后我们也无法调用对象的抽象方法。所以抽象类只能作为父类使用,让其他类继承抽象类。其包含的抽象方法必须在其子类中被实现,否则该子类只能声明为abstract;抽象方法不能为static;在下列情况下,一个类必须声明为抽象类:当一个类的一个或多个方法是抽象方法时;当类是一个抽象类的子类,并且没有实现父类的所有抽象方法,即只实现部分;当一个类实现一个接口,并且不能为全部抽象方法都提供实现时;,抽象类的思考,抽象类是否能够实例化?抽象类是否需要构造器?,抽象类的本质,抽象类是抽象

14、方法和非抽象方法的集合特殊情况全部是抽象方法全部为非抽象方法实际上是一套规范,它规定了子类必须定义的方法,除非子类严格的执行了这套规范,否则这个子类将不能实例化和使用。,接口interface,接口不是一个类,不能实例化;接口是常量和抽象方法的集合;接口对类来说是一套规范,是一套行为协议;定义格式如下:,public interface MyInterface interfaceBody,类实现接口,接口实质上就是一个常量和抽象方法的集合。为了使用一个接口,你要编写实现接口的类。如果一个类要实现一个接口,那么这个类就必须实现接口中所有抽象方法。否则这个类只能声明为抽象。格式如下:,public

15、 class MyClass implements MyInterface/实现接口中所有抽象方法,接口的特点,接口使用interface关键字来定义,而不是class。接口中定义的变量都是公共静态最终变量。接口中没有自己的构造函数,而且接口中定义的方法全部都是抽象方法,即只提供方法的定义,而没有提供方法的具体实现的语句。接口采用多继承机制,而不像类一样采用单继承机制。如果在实现某个接口的同时还继承了某个类,那么,extends要写在 implements之前。接口默认:常量:public static final抽象方法:public abstract,接口与抽象类的区别,接口不能含有任何非

16、抽象方法,而抽象类可以。类可以实现许多接口,但只能有一个父类。接口和接口之间可以多继承 如:public interface A extends B,C B,C也是接口.接口不是类分级结构的一部分,没有联系的类可以实现相同的接口。抽象类可以理解为抽象方法和非抽象方法的混合体,而接口中的方法完全是抽象方法,是一套纯粹的规范。一般来说,有关系的类才能继承同一个抽象类,而无关的类不可能有同一个抽象父类,但是无关的类可以实现同一个接口。,类的继承,interface,implements,class A implements C,D,class,class,class A extends B,inte

17、rface,class,implements,class A implements C,class,class,class A extends B implements C,implements,interface,implements,interface,class A extends B implements C,D,抽象类的继承,class,abstract class,class A extends B,abstract class,abstract class A extends B,abstract class,implements,interface,abstract class

18、 A implements C,D,implements,interface,abstract class A implements C,abstract class,interface,abstract class A extends B implements C,D,interface,implements,接口的继承,interface A extends B,interface,interface,interface,interface A extends B,C,D,interface,访问接口中常量,public static final int MAX_SPEED=100;接口中

19、的常量默认为public static final类型。有三种方式:对象名.MAX_SPEED类名.MAX_SPEED接口名.MAX_SPEED,引用数据类型的转换,前提:具有继承关系原则:子类就是父类具有继承关系的引用变量才能互相转换向上造型:由于子类是父类的一种,子类转换为父类,自动转换;如:Student s=new Student();Person p=s;/赋值时发生类型转换。或是可直接简写:Person p=new Student();,生物,植物,动物,人类,猫类,向上造型,引用数据类型的转换(续),向下造型:强制转换曾经向上转换过的对象,才能再向下转换。对象不允许不经过上溯造型

20、而直接下溯造型。如下写法是会出现语法错误:Person p=new Person();Student s=(Student)p;向上转换损失了子类新扩展的属性和方法仅剩下父类中声明过的属性和方法,Person p=new Student();/先上溯转型Student s=(Student)p;/再向下转型,instanceof运算符,其实经过上溯和下溯造型之后,我们很难知道某个引用到底指向哪种类型的对象了。可以通过instanceof来判断该经过上溯转型后是哪一个子类的。见实例。instanceof运算符的一般格式:object instanceof classobject instance

21、of interface返回值都是boolean,所有类的父类 Object,Object类是所有类的超类,在Object类中定义的方法,在所有类中都可以使用。一个类可以不是Object类的直接子类,但一定是Object类的子类,Java中的每一个类都是从Object扩展来的。Object是Java语言中唯一一个没有父类的类。Object类常用方法:public int hashCode():该方法返回对象的哈希码,哈希码是一个代表对象的整数,比作对象的身份证号。在程序运行期间,每次调用同一个对象的hashCode()返回的哈希码必定相同,但是多次执行同一个程序,程序的一次执行和下一次执行期间

22、同一个对象的哈希码不一定相同。实际上默认的哈希码是将对象的内存地址通过某种转换得到的,所以不同对象会有不同的哈希码。返回十六进制整数,唯一标识一个对象public String toString()返回 类名hashcode。事实上返回这样的字符串没有什么实际的意义。一般子类都会覆盖该方法,让它返回有意义的文本。public boolean equals(Objectobj)比较两个对象引用的值是否相等(比较地址)。指出调用该方法的对象是否与obj对象相等。即地址是否相等。,续,通常,子类会覆盖equals(),改变它的含义,所以有的类中equals()是比较地址,有的类中该方法就不比较地址,

23、具体的,就看子类新定义的该方法的规定在java中有个规定:如果equals()返回两个对象是相等的,那这两个对象上调用hashCode()返回的整数必须相等。否则在使用Hash类型集合时就会产生错误。所以在我们覆盖equals()方法同时,还要记得覆盖hashCode()方法。需要说明,如果equals()返回两个对象不等,它们的hashCode()也可以返回相同的整数。但是最好让它们的hashCode()返回不同的整数,这有利于提高Hash类型集合的性能。,equals()与=的区别,理解equals()方法和=运算符的区别是非常重要的。equals()只能比较引用类型,=既能比较引用类型又

24、能比较基本类型。equals()方法从Object类继承原意:比较对象引用的值一般都被子类方法覆盖,不再比较引用的值=运算符比较基本数据类型:相当于算术等号比较引用数据类型:比较引用的值,不能被覆盖。,多态,见示例TestPolymorphism.javapublic class TestPolymorphism public static void main(String args)Shape s1=new Rectangle(10,20,Red);Shape s2=new Circle(10,Gold);Shape s3=new Triangle(3,4,5,Blue);s1.showAl

25、l();s2.showAll();s3.showAll();三个子类都分别上溯造型为Shape,变量s1,s2,s3都是Shape类型,调用的也都是showAll(),然而从输出结果上看出执行的并不是同一个方法体。实际上这种情况,执行哪个方法体不是由调用方法的引用类型决定的,而是由这些引用所代表的具体对象类型决定的。实际上s1指向了Rectangle类对象。所以执行的方法各不相同。Java中这种相同类型的变量,调用相同的方法,执行的具体代码不同的现象为“多态”。多态的机制多态只能发生在非静态方法上,对于静态方法和属性则不会发生多态。静态方法和属性的调用仅决定于调用他们的引用类型,和该引用所指向

26、的对象无关。分为两种表现形式,OverWrite,Override:重写、重载。,Java中常用的包,项目中所有的类都必定隶属于某一个包,不存在不属于任何包的类。包像目录和文件夹一样可以进行嵌套,有自己的规范:要求包名必须全部是小写字母,通常由公司名称、项目名称、功能名称组成。java.langJava语言包,任何程序中,该包都被自动导入。java.awt图形用户界面包。图形用户界面事件处理包。java.swing跨平台轻量级组件包。,Java中常用的包(续),java.sql数据库访问包。java.io这个包由对您的输入/输出操作有用的类组成。java.util该包提供了许多创建如:list

27、s,calendar,date等所需要的类和接口。该包提供了许多进行TCP/IP网络编程的类和接口。,用import引入包,导入包中所有的类:依照下列语法导入单个类:导入网络包中所有的类:,import package_name.*;,import package_name.class_name;,import.*;,把自己的类打包,01/*02*(#)Frame.java 1.134 02/04/1103*04*Copyright 2002 Sun Microsystems,Inc.All rights reserved.05*SUN PROPRIETARY/CONFIDENTIAL.06*

28、/07 package com.neusoft;08 09 import java.awt.peer.FramePeer;10 import java.awt.event.*;,把类打包到com.neusoft,把自己的类打包,包名全部小写语句只能出现一条,且只能在首行(除注释)编译打包的类javac-d c:ABC.java包是类的一部分,访问权限修饰符,使用访问权限修饰符对类的成员进行控制,在java中称为“封装”。不过不要把封装理解为private,不要误认为不能访问成员才是封装。实际上对成员访问权限的任何控制(包括public)都可以称为封装机制。构造器和类的权限通常为public;p

29、rivate权限最小,限制类外访问,一般把属性设为private,让其他类不能直接访问属性,达到保护属性的目的;friendly是默认权限,即不使用权限修饰符时,即为friendly,该权限声明的成员在类内以及在同一个包中的其他类可以访问;而protected所修饰的成员在类内、同一个包中、所在类的子类中都可以访问。public protected friendly private封装,Employee,public namepublic phoneprivate salary,public sayHello()private writeMail(),Employee,public namep

30、ublic phone,public sayHello(),从类外看,续,不过类只有两种权限:public,friendly.一般情况下我们只在类的成员上设置权限控制,而不在类上做权限控制,所以通常类的权限为public。如果把类设为friendly,那么只有该包中的类能够访问它,其他包中的类将无法使用这个类。,访问权限修饰符(续),包,包装类wrapper,Everything is object.Java编程语言不把基本数据类型看作对象。Java 编程语言提供包装类来将基本数据类型看作对象。在功能上包装类能够完成数据类型之间(除boolean)的相互转换,尤其是基本数据类型和String类

31、型的转换。包装类中包含了对应基本数据类型的值,封装了String和基本数据类型之间相互转换的方法,还有一些处理这些基本数据类型时非常有用的属性和方法。,bytecharshortintlongfloatdoubleboolean,ByteCharacterShortIntegerLongFloatDoubleBoolean,包装,基本数据类型,引用数据类型,包装类的创建方法,基本数据类型通过构造器转换为包装类,int pInt=500;Integer wInt=new Integer(pInt);Integer a=new Integer(3);,包装类的几个通用方法,primitive wr

32、apperContructorString wrapperContructor(除Character,注意Boolean)static valueOf(String s)静态有参数wrapper primitivetypeValue()无参数String primitivestatic parseType()equals():该方法是包装类中重写了Object类里的equals(),新的equals()不在比较引用的值,而是比较被包装的基本数据类型的值是否相等。见示例TestWrapperEquals.javatoString():在包装类中的该方法也被重写,它返回的不再是含有哈希码的字符串了

33、,而是返回被包装的基本数据类型的值。,数据类型转换图,字符串String,包装类Wrapper,基本数据类型,构造器或valueOf(),toString(),typeValue(),构造器,parseType(),内部类的定义及特点,我们知道类的成员包括:属性、方法、构造器、程序块。实际上还包括类。这个被嵌套在一个类里面的类,称为内部类。内部类就是定义在另一个类内部的类。内部类对于同一包中的其它类来说,内部类能够隐藏起来。因为:普通类的权限只有public 和friendly,而内部类作为类的成员,可以和其他成员一样使用所有4种权限。其实,如果没有特殊需要,尽量让内部类为private,避免

34、暴露内部类给其他类。,内部类和外部类之间的访问,内部类的方法可以访问外部类的成员(包括私有的),且不必实例化外部类;相反则不同,外部类要访问内部类的成员必须先实例化内部类,通过内部类对象类访问。outerInnerClass.TestOuterInnerClass.java无需创建外部类的对象,即可从内部类访问外部类的变量和方法。必须创建内部类的对象,否则无法从外部类访问内部类的变量和方法。如果内部类中有和外部类同名的变量或方法,则内部类的变量和方法将获得比外部类的变量和方法更高的优先级。见示例 outerInnerClass InnerFirstofOuter.javaJava规定在内部类中

35、不能定义static变量,只能定义非静态成员。,从其他类访问内部类,在Outer内访问Inner,只需如下:Inner in=new Inner();在Outer外访问Inner,必须如下:Outer o=new Outer();/实例化外部类Outer.Inner oi=o.new Inner();/实例化内部类,内部类的权限修饰符,普通类的访问控制方式friendlypublic内部类定义为privateprotectedpublicfriendly,静态内部类,内部类也可以声明为static,即静态内部类。静态内部类与普通内部类不同:静态内部类作为外部类的静态成员,不能访问外部类的非静态

36、成员;非静态内部类只能定义非静态成员,而静态内部类可以定义静态成员和非静态成员见示例:outerInnerClass.StaticofInnerClass.java,局部内部类,class A int a;public void method(int c)int b=0;class B,class A int a;public void method()class B,静态内部类,Outer.Inner inn=new Outer.Inner();非静态内部类不可以使用上面的方式可以定义static变量就相当于定义在外部的类。,局部内部类举例,01 public class Outer2 02 public int a=1;03 private int b=2;04 public void method(final int c)05 int d=3;06 final int e=2;07 class Inner 08 private void iMethod(int e)09/System.out.println(e);10 11 12 13,Question And Answer,本章小结,static的含义继承的规则子类实例化的过程方法的覆盖final关键字抽象类的特性接口的规范数据类型的转换包和访问权限修饰符包装类和内部类,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号