第六章高级语言特征 第六章高级语言特征 本模块讨论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. 非静态数据只限于实例,只能通过该实例的非静态方法对它进行访问。非静态数据定义对象之间互不相同 的特点,非静态方法在它们所作用的非静态数据的基础上对每个对象的行为互不相同。 考虑一下模仿汽车的特殊类型的一个对象的实例。轮子的大小,对该类型的所有汽车来说是个常量,可能被模仿成