第六章高级语言特征 第六章高级语言特征 本模块讨论Java编程语言更多的面向对象特征 -- object-Oriented Progra Handling User Interfaces BadneSs TheAT JavR Componant Lacy A M ultith reading 第一节相关问题 讨论一下述问题与本模块中出现的材料相关: 如何保持一个类或方法不被分成子类或被覆盖? 如何将数组概念的使用扩展到对象? 第二节目的 完成本模块的学习后,应该能 描述 static变量,方法和初始程序 描述 final类,方法和变量 列出访问控制级别 确认降级类并解释如何从JKL.0升迁到JDK1.1到JDKL.2 描述如何应用收集和反射 在Java软件程序中,确认 static方法和变量 public, private, protected和缺省变量 使用 abstract类和方法 解释如何以及何时使用内部类 解释如何以及何时使用接口 描述=和 equals(之间的不同
第六章 高级语言特征 76 第六章 高级语言特征 本模块讨论 Java 编程语言更多的面向对象特征。 第一节 相关问题 讨论-下述问题与本模块中出现的材料相关: - 如何保持一个类或方法不被分成子类或被覆盖? - 如何将数组概念的使用扩展到对象? 第二节 目 的 完成本模块的学习后,应该能 - 描述 static 变量,方法和初始程序 - 描述 final 类,方法和变量 - 列出访问控制级别 - 确认降级类并解释如何从 JDK1.0 升迁到 JDK1.1 到 JDK1.2 - 描述如何应用收集和反射 - 在 Java 软件程序中,确认 - static 方法和变量 - public,private,protected 和缺省变量 - 使用 abstract 类和方法 - 解释如何以及何时使用内部类 - 解释如何以及何时使用接口 - 描述==和 equals()之间的不同
第六章高级语言特征 第三节类( static)变量 类( static)变量 在所有类的实例中共享 可以被标记为 public或 private 如果被标记为 public而没有该类的实例,可以从该类的外部访问 public class Count i private int serialNumber; private static int counter =0 counter++ serialNumber counter 有时想有一个可以在类的所有实例中共享的变量。比如,这可以用作实例之间交流的基础或追踪已经创建的实例的 数量。 可以用关键字 static来标记变量的办法获得这个效果。这样的变量有时被叫做 class variable,以便与不共享的成 员或实例变量区分开来。 public class Count t private static int counter =0; public Count() counter+ti serialNumber 在这个例子中,被创建的每个对象被赋于一个独特的序号,从1开始并继续往上。变量 counter在所有实例中共享, 所以,当一个对象的构造函数增加 counter时,被创建的下一个对象接受增加过的值 Static变量在某种程度上与其它语言中的全局变量相似。Java编程语言没有这样的全局语言,但 static变量是可 以从类的任何实例访问的单个变量 如果 static变量没有被标记成 private,它可能会被从该类的外部进行访问。要这样做,不需要类的实例,可以通 过类名指向它 public class staticvar public static int number; public class otherClass public void method() int x= staticvar number 第四节类( static)方法 类( static)方法 没有它所属的类的任何实例, static方法可以被调用 ublic class generalFunction i public static int addU(int x, int y)i tun x+
第六章 高级语言特征 77 第三节 类(static)变量 类(static)变量 在所有类的实例中共享 可以被标记为 public 或 private 如果被标记为 public 而没有该类的实例,可以从该类的外部访问 public class Count { private int serialNumber; private static int counter = 0; public Count() { counter++; serialNumber = counter; } } 有时想有一个可以在类的所有实例中共享的变量。比如,这可以用作实例之间交流的基础或追踪已经创建的实例的 数量。 可以用关键字 static 来标记变量的办法获得这个效果。这样的变量有时被叫做 class variable,以便与不共享的成 员或实例变量区分开来。 public class Count { private int serialNumber; private static int counter = 0; public Count() { counter++; serialNumber = counter; } } 在这个例子中,被创建的每个对象被赋于一个独特的序号,从 1 开始并继续往上。变量 counter 在所有实例中共享, 所以,当一个对象的构造函数增加 counter 时,被创建的下一个对象接受增加过的值。 Static 变量在某种程度上与其它语言中的全局变量相似。Java 编程语言没有这样的全局语言,但 static 变量是可 以从类的任何实例访问的单个变量。 如果 static 变量没有被标记成 private,它可能会被从该类的外部进行访问。要这样做,不需要类的实例,可以通 过类名指向它。 public class StaticVar { public static int number; } public class OtherClass [ public void method() { int x = StaticVar.number; } } 第四节 类(static)方法 类(static)方法 没有它所属的类的任何实例,static 方法可以被调用 public class GeneralFunction { public static int addUp(int x, int y) { return x + y;
第六章高级语言特征 public class Use General i int c= GeneralFunction addu(a, b); System. out println("addupo gives"+c); 当没有一个特殊对象变量的实例的时候,有时需要访问程序代码。用关键字 static标记的方法可以这样使用,有时 被称做 class method. static方法可以用类名而不是引用来访问,如 public class GeneralFunction t public static int addUp(int x, int y) public class UseGeneral t ublic void int a =9 int b int c=GeneralFunction. addup(a, b)i System. out. println("addup()gives c 因为 static方法不需它所属的类的任何实例就会被调用,因此没有this值。结果是, static方法不能访问与它本 身的参数以及 static变量分离的任何变量。访问非静态变量的尝试会引起编译错误 「注-非静态变量只限于实例,井只能通过实例引用被访问。 public class wrong t public static void main(String args [])i x =9:// COMPILER ERROR! Import points to remember about static me thods Main0是静态的,因为它必须在任何实例化发生前被顺序地访问,以便应用程序的运行 静态方法不能被覆盖成非静态 第五节静态初始化程序 静态初始化程序 在 static block中,类可以包含方法程序中不存在的代码 当类被装载时,静态代码块只执行 程序体中不存在的代码在 static block中类可以包含该代码,这是完全有 当类被装载时,静态块代码只 执行一次。类中不同的静态块按它们在类中出现的顺序被执行
第六章 高级语言特征 78 } } public class UseGeneral { public void method() { int a = 9; int b = 10; int c = GeneralFunction.addUp(a, b); System.out.println("addUp() gives " + c); } } 当没有一个特殊对象变量的实例的时候,有时需要访问程序代码。用关键字 static 标记的方法可以这样使用,有时 被称做 class method。static 方法可以用类名而不是引用来访问,如: public class GeneralFunction { public static int addUp(int x, int y) { return x + y; } } public class UseGeneral { public void method() { int a = 9; int b = 10; int c = GeneralFunction.addUp(a, b); System.out.println("addUp() gives " + c); } } 因为 static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值。结果是,static 方法不能访问与它本 身的参数以及 static 变量分离的任何变量。访问非静态变量的尝试会引起编译错误。 注-非静态变量只限于实例,并只能通过实例引用被访问。 public class Wrong { int x; public static void main(String args[]) { x = 9; // COMPILER ERROR! } } Import points to remember about static methods: Main()是静态的,因为它必须在任何实例化发生前被顺序地访问,以便应用程序的运行。 静态方法不能被覆盖成非静态。 第五节 静态初始化程序 静态初始化程序 在 static block 中,类可以包含方法程序中不存在的代码。 当类被装载时,静态代码块只执行一次。 方法程序体中不存在的代码在 static block 中类可以包含该代码,这是完全有效的。当类被装载时,静态块代码只 执行一次。类中不同的静态块按它们在类中出现的顺序被执行
第六章高级语言特征 public class staticIni tDemo t static int i =5 System. out. println("Static code i=+ i++ public class Test public static void main(string args[])i System. out. println(Main code: i StaticInit Demo i)i 将打印出 Main code: 1=6 Static方法和数据 第六节一个完整的例子 1. class MyClass t stat nt statIn 4 3. static Double statDouble =16.0; 4 int ins tInt double instDouble ublic static void statMethod(t System. out. println ("statInt=+statInt+ n;statdouble=+statDouble) 11. public static void ins tMethod()I 12. System. out. println("instInt= +instInt+ 13 ";instdouble="+instDouble) 4.} 15. public MyClass (int intArg, double doubleArg) instIt intArg 17. instDouble doubleArgi 1 19. public static void main(string args[])t 20. MyClass instance new MyClass(1,2.0) 1. MyClass instance new MyClass(3,4.0)
第六章 高级语言特征 79 public class StaticInitDemo { static int i = 5; static { System.out.println("Static code i= "+ i++ ); } } public class Test { public static void main(String args[]) { System.out.println("Main code: i=" + StaticInitDemo.i); } } 将打印出: Static code: i=5 Main code: i=6 Static 方法和数据 第六节 一个完整的例子 1. class MyClass { 2. static int statInt = 4; 3. static Double statDouble = 16.0; 4. int instInt; 5. double instDouble; 6. 7. public static void statMethod(){ 8. System.out.println ("statInt="+statInt+ 9. ";statdouble="+statDouble); 10.} 11.public static void instMethod(){ 12. System.out.println("instInt="+instInt+ 13. ";instdouble="+instDouble); 14.} 15.public MyClass(int intArg, double doubleArg){ 16. instInt = intArg; 17. instDouble = doubleArg; 18.} 19.public static void main(string args[]){ 20. MyClass instance1 = new MyClass(1,2.0); 21. MyClass instance2 = new MyClass(3,4.0); 22.
第六章高级语言特征 Myclass. statMethod (i //Outputs: stat Int=4 26. instance. instMethod ();//Outputs: instInt=l 28. instance. statMethod()i //outputs: statIn=4; //statDouble=16.0 31. instance. instMethod ()i//outputs: instInt=3; //instDouble=4.0 33. instance. statMethod (i//outputs: statIn=4 //stat Double=16.0 333 图6-1是 MyClass类定义的框图。这个例子阐述了 1. Static方法和数据的单个(共享)副本是因为类和该类的所有实例而存在。通过一个实例或通过类本身可 以访问 static成员 2.非静态数据只限于实例,只能通过该实例的非静态方法对它进行访问。非静态数据定义对象之间互不相同 的特点,非静态方法在它们所作用的非静态数据的基础上对每个对象的行为互不相同。 考虑一下模仿汽车的特殊类型的一个对象的实例。轮子的大小,对该类型的所有汽车来说是个常量,可能被模仿成 My Class Instance 1 instance data instant =1 instance. instMe thod instDouble 2.0: statMethodo and maino Myclass class(static)data statMe thod and main( Instance 2 instance data 1060 statMethodo and maino instance. instMethodo
第六章 高级语言特征 80 23. MyClass.statMethod(); //Outputs:statInt=4; 24. //statDouble=16.0 25. 26. instance1.instMethod(); //Outputs:instInt=1; 27. //instDouble=2.0 28. instance1.statMethod(); //Outputs:statInt=4; 29. //statDouble=16.0 30. 31. instance2.instMethod(); //Outputs:instInt=3; 32. //instDouble=4.0 33. instance2.statMethod(); //Outputs:statInt=4; 34. //statDouble=16.0 35.} 36.} 37. 图 6-1 是 MyClass 类定义的框图。这个例子阐述了: 1. Static 方法和数据的单个(共享)副本是因为类和该类的所有实例而存在。通过一个实例或通过类本身可 以访问 static 成员。 2. 非静态数据只限于实例,只能通过该实例的非静态方法对它进行访问。非静态数据定义对象之间互不相同 的特点,非静态方法在它们所作用的非静态数据的基础上对每个对象的行为互不相同。 考虑一下模仿汽车的特殊类型的一个对象的实例。轮子的大小,对该类型的所有汽车来说是个常量,可能被模仿成
第六章高级语言特征 个静态变量。颜色根据对象的不同而不同,其行为也根据对象的不同而不同,在它所作用的非静态数据的基础上对不 同对象返回不同的颜色 图6-1 Myclass例子 第七节关键字 final 6.7.1Fina1类 关键字 final Final类不能被分成子类 Fina1方法不能被覆盖 Final变量是常数 Java编程语言允许关键字 Final被应用到类中。如果这样做了,类便不能被子分成子类。比如,类Java.lang. String 就是一个fina1类。这样做是出于安全原因,因为它保证,如果方法有字符串的引用,它肯定就是类 String的字符串, 而不是某个其它类的字符串,这个类是 String的被修改过的子类,因为 String可能被恶意窜改过 6.7.2Fina1方法 个体方法也可以被标记为 final。被标记为 final的方法不能被覆盖。这是由于安全原因。如果方法具有不能被改变 的实现,而且对于对象的一致状态是关键的,那么就要使方法成为fina 被声明为fina1的方法有时被用于优化。编译器能产生直接对方法调用的代码,而不是通常的涉及运行时查找的虚 拟方法调用 被标记为 static或 private的方法被自动地fina1,因为动态联编在上述两种情况下都不能应用。 6.7.3Fina1变量 如果变量被标记为 final,其结果是使它成为常数。想改变 final变量的值会导致一个编译错误。下面是一个正确定 义 final变量的例子 public final int MAX ARRAY SIZE =25; 注-如果将引用类型(即,任何类的类型)的变量标记为 fina l,那么该变量不能指向任何其它对象。但可能改变对象的 内容,因为只有引用本身是 fina l。 第八节抽象类 抽象类 声明方法的存在而不去实现它的类被叫做抽象类 可以通过关键字 abstract进行标记将类声明为抽象 public abstract void drawDot (int x, int y) public void drawLine(int xl, int y1 x2, int y2)[ // draw using the drawDot()method repeatedly 个 abstract类可以包含非抽象方法和变量 有时在库开发中,要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该行为。取而代之 在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法 例如,考虑一个 Drawing类。该类包含用于各种绘图设备的方法,但这些必须以独立平台的方法实现。它不可能去 访问机器的录像硬件而且还必须是独立于平台的。其意图是绘图类定义哪种方法应该存在,但实际上,由特殊的从属于 平台子类去实现这个行为 正如 Drawing类这样的类,它声明方法的存在而不是实现,以及带有对已知行为的方法的实现,这样的类通常被称 做抽象类。通过用关键字 abstract进行标记声明一个抽象类。被声明但没有实现的方法(即,这些没有程序体或仆}), 81
第六章 高级语言特征 81 一个静态变量。颜色根据对象的不同而不同,其行为也根据对象的不同而不同,在它所作用的非静态数据的基础上对不 同对象返回不同的颜色。 图 6-1 Myclass 例子 第七节 关键字 final 6.7.1 Final 类 关键字 final Final 类不能被分成子类 Final 方法不能被覆盖 Final 变量是常数 Java 编程语言允许关键字 Final 被应用到类中。如果这样做了,类便不能被子分成子类。比如,类 Java.lang.String 就是一个 final 类。这样做是出于安全原因,因为它保证,如果方法有字符串的引用,它肯定就是类 String 的字符串, 而不是某个其它类的字符串,这个类是 String 的被修改过的子类,因为 String 可能被恶意窜改过。 6.7.2 Final 方法 个体方法也可以被标记为 final。被标记为 final 的方法不能被覆盖。这是由于安全原因。如果方法具有不能被改变 的实现,而且对于对象的一致状态是关键的,那么就要使方法成为 final。 被声明为 final 的方法有时被用于优化。编译器能产生直接对方法调用的代码,而不是通常的涉及运行时查找的虚 拟方法调用。 被标记为 static 或 private 的方法被自动地 final,因为动态联编在上述两种情况下都不能应用。 6.7.3 Final 变量 如果变量被标记为 final,其结果是使它成为常数。想改变 final 变量的值会导致一个编译错误。下面是一个正确定 义 final 变量的例子: public final int MAX_ARRAY_SIZE = 25; 注-如果将引用类型(即,任何类的类型)的变量标记为 final,那么该变量不能指向任何其它对象。但可能改变对象的 内容,因为只有引用本身是 final。 第八节 抽象类 抽象类 声明方法的存在而不去实现它的类被叫做抽象类 可以通过关键字 abstract 进行标记将类声明为抽象 public abstract class Drawing { public abstract void drawDot(int x, int y); public void drawLine(int x1, int y1, int x2, int y2) { // draw using the drawDot() method repeatedly. } } 一个 abstract 类可以包含非抽象方法和变量 有时在库开发中,要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该行为。取而代之, 在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 例如,考虑一个 Drawing 类。该类包含用于各种绘图设备的方法,但这些必须以独立平台的方法实现。它不可能去 访问机器的录像硬件而且还必须是独立于平台的。其意图是绘图类定义哪种方法应该存在,但实际上,由特殊的从属于 平台子类去实现这个行为。 正如 Drawing 类这样的类,它声明方法的存在而不是实现,以及带有对已知行为的方法的实现,这样的类通常被称 做抽象类。通过用关键字 abstract 进行标记声明一个抽象类。被声明但没有实现的方法(即,这些没有程序体或{})
第六章高级语言特征 也必须标记为抽象 public abstract class Drawing public abstract void drawDot (int x, int y)i public void drawLine(int xl, int yl int x // draw using the drawDot() method repeatedly 不能创建 abstract类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不 能有抽象构造函数或抽象静态方法。 Abstract类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类 public class MachineDr awing extends Drawing public void drawDot (int mach x, intmach y) / Draw the dot Drawing d= new MachineDrawing( 第九节接口 接口是抽象类的变体 在接口中,所有方法都是抽象的。 多继承性可通过实现这样的接口而获得。 句法是 public interface Transparency t ublic static final int OPAQUE=I ublic static final int BITMAs public static final int TRANSLUCENT=3 public int getTransparency(: 接口是抽象类的变体。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义 static final成员变量。 接口的好处是,它给出了屈从于Java技术单继承规则的假象。当类定义只能扩展出单个类时,它能实现所需的多个 接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即,将程序体 给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许 使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换, instanceof运 算符可以用来决定某对象的类是否实现了接口 接口是用关键字 interface来定义的,如下所述 public static final int OPAQUE=1 public static final int BITMASK=2 public static final int TRANSLUCENT=3;
第六章 高级语言特征 82 也必须标记为抽象。 public abstract class Drawing { public abstract void drawDot(int x, int y); public void drawLine(int x1, int y1, int x2, int y2) { // draw using the drawDot() method repeatedly. } } 不能创建 abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不 能有抽象构造函数或抽象静态方法。 Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类。 public class MachineDrawing extends Drawing { public void drawDot (int mach x, intmach y) { // Draw the dot } } Drawing d = new MachineDrawing(); 第九节 接 口 接 口 接口是抽象类的变体。 在接口中,所有方法都是抽象的。 多继承性可通过实现这样的接口而获得。 句法是: public interface Transparency { public static final int OPAQUE=1; public static final int BITMASK=2; public static final int TRANSLUCENT=3; public int getTransparency(); } 接口是抽象类的变体。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义 static final 成员变量。 接口的好处是,它给出了屈从于 Java 技术单继承规则的假象。当类定义只能扩展出单个类时,它能实现所需的多个 接口。 接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即,将程序体 给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许 使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运 算符可以用来决定某对象的类是否实现了接口。 接口是用关键字 interface 来定义的,如下所述: public interface Transparency { public static final int OPAQUE=1; public static final int BITMASK=2; public static final int TRANSLUCENT=3;
第六章高级语言特征 public int getTransparency ( 类能实现许多接口。由类实现的接口出现在类声明的末尾以逗号分隔的列表中,如下所示: public class MyApplet extends Applet implements 下例表示一个简单的接口和实现它的一个类: interface SayHello t void printMe ssage ( class sayHelloImpl imp lements sayHello t System. out. println("Hello")i nterface SayHello强制规定,实现它的所有的类必须有一个称做 printMessage的方法,该方法带有一个void返 回类型且没有输入参数。 对于下述情况,界面是有用的 声明方法,期望一个或更多的类来实现该方法 决定一个对象的编程界面,而不揭示类的实际程序体 捕获无关类之间的相似性,而不强迫类关系 描述“似函数”对象,它可以作为参数被传递到在其它对象上调用的方法中 对于下述情况,接口是有用的 声明方法,期望一个或更多的类来实现该方法 揭示一个对象的编程接口,而不揭示类的实际程序体。(当将类的一个包输送到其它开发程序中时它是非常有用的。) 捕获无关类之间的相似性,而不强迫类关系。 描述“似函数”对象,它可以作为参数被传递到在其它对象上调用的方法中。它们是“函数指针”(用在C和C++中) 用法的一个安全的替代用法。 第十节高级访问控制 高级访问控制 修饰符同类 同包子类 通用性 公共 是 是 受保护 缺省 是是是 是 变量和方法可以处于四个访问级别的一个中;公共,受保护,缺省或私有。类可以在公共或缺省级别 变量、方法或类有缺省访问性,如果它没有显式受保护修饰符作为它的声明的一部分的话。这种访问性意味着,访 问可以来自任何方法,当然这些方法只能在作为目标的同一个包中的成员类当中
第六章 高级语言特征 83 public int getTransparency(); } 类能实现许多接口。由类实现的接口出现在类声明的末尾以逗号分隔的列表中,如下所示: public class MyApplet extends Applet implements Runnable, MouseListener{ "..." } 下例表示一个简单的接口和实现它的一个类: interface SayHello { void printMessage(); } class SayHelloImpl implements SayHello { void printMessage() { System.out.println("Hello"); } } interface SayHello 强制规定,实现它的所有的类必须有一个称做 printMessage 的方法,该方法带有一个 void 返 回类型且没有输入参数。 接 口 对于下述情况,界面是有用的: 声明方法,期望一个或更多的类来实现该方法 决定一个对象的编程界面,而不揭示类的实际程序体 捕获无关类之间的相似性,而不强迫类关系 描述“似函数”对象,它可以作为参数被传递到在其它对象上调用的方法中 对于下述情况,接口是有用的: 声明方法,期望一个或更多的类来实现该方法。 揭示一个对象的编程接口,而不揭示类的实际程序体。(当将类的一个包输送到其它开发程序中时它是非常有用的。) 捕获无关类之间的相似性,而不强迫类关系。 描述“似函数”对象,它可以作为参数被传递到在其它对象上调用的方法中。它们是“函数指针”(用在 C 和 C++中) 用法的一个安全的替代用法。 第十节 高级访问控制 高级访问控制 修饰符 同类 同包 子类 通用性 公共 是 是 是 是 受保护 是 是 是 缺省 是 是 私有 是 变量和方法可以处于四个访问级别的一个中;公共,受保护,缺省或私有。类可以在公共或缺省级别。 变量、方法或类有缺省访问性,如果它没有显式受保护修饰符作为它的声明的一部分的话。这种访问性意味着,访 问可以来自任何方法,当然这些方法只能在作为目标的同一个包中的成员类当中
第六章高级语言特征 以修饰符 protected标记的变量或方法实际上比以缺省访问控制标记的更易访问。一个 protected方法或变量可以 从类当中的任何方法进行访问,这个类可以是同一个包中的成员,也可以是从任何子类中的任何方法进行访问。当它适 合于一个类的子类但不是不相关的类时,就可以使用这种受保护访问来访问成员 表6-1总结访问性标准 表6-1访问性标准 修饰符 公共 受保护 是是是 缺省 是是是是 私有 受保护访问甚至被提供给子类,该子类驻留在与拥有受保护特征的类的不同包中 第十一节降级 降级就是过时的构造函数和方法调用。 过时的方法和构造函数由具有更标准化的命名规则的方法所取代 当升迁代码时,用- deprecation标志来编译代码: 在JDK1.1中,对方法名称的标准化做了重大努力。因此,在JDK1.2中,大量的类构造函数和方法调用过时。它们 根据更标准化的命名规则规定的方法名称所取代,总的说来,使程序员的生活简单化 例如,在JDK1.1版本中的Java.awt. Component类: 改变或获得组件大小的方法是 resize o和 size o 改变或获得组件矩形框的方法是 reshape o和 bounds 在JDK1.0版本中的Java.awt. Component,这些方法被降级并被以set和get开头表示该方法的初级运算的方法所代 替 setsize0和 getSizeo setBounds o getBounds o 无论什么时候将代码从JDK1.0升迁到JDK1.1或更高版本中,或者即使使用以前用在JDK1.0中的代码,对用 deprecation标志来编译代码都是 主意。 c:\ javac -deprecation MyFile. java deprecation标志将报告在降级过的类中使用的任何方法。例如,看一个叫做 DateConverter的实用类,它将 n/dd/yy格式的日期转换成星期几 1. package myutilities; 4. public final class Dat cOnverter i private static String day of the week []=t"Sunday",Monday ,"Tue sday" ,"Wednesday", Thurso "Friday","Saturday " 8. public static string getDay ofweek (String theDate)(
第六章 高级语言特征 84 以修饰符 protected 标记的变量或方法实际上比以缺省访问控制标记的更易访问。一个 protected 方法或变量可以 从类当中的任何方法进行访问,这个类可以是同一个包中的成员,也可以是从任何子类中的任何方法进行访问。当它适 合于一个类的子类但不是不相关的类时,就可以使用这种受保护访问来访问成员。 表 6-1 总结访问性标准 表 6-1 访问性标准 修饰符 同类 同包 子类 通用性 公共 是 是 是 是 受保护 是 是 是 缺省 是 是 私有 是 受保护访问甚至被提供给子类,该子类驻留在与拥有受保护特征的类的不同包中。 第十一节 降级 降 级 降级就是过时的构造函数和方法调用。 过时的方法和构造函数由具有更标准化的命名规则的方法所取代。 当升迁代码时,用-deprecation 标志来编译代码: javac -deprecation MyFile.java 在 JDK1.1 中,对方法名称的标准化做了重大努力。因此,在 JDK1.2 中,大量的类构造函数和方法调用过时。它们 由根据更标准化的命名规则规定的方法名称所取代,总的说来,使程序员的生活简单化。 例如,在 JDK1.1 版本中的 Java.awt.Component 类: 改变或获得组件大小的方法是 resize()和 size()。 改变或获得组件矩形框的方法是 reshape()和 bounds()。 在 JDK1.0 版本中的 Java.awt.Component,这些方法被降级并被以 set 和 get 开头表示该方法的初级运算的方法所代 替。 setSize()和 getSize() setBounds()getBounds() 无论什么时候将代码从 JDK1.0 升迁到 JDK1.1 或更高版本中,或者即使使用以前用在 JDK1.0 中的代码,对用 -deprecation 标志来编译代码都是一个好主意。 c:\ javac -deprecation MyFile.java -deprecation 标志将报告在降级过的类中使用的任何方法。例如,看一个叫做 DateConverter 的实用类,它将 mm/dd/yy 格式的日期转换成星期几: 1. package myutilities; 2. import java.util.*; 3. import java.text.*; 4. public final class DateConverter { 5. 6. private static String day_of_the_week [] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 7. 8. public static String getDayOfWeek (String theDate){ 9. int month, day, year;
第六章高级语言特征 11. StringTokenizer st= new StringTo kenizer (theDate,"/")i 13. month Integer parseInt(st. nextToken () Integer parseInt(st. nextToken ()) 15. year Integer parseInt(st next Token()) 16. Date d= new Date (year, month, day 18. return (day of the week [d. getDay ()]) 20.} 当这个代码用- deprecation标志在JD1.2中被编译时,会得到 DateConverter. java: 16: Note: The constructor java util. Date(int, int, int) has been depreca ted Date d new Date (year, month, day)i DateConverter. java: 18: Note: The method int getDay () in class java. ut il Date has been deprecated return (day of the week [d. getDay()1) Note: Date Converter. java uses a deprecated APl. Please consult the documentation for a better alternative. 3 warnings 重写的 DateConverter类看起来象这样 工 t Java.uti1 t Java. text 4. public final class DateConverter 6. private static String day of The Week [ I"Sunday ,"Monday","Tuesday ,"Wednesday","Thurs day ",Friday , "Saturday " ) public static String getDayOfweek (String theDate)t 9 Date d 10 SimpleDateFormat sdf ew simpleDateFormat ("MM/dd/yy")i d sdf parse (theDate y catch (ParseException e)i 15 System. out. println (e)i eprint stack Trace() // Create a Gregoriancalendar object
第六章 高级语言特征 85 10. 11. StringTokenizer st = 12. new StringTokenizer (theDate, "/"); 13. month = Integer.parseInt(st.nextToken ()); 14. day = Integer.parseInt(st.nextToken()); 15. year = Integer.parseInt(st.nextToken()); 16. Date d = new Date (year, month, day); 17. 18. return (day_of_the_week[d.getDay()]); 19. } 20. } 当这个代码用-deprecation 标志在 JDK1.2 中被编译时,会得到: c:\ javac -deprecation DateConverter.java DateConverter.java:16: Note: The constructor java.util.Date(int,int,int) has been deprecated. Date d = new Date (year, month, day); ^ DateConverter.java:18: Note: The method int getDay() in class java.util.Date has been deprecated. return (day_of_the_week[d.getDay()]); ^ Note: DateConverter.java uses a deprecated API.Please consult the documentation for a better alternative. 3 warnings 重写的 DateConverter 类看起来象这样: 1. package myutilities; 2. import java.util.*; 3. import java.text.*; 4. public final class DateConverter { 5. 6. private static String day_Of_The_Week [] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 7. 8. public static String getDayOfWeek (String theDate){ 9. Date d = null; 10. SimpleDateFormat sdf = 11. new SimpleDateFormat ("MM/dd/yy"); 12. try { 13. d = sdf.parse (theDate); 14. } catch (ParseException e) { 15. System.out.println (e); 16. e.printStackTrace(); 17. } 18. // Create a GregorianCalendar object 19. Calendar c =