08.面向对象程序设计进阶(下)a.ppt_第1页
08.面向对象程序设计进阶(下)a.ppt_第2页
08.面向对象程序设计进阶(下)a.ppt_第3页
08.面向对象程序设计进阶(下)a.ppt_第4页
08.面向对象程序设计进阶(下)a.ppt_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、static关键字 1、修饰变量 静态变量(类变量) country=“中国” 在JVM中,该变量只有一份拷贝,通过任何该类的实例或类本身去修改静态变量的值都是在修改同一个值 2、修饰方法(静态方法) A、可以通过类直接访问 B、静态方法只能直接访问其它的静态变量或静态方法. 3、修饰块(静态块) 一个类中可以使用不包含在任何方法体中的静态代码块(static block ),当类被载入(ClassLoad)时,静态代码块被执行,且只被执行一次,静态块经常用来进行类属性的初始化。,静态(static),Static 静态变量: 当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生

2、实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。,静态(static),静态方法: 1.在静态方法里只能直接调用同类中其它的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前不用创建任何对象。 2. 静态方法不能以任

3、何方式引用this和super关键字。与上面的道理一样,因为静态方法在使用前不用创建任何实例对象,当静态方法被调用时,this所引用的对象根本就没有产生。 3.main() 方法是静态的,因此JVM在执行main方法时不创建main方法所在的类的实例对象,因而在main()方法中,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情况,我们在以后的例子中会多次碰到。,静态(static),理解main方法 由于java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为java虚拟机在执行main()方法

4、时不必创建对象,所以该方法必须是static的,该方法接收一个String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数。,静态(static),静态块 一个类中可以使用不包含在任何方法体中的静态代码块(static block ),当类被载入时,静态代码块被执行,且只被执行一次,静态块经常用来进行类属性的初始化。例如类加载时的初始化工作,那些一次性加载不再作修改的内容。(构造器通常作实例变量初始化) 类中的静态代码块被自动执行,尽管我们产生了类的多个实例对象,但其中的静态代码块只被执行了一次。,静态(static),1、修饰变量(常量) 2、修饰方法 A、该方法不能被覆

5、盖 B、JVM会对final方法自动优化,其执行效率会比普通方法更高 3、修饰类 类不能被继承,final,Java中可以定义一些不含方法体的方法,它的方法体的实现交给该类的子类根据自己的情况去实现.这样的方法就是抽象方法,包含抽象方法的类就叫做抽象类。一个类中可以有一个或多个抽象方法。,抽象类(abstract),A、抽象方法只需声明,而不需实现。含有抽象方法的类必须被声明为抽象类,抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类也必须声明为抽象类。 B、抽象类不能实例化(即就是不能用new关键字去产生对象),抽象类的作用就是为了被继承 C、抽象类可以包含具体方法 D、当一个类

6、继承抽象类时,必须实现抽象类中的所有抽象方法,否则,这个子类也必须声明为一个抽象类 注意:含有抽象方法的类肯定是抽象类,而抽象类不一定包含抽象方法.,抽象类(abstract),如果一个抽象类中的所有方法都是抽象的,我们就可以将这个类用另外一种方式来定义,也就是接口定义。接口是抽象方法和常量值的定义的集合,从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。 但是接口和抽象类的意义就有非常大的区别,接口(interface),A、接口中所有方法都是抽象方法(abstract关键字可以省略) B、接口中可以有属性,所有属性将默认包含public、sta

7、tic、final修饰符 C、我们可以定义一个新的接口用extends关键字去继承一个已有的接口 ,我们也可以定义一个类用implements关键字去实现一个接口中的所有方法,我们还可以去定义一个抽象类用implements关键字去实现一个接口中定义的部分方法。 D、如果一个类实现了某个接口而未能实现接口中定义的所有抽象方法,则该类必须声明为抽象类 E、一个类可以继承一个父类的同时,实现一个或多个接口,extends关键字必须位于implemnets关键字之前 。(Java多继承的实现),接口(interface),为什么接口里面只能定义常量? 接口就是提供一种统一的”协议”,而接口中的属性也

8、属于“协议”中的成员。它们是公共的,静态的,最终的常量。相当于全局常量。 如果接口可以定义变量,但是接口中的方法又都是抽象的,在接口中无法通过行为来修改属性。有的人会说了,没有关系,可以通过实现接口的对象的行为来修改接口中的属性。这当然没有问题,但是考虑这样的情况。如果接口 A 中有一个public 访问权限的静态变量 a。按照 Java 的语义,我们可以不通过实现接口的对象来访问变量 a,通过 A.a = xxx; 就可以改变接口中的变量 a 的值了。那么实现接口 A 的所有对象也都会自动拥有这一改变后的 a 的值了,也就是说一个地方改变了 a,所有这些对象中 a 的值也都跟着变了。这和抽象

9、类有什么区别呢,怎么体现接口更高的抽象级别呢,怎么体现接口提供的统一的协议呢,那还要接口这种抽象来做什么呢?所以接口中不能出现变量,如果有变量,就和接口提供的统一的抽象这种思想是抵触的。所以接口中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性。 你认为是要变化的东西,就放在你自己的实现中,不能放在接口中去,接口只是对一类事物的属性和行为更高层次的抽象。,接口(interface),在Java中设计接口的目的是为了让类不必受限于单一继承的关系,而可以灵活地同时继承一些共有的特性,从而达到多继承的目的,并且避免了C+中多继承的复杂关系所产生的问题(多重继承的危险性在于一

10、个类有可能继承了同一个方法的不同实现,对于接口来说就决不会发生这种情况,因为接口是没有任何实现的)。 接口使得程序更加灵活,最终带来很大的自由.,接口(interface),抽象类里面用来定义一些公共的功能。抽象类可以理解为一个框架,根据他来派生出活生生的具体的子类. 由这些具体的类在派生出新的类来适应新的要求.如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法. 而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点.,接口(inter

11、face),接口实际上是定义一个规范、标准。 通过接口可以实现不同层次、不同体系对象的共同属性; 以JAVA数据库连接为例子: JDBC制定标准;数据厂商实现标准;用户使用标准。 接口通常用来屏蔽底层的差异。 接口也因为上述原因被用来保持架构的稳定性. 而接口(对象必须实现的承诺)与实现(对象如何履行这些承诺)相分离, 允许多个类提供相同的功能,允许一个类同时实现多个接口,最终带来很大的自由. 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。(如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染),接口(interface),一个对象多种

12、形态。 一个对象多种表现方式。 多态是面向对象里面非常重要的一个概念。,多态 polymorphism,多态分静态多态和动态多态。 静态的多态就是指函数的重载,动态的多态就是指方法的覆盖。 class Test void print() System.out.println(hello world); void print(int x) System.out.println(hello world+i); public static void main(String args) Test ts=new Test(); ts.print(); ts.print(10); 上面的程序就是在一个类中

13、成员方法的重载例子。也就是一个静态的多态。系统会在你编译的时候根据你调用的方法的参数列表来动态的决定调用那一个函数。,多态 polymorphism,多态有分两种: 编译时多态: Ainmal ainmal = new Dog(); 运行时多态: ainmal.sleep(); Animal a=new Dog();(编译时看左边) a.sleep();(运行时看右边),多态 polymorphism,Animal a=new Dog(); Dog d=(Dog)a。 (强制转换) 关系运算符:instanceof a instanceof Animal;(这个式子的结果是一个布尔表达式) a

14、为对象变量,Animal是类名。 上面语句是判定a是否是Animal的子类。如果是则返回true,否则返回false。 instanceof用于判断前面的对象变量是否是后面类的子类或者实现了同一个接口。,多态 polymorphism,对象的类型转换 A. 子类能自动转换成父类。除此之外,程序还可以直接创建一个子类的实例对象,传递给需要父类的实例对象作为参数的方法,在参数传递过程中发生了隐式自动类型转换。理解子类能够自动转换成父类:人是父类,男人是子类。 B. 父类转换成子类需要进行强制类型转换。理解父类转换成子类需要进行强制类型转换:一个男人肯定是人,一个人却不一定是男人。在不确定一个人是男

15、人还是女人的时候强行使用男人或女人的特定方法是会出现问题的,所以编译不通过。在强制类型转换时,程序员是要对转换完后的后果负责的,也就是要确保在内存中存在的对象本身确实是可以被转换的类型,否则即使编译通过,运行还是会出错的。强制类型转换的前提是程序员提前就知道要转换的父类引用类型对象的本来面目确实是子类类型的。 C. instanceof操作符 对象 instanceof 类(或接口) 返回值:ture or false,多态 polymorphism,Java是静态语言,也就是说程序的运行结果是在编译时决定的,运行时是不可以改变的。那如何让Java语言具有动态语言的特点,能够在运行时动态改变程

16、序运行的结果呢? 多态性是OOP中的一个重要特性,主要是用来实现动态联编的,换句话说,就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。使用多态就可以在运行时为我们所需要的功能提供不同的实现.这样可以提高程序的灵活性和扩展性。,多态 polymorphism,思考: 子类的功能可以被父类的方法或引用变量调用,这叫做向后兼容,可以提高程序的可扩充性和可维护性。以前写的程序可以被后来的程序调用不足为奇,现在写的程序能够调用以后写的程序(调用以后编写的子类)就非常了不起了。,多态 polymorphism,设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题

17、的思考方式。设计模式就想是经典的棋谱,不同的棋局,我们用不同的棋谱,免得我们自己再去思考和摸索。失败为成功之母,但是要以大量的时间和精力为代价,如果有成功经验可借鉴,没有人再愿意去甘冒失败的风险,我们没有理由不去了解和掌握设计模式,这也是Java开发者提高自身素质的一个很好选择。使用设计模式也许会制约你去创新,但是创新业炫耀去了解和借鉴前人的成功经验。,设计模式,单例模式 Singleton 所谓单例模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。 单例模式的实现 1.一个静态变量指向自己。 2.私有构造器保证不能从外部创建对象。 3.一个静态方法返回实例对象。,

18、设计模式,模版设计模式 在类中定义了某个算法的骨架,但不具体实现,而在其子类中实现 例如,银行计算利息,都是利率乘以本金和存款时间,但各种存款方式计算利率的方式不同,所以,在账户这个类的相关方法里,只搭出算法的骨架,但不具体实现。具体实现由各个子类来完成。,设计模式,abstract class LoanAccount /利息,本金 private double Interest,Fund; public double calculateInterest() / 取得利率 double interest=getInterestRate(); /用于计算利息的算法:本金*利率,但是利率的算法实现

19、并没有在这个类中实现 Interest=getFund()*getInterestRate(); return Interest; /*不同的存款类型有不同的利率, 因此,不在这个父类中实现利率的计算方法, * 而将它推迟到子类中实现 */ protected abstract double getInterestRate(); ,模版设计模式例子,工厂模式 工厂模式就是在声明的时候不知道到要什么对象 在使用的时候再实例化!采用接口或者基类调用! 以提高代码的复杂度为代价来增强灵活性、可复用性,维护的时候非常方便. 它为系统结构提供了灵活的动态扩展机制. 例子:fruit,farmer,设计模

20、式,工厂模式的实现: 工厂模式根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这组类有一个公共的抽象父类或接口并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。 首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法,然后需要定义一个工厂类,工厂类可以根据条件生成不同子类的实例。得到实例后,可以调用基类的方法而不必考虑到底返回的是哪个子类的实例。,设计模式,命令模式 某个方法需要完成某个功能,完成这个功能的大部分步骤已经确定了,但是有少量步骤无法确定,必须等到执行方法时才能确定。 例如:需要遍历一个数组,但是遍历完后做什么还不确定,我们必须把处理

21、行为作为参数传进去。 实现方法和行为相分离,使程序更加灵活。,设计模式,对于简单类型数据,Java对它们进行了封装,使它们都有相应的封装类,封装类,public class WrapperClass public static void main(String args) Integer i = new Integer(10); Integer j = new Integer(10); System.out.println(i=j); ,封装类的例子,定义在类里面的类。 成员内部类 静态内部类 局部内部类 匿名内部类,内部类,成员内部类 依赖于外部类存在 当一个类中的程序代码要用到另外一个类的

22、实例对象,而另外一个类中的程序代码又要访问第一个类中的成员,将另外一个类做为第一个类的内部类,程序代码就要容易编写的多。 1、可以访问外部类中所有的成员变量,所有的成员方法 2、可以有自己的成员变量;(非静态) 3、可以有自己的方法.(非静态) 4、不能有自己的静态属性和静态方法; 何时选用内部类: 假如更多是内部外部类相互调用, 很少涉及第3方调用。 选择成员内部类,内部类,为什么外部类不能访问成员内部类的实例属性? 答:因为当成员内部类对象存在时,外部类肯定存在,而当外部类对象存在时,成员内部类的对象不一定存在。,问题,静态内部类: 1、只能访问外部类中静态的属性和方法。 2、如果创建对象

23、不需要外部类的对象就可以创建; 3、可以直接调用静态内部类中的静态方法. 外部类名.内部类名.方法名 4、也可以有非静态的属性和方法;但是在静态方法中不能调用非静态的属性; 如果需要使用非静态的方法或属性需要对象进行调用; 何时选择静态内部类: 假如更多只是面向第3方客户,而内部外部类相互调用机会较少选择静态内部类。,内部类,为什么静态内部类实例方法也不能访问外部类的实例属性呢? 答:因为静态内部类是和外部类相关的,而不是和外部类的对象相关的。也就是说,当静态内部类的对象存在时,也许外部类的对象并不存在,静态内部类的对象里只有外部类的引用,而没有外部类对象的引用。如果允许访问会出现错误,问题,

24、既然内部类是外部类的成员,是否可以为外部类定义子类,在子类中再定义一个内部类来重写其父类中的内部类? 答:不可以!因为内部类的类名不再是简单地由内部类的类名组成,它实际上还把外部类名作为一个命名空间,作为内部类类名的限制。因此子类中内部类和父类中的内部类不可能完全同名,即使二者所包含的内部类的类名相同,但因为它们所处的外部类空间不同,所以它们不可能是同一个类,也就不可能重写。,问题,局部内部类: 在一个方法中声明的类。 局部内部类只在定义它的代码段中可见,不能在它所属代码段之外的代码中使用;因此也就没有public/private/default权限修饰符(无意义) 局部内部类可以访问外部类的实例变量,只能访问其所属代码段中(方法中)的final局部变量(?),但不能访问方法中的局部变量。 在类外不可直接生成局部内部类(保证局部内部类对外是不可见的)。 要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论