• 1. 类的继承和多态类的继承; 关键字super; 覆盖和重写; 对象的类型转换; 关键字final; 多态性 包的定义和使用 关键字abstract; 接口 匿名类;
  • 2. class Animal { int height,weight; void eat() { System.out.println("animal eat"); } void sleep() { System.out.println("animal sleep"); } void breathe() { System.out.println("animal breathe"); } } class Fish extends Animal { } class Integration { public static void main(String[] args) { Animal an=new Animal(); Fish fh=new Fish(); an.breathe(); fh.height=30; fh.breathe(); } }
  • 3. 4.8 类的继承 继承是一种由已有的类创建新类的机制。利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类,新类继承一般类的状态和行为,并根据需要增加它自己的新的状态和行为。 由继承而得到的类称为子类,被继承的类称为父类(超类)。 Java不支持多重继承(子类只能有一个父类)。
  • 4. 1.子类 在类的声明中,通过使用关键字extends来创建一个类的子类,格式如下: class 子类名 extends 父类名 {… } 例如: class Students extends People {… }如果一个类声明中没有使用extends关键字,这个类被系统默认为是Object的直接子类,object是java.lang包中的类
  • 5. 2.子类的继承性 子类的成员中有一部分是子类自己声明定义的,另一部分是从它的父类继承的。 所谓子类继承父类的成员变量作为自己的一个成员变量,就好象它们是在子类中直接声明一样,可以被子类中自己声明的任何实例方法操作. 所谓子类继承父类的方法作为子类中的一个方法,就象它们是在子类中直接声明一样,可以被子类中自己声明的任何实例方法调用。
  • 6. class className extends superClassName子类的定义,只要定义新增的成员子类具有父类的所有特性,另外,还可以有自己独特的特性;double area(){return 0;}int x,y;!父类的构造函数不被子类所继承
  • 7. 4.8.3 成员变量的隐藏子类定义的成员变量和继承自父类的成员变量同名时,继承的成员变量被隐藏。
  • 8. 方法的覆盖(重写)子类可以隐藏从父类继承过来的方法,即方法的重写。 在子类中定义一个与父类同名、返回类型、参数类型均相同一个方法,称为方法的覆盖。 覆盖发生在子类与父类之间。 子类可以通过方法的重写将父类的状态和行为改变为自身的状态和行为;
  • 9. 练习class SuperDemo { public static void main(String args[]) { Average ave = new Average(); ave.n = 10; float aver = ave.f(); System.out.println("average = " + aver); } }
  • 10. 运行结果: 3.141592653589793
  • 11. 特殊变量super特殊变量super,提供了对父类的访问。 可以使用super访问父类被子类隐藏的变量或覆盖的方法。 每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
  • 12. 通过super调用超类的构造函数
  • 13. 再次讨论构造函数 首先明确一点: 子类一定会调用父类的构造方法 若父类没有定义构造函数,那么对父类数据的初始化将采用系统缺省的构造函数; 若父类定义有缺省构造函数,那么子类可根据自己的需要设置自己的构造函数; 若父类定义的构造函数都是有参的,那么子类构造函数必须通过super调用父类构造函数。
  • 14. 子类方法的调用子类创建了一个对象 如果子类重写了父类的方法,那么子类调用方法就会运行重写的方法; 如果子类没有重写父类的方法,那么子类调用方法就会调用父类的方法; 如果子类重写了父类的方法,还希望调用到父类的方法,必须使用super关键字。
  • 15. 平均数 = 总和 / n; super.n = n; 求和的基数为n; super.f();求n个数的总和;
  • 16. 覆盖 VS 重载方法的覆盖发生在父类和子类之间 子类中定义的方法和父类的方法: 函数原型完全相同; 函数实现一定不完全相同; 方法的重载可以出现在一个类中,也可以出现在父类与子类的继承关系中, 重载方法的原型一定不完全相同;
  • 17. 对象的上转型对象 假设B类是A类子类或间接子类,当我们用子类B创建一个对象,并把这个对象的引用放到A类的对象中时: A a; B b=new B(); a=b; 称这个A类对象:a,是子类对象b的上转型对象. 对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原子类对象的一些属性和功能。
  • 18. 上转型对象 类型向上转换是安全的,因为这是从特殊类型到一般类型的转换。 进行向上类型转换时,出现的唯一问题是可能丢失子类中定义的方法和变量。从特殊到一般的转换,忽略了实体的特殊特性,保留下来的是和父类共有的一般属性
  • 19. (本页无文本内容)
  • 20. A a; a = new B(); A a; B b = new B(); a = b;上转对象不能操作子类新增的成员变量(失掉了这部分属性);不能使用子类新增的方法(失掉了一些功能)。 上转型对象可以操作子类继承或隐藏成员变量,也可以使用子类继承的或重写的方法。 上转型对象操作子类继承或重写的方法时,就是通知对应的子类对象去调用这些方法。因此,如果子类重写了父类的某个方法后,对象的上转型对象调用这个方法时,一定是调用了这个重写的方法。 可以将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所有属性和功能。
  • 21. 多态性 多态性就是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为 . 当一个类有很多子类时,并且这些子类都重写了父类中的某个方法。那么当我们把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个上转型对象,那么这个上转的对象在调用这个方法时就可能具有多种形态.
  • 22. 通过覆盖父类的方法来实现,在运行时根据传递的对象引用,来调用相应的方法。
  • 23. 转型操作符的优先级低于点操作符,所以向下类型转换必须使用两组括号。 point p; circle c = new circle(1,1,1); p = c; ((circle)p).area();
  • 24. 包(package)为了便于管理大型软件系统中数目众多的类,解决类命名冲突的问题,Java引入了包(package)。http://www.sunxin.org
  • 25. Java中的包与C++中的名字空间相似。在不同的包中可以有同名的类存在。 在Java中可以将自己写的类,按一定的方法归属于不同的子目录中(包)。 package语句告诉编译器当前类属于哪个包。
  • 26. package语句必须是文件中的第一条语句。也就是说,在package语句之前,除了空白和注释之外不能有任何语句。 如果不加package语句,则指定为缺省包或无名包。 包对应着文件系统的目录层次结构。 在package语句中,用“.”来指明包(目录)的层次。http://www.sunxin.org
  • 27. package语句包名可以是一个合法的标识符,也可以用若干个标识符加.分割而成。 那么目录必须包含如下的结构:package 包名;package cn.mybole;...\cn\mybole\...
  • 28. 具有包定义的类:编译、运行class A { …… } 位于...\cn\mybole\...目录中 编译:javac 源文件名 运行:位于...\cn\mybole\...的上层目录 java cn/mybole/ 类名package javagloria.javateaching; class A { …… } 位于...\cn\mybole\...的上层目录 编译:javac cn\mybole\源文件名 运行:java cn/mybole/ 类名实例程序:Test.java
  • 29. 编译并生成包在当前目录下生成包 javac -d . Test.java 在指定目录下生成包 javac -d E:\ Test.java
  • 30. import语句 使用import语句可以引入包中的类。在编写源文件时,除了自己编写类外,经常要引用Java提供的类,这些类在不同的包中。 学习Java时,使用已经存在的类,避免一切从头开始,这是面向对象编程的一个重要方面。
  • 31. import语句语法import语句位于package语句之后,类定义之前; 要引入一个包中的全部类,可以用*代替类名。 采用*号不影响程序的运行性能,但会影响编译速度。指明具体类比引入整个包更为合理。import 包名.(类名 | *); import java.awt.*; 引入java.awt包中所有类 import java.util.Date; 引入java.util中的Date类
  • 32. (本页无文本内容)
  • 33. 在同一包中的类可以互相引用,无需import语句。 如果不想通过import语句导入所需要的类,也可以写上该类的完整类名。package cn.mybole; import java.io.*; class Test1 { public static void main(String[] args) { File f=new File( "f:\\aa"); System.out.println("文件的长度:"+f.length( )); System.out.println("mybole test!"); } }实例程序:Test1.java可写成java.io.File f=new java.io.File( "f:\\aa");
  • 34. 类的说明符类的访问说明符 (1)public (2)default(不加访问说明符时) 类的其它修饰符 (1)final (2)abstract
  • 35. Public 类:可以在任何另外一个类中访问该类,不管是否在一个包中; 缺省类:只能在同一个包中的类访问缺省类。
  • 36. package cn.mybole; class Test { public static void main(String[] args) { Test2 t2=new Test2( ); } }import com.winsunlight.Test2; package cn.mybole; class Test2 { }package com.winsunlight;public实例程序:Test.java Test2.java
  • 37. final类:最终类,表示不能从该类派生出其他子类。 package cn.mybole; import com.winsunlight.Test2; class Test extends Test2 { public static void main(String[] args) { Test2 t2=new Test2( ); } } package com.winsunlight; public final class Test2 { }
  • 38. 访问权限用类创建对象以后,可以用.运算符来操作自己的变量和方法,但对象操作自己的变量和方法是有一定限制的。 访问权限是指:对象是否可以通过.运算符操作自己的变量和方法。注意:一个类中的实例方法总是可以操作该类中的成员变量;类方法总是可以操作该类中的类变量,与访问限制符没有关系。
  • 39. 访问权限限制Java提供了四种访问权限:公有、私有、保护、缺省(友元); Java提供了三个访问权限修饰符:public、private、protected; 修饰符置于每个类成员的定义之前,且仅能控制它所修饰的那个成员 。
  • 40. 方法的访问控制publicprotecteddefaultprivate同类同包子类通用性不同 情形下访问说明符
  • 41. 在同一个类中:package cn.mybole; class Test { public void pubMethod() { System.out.println("pubMethod"); } protected void proMethod() { System.out.println("proMethod"); } void defMethod() { System.out.println("defMethod"); } private void priMethod() { System.out.println("priMethod"); }public static void main(String[] args) { Test t=new Test( ); t.pubMethod(); t.proMethod(); t.defMethod(); t.priMethod(); } }在同一个类中,四类方法均可被访问。
  • 42. 方法的访问控制publicprotecteddefaultprivate同类同包子类通用性不同 情形下访问说明符
  • 43. 在同一个包中:package cn.mybole; public final class Test2 { public static void main(String[] args) { Test t=new Test( ); t.pubMethod( ); t.proMethod(); t.defMethod(); t.priMethod(); } }实例程序:Test2.javaPrivate方法只能在同一个类中访问,在同一个包中不能访问。缺省的方法和缺省的类都只能在同一个包中被访问。
  • 44. 方法的访问控制publicprotecteddefaultprivate同类同包子类通用性不同 情形下访问说明符
  • 45. 在不同包的继承关系中:对于分属于不同的包中的两个类,但这两个类之间有继承关系。package com.winsunlight; import cn.mybole.Test; public final class Test2 extends Test { public static void main(String[] args) { Test2 t=new Test2( ); t.pubMethod( ); //t.proMethod( ); //t.defMethod( ); //t.priMethod( ); } }Public和protected方法可以被访问;缺省方法和private方法不能被访问
  • 46. 方法的访问控制publicprotecteddefaultprivate同类同包子类通用性不同 情形下访问说明符
  • 47. 通用性:对于在不同的包中的没有任何关系的两个类package com.winsunlight; import cn.mybole.Test; public final class Test2 { public static void main(String[] args) { Test t=new Test( ); t.pubMethod( ); //t.proMethod( ); //t.defMethod( ); //t.priMethod( ); } }只有Public方法可以被访问;其它方法均不能被访问
  • 48. 方法的访问控制publicprotecteddefaultprivate同类同包子类通用性不同 情形下访问说明符
  • 49. final方法 为了确保某个函数的行为在继承过程中保持不变,并且不能被覆盖(overridden),可以使用final方法。 在方法定义前加上final,该方法成为终极方法 ; 包含终极方法的类仍然可以被子类继承; 该方法就不能被子类覆盖(重写);
  • 50. package cn.mybole; class Test { public final void pubMethod() { System.out.println("pubMethod");} protected void proMethod() { System.out.println("proMethod");} void defMethod() { System.out.println("defMethod");} private void priMethod() { System.out.println("priMethod");} public static void main(String[] args) { Test t=new Test( ); t.pubMethod(); t.proMethod(); t.defMethod(); t.priMethod(); } }package cn.mybole; public class Test2 extends Test { public void pubMethod( ) { } public static void main(String[] args) { Test t=new Test( ); //t.pubMethod( ); //t.proMethod( ); //t.defMethod( ); //t.priMethod( ); } }
  • 51. 关键字abstract 抽象方法:在类中仅有方法声明,但没有方法定义。 抽象类:包含抽象方法的类。
  • 52. 抽象类抽象类体现数据抽象的思想,是实现程序多态性的一种手段。 抽象类将许多有关的类组织在一起,提供一个公共的类。他刻画了公有行为的特征,并通过继承机制传送给它的派生类。 抽象类中定义抽象方法的目的是使所有子类对外都呈现一个相同名字。
  • 53. 抽象类是不能创建对象的: 因为抽象类还有尚未实现的方法,还是“抽象” 的 我们可以将一个没有任何抽象方法的类声明为abstract,避免由这个类产生任何的对象。 抽象类不能用final修饰。 构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法。
  • 54. 抽象类可以派生子类,在抽象类派生的子类中要实现抽象类中定义的所有的抽象方法。 如果一个子类没有实现抽象基类中所有的抽象方法,则子类也成为一个抽象类。
  • 55. (本页无文本内容)
  • 56. // 抽象方法 abstract class instrument { abstract void play( ); }   // wind不是抽象类 class wind extends instrument { void play( ){ System.out.println("wind play!"); } }   // percussion不是抽象类 class percussion extends instrument { void play(){ System.out.println("percussion play!"); } }
  • 57. // stringed也不是抽象类 class stringed extends instrument { void play( ){ System.out.println("stringed play!");} } // 覆盖父类中的play方法 class woodWind extends wind { void play( ){ System.out.println("woodWind play!"); } }   // 覆盖了父类中的play方法 class brass extends wind { void play( ){ System.out.println("brass play!"); } }
  • 58. public class music { static void tuneAll( instrument e[ ]){ for(int i=0;i
  • 59. 接口Java源文件就是由类和接口组成的。 接口是一系列常量和空方法的集合,它提供了多个类共同的方法,但不限制每个类如何实现这些方法。 Java允许一个类同时实现多个接口,相当于实现多继承的功能。
  • 60. 接口的定义[public] interface 接口名字 [extends 父接口列表] { 常量类型 常量名字 = 初值; 方法返回类型 方法名字( 参数表 ); } interface 接口名字;接口的声明接口体
  • 61. 定义接口实现接口
  • 62. 接口的使用一个类通过使用关键字implements声明自己使用接口,如果一个类实现多个接口,应该在接口名之间用逗号隔开。 接口中不能声明任何变量和构造函数。 class A implements Printable,Addable
  • 63. 接口的常量接口中定义的变量实际上是常量; 必须给出它们的初始值; 实现接口的类可以自由引用这些常量;interface constant { int EXCELLENT=5; int GOOD=4; int PASS=3; int FAIL=2; }
  • 64. 接口的方法当一个类实现接口时,必须实现接口的所有方法,若实现接口的类是一个抽象类,可以把实现接口的任务交给子类去实现。 在类中实现接口方法时,类中方法的原型必须和接口中声明的方法原型特征保持一致; 方法的名字、返回类型、参数个数、参数类型 若一个类声明实现一个接口,但没有实现接口中的所有方法,那么必须将该类声明为abstract类。
  • 65. interface inter { // 接口 void methodA( ); }  abstract class Derived1 implements inter { // 此处不需要写出methodA( )的原型 }   class Derived2 extends Derived1{ public void methodA( ) { // 实现方法 System.out.println("Hi,methodA"); } }
  • 66. 理解接口接口的语法很容易掌握,更重要的是要理解接口。 接口(Interface)是实现封装的一种方式。接口提供一种途径,使类隐藏其处理细节,仅对外公布它必须支持的属性。 举例:List接口定义了一个线性表操作集合。可用于ArrayList(顺序存储)和LinkedList(自由存储),它们都实现了List接口。List接口在定义时,不必考虑是ArrayList还是LinkedList,只要知道需要实现的操作有增加、删除、更新、查找。这个操作集合就是接口。
  • 67. 接口的修饰符接口体中只有常量定义和方法定义: 常量定义默认是public static常量; 方法默认是public abstract方法; 编写接口时,允许: 省略常量前面的public、final和static修饰; 省略方法前面的public、abstract修饰;
  • 68. 在子类中覆盖父类的方法时,不能降低方法的访问权限。 在实现类中实现接口抽象方法时,类中方法的访问权限不能低于在接口中定义的访问权限。接口中方法的访问权限是public的,因此实现类中实现接口的方法都要是public的访问权限。
  • 69. interface Sport { void run(); void jump(); } class Athlete implements Sport { void run() { System.out.println("短跑"); } void jump() { System.out.println("三级跳"); } public static void main(String[] args) { Athlete zhangsan=new Athlete(); zhangsan.run(); zhangsan.jump(); } }publicpublicSport.java
  • 70. 接口和抽象类的异同相同点: 二者都包含抽象方法,都必须在子类中实现方法; 不能用new关键字来创建对象; 抽象类和接口都可以被子类所继承; 接口和类一样可以有public属性,在interface前加上public关键字,表示各个包中的类均可实现接口。
  • 71. 不同点: 抽象类在定义抽象方法时,名称前必须加abstract关键字,接口则不需要。 在抽象类中,除抽象方法外,还可以定义实例变量和非空方法,而接口中只能定义常量和抽象方法; 接口允许多继承,抽象类只支持单继承。 接口的方法可以不是继承链上的类中实现,从而为相互没有关系的类能实现同样功能的一组方法提供一种有效手段
  • 72. 接口回调 接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中。那么该接口变量就可以调用被类实现的接口中的方法。 实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法 .
  • 73. 接口回调接口回调
  • 74. 接口做参数 一个方法的参数是接口类型,就可以将任何实现该接口的类的实例的引用传递给该接口参数,接口参数就可以回调类实现的接口方法。
  • 75. 接口回调
  • 76. 内部类Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌类。 内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。
  • 77. 运行结果:
  • 78. 匿名类和类有关的匿名类 当使用类创建对象时,程序允许把类体与对象的创建组合在一起 此类体被认为是该类去掉类声明后的类体,称为匿名类。 匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明一个对象,但是可以创建一个对象。new people() { 匿名类的类体 }用people类创建对象
  • 79. 尽管匿名类的对象没有经过类声明,但匿名对象的引用必须传递给一个匹配的参数,匿名类的主要用途就是向方法传递参数值。void f(B x) { x调用B类的方法 }f(new B() { 匿名类的类体 } )方法的定义 参数是B类的对象 方法的调用 向参数x传递一个匿名对象
  • 80. A a = new A(); a.f(new Cubic() { double getCubic(int n) { return n*n*n; } } );
  • 81. 和接口有关的匿名类 Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了接口的类去掉类声明后的类体,称为匿名类。 new Computable() { 实现接口的匿名类的类体 }void f(Computable x) { …… }f(new Computable() { 实现接口的匿名类的类体 } )
  • 82. finalize Java的垃圾回收器具有自动回收垃圾的能力。 垃圾回收器是一个优先级比较低的线程,在系统空闲时运行。 在对象被回收之前,有时需要执行一些特殊的操作,例如保存文件、清除屏幕等,这时就要用Java的finalize方法。
  • 83. (本页无文本内容)
  • 84. (本页无文本内容)
  • 85. new创建对象调用对象的构造函数 父类构造函数→子类构造函数对象=null;对象变成了垃圾 System.gc()是个异步命令,在随后的时间内,调用对象的finalize函数