返回列表 发帖

SUN JAVA标准教程

关于本课程
本书的主要目标是为你提供有关Java应用和Java applets的面向对象的程序设计所必需的知识和技能;并讲授Java编程语言句法和面向对象的概念,以及Java运行环境的许多特性, 对图形用户界面(GUIs)、多线程和网络的支持等。本课程包括了参加SUN Certified Java Programmer和SUN Certified Java Developer考试所必备的知识。
一、课程概述
   
课程概述
本课程主要包括以下内容:
-Java编程语言句法
-应用于Java编程语言的面向对象的概念
-图形用户界面(GUI)编程
-创建Applet
-多线程
-网络
本课程首先讨论了Java运行环境和Java编程语言句法,然后阐述了应用于Java编程语言的面向对象的概念;随着课程的进展还将讨论有关Java平台的更先进的特性。
本课程授课对象应具备运用Java 编程语言或其它语言进行基本语言设计的能力,它是“非程序员Java编程”(“Java Programming for Non—Programmers”,SL-110)课程的延续。
    尽管Java编程语言独立于操作系统,但它所产生的图形用户界面(GUI)却可能依赖于执行其代码的操作系统。本课程中的例题所使用的代码运行于Solaris TM操作系统,因而本手册中的图形具备Motif GUI。如果将这些代码运行于Windows 95操作系统,则可产生Microsoft Windows 95 GUI。本课程的内容适用于所有Java操作系统端口。
二、课程图
每一模块的课程都从一张课程图开始,使学员可掌握自己的学习进度。全课程设置流程图如下所示:

SUN JAVA标准教程

晕~你给我发本书  出来了?

TOP

SUN JAVA标准教程

呵呵 有没有后续啦??老深~~

TOP

SUN JAVA标准教程

) {
9.        ExGui guiWindow = new ExGui();
10.        guiWindow.go();
11.      }
12.
13.      public void go() {
14.        f = new Frame("GUI example");
15.        f.setLayout(new FlowLayout());
16.        b1 = new Button("Press Me");
17.        b2 = new Button("Don't Press Me");
18.        f.add(b1);
19.        f.add(b2);
20.        f.pack();
21.        f.setVisible(true);
22.      }
23.}
    main()方法
    本例中第8行main()方法有两个作用。首先,它创建了ExGui对象的一个实例。回想一下,直到一个实例存在,还没有被称做f,b1和b2的真实数据项可以使用。第二,当数据空间被创建时,main()在该实例的上下文中调用实例方法go()。在go()中,真正的运行才开始。
    new Frame (“GUI Example”)
    这个方法创建Java.awt.Frame类的一个实例。根据本地协议,在Java编程语言中,Frame是顶级窗口,带有标题条—在这种情况下,标题条由构造程序参数“GUI Example”定义—缩放柄,以及其它修饰。
    f.setLayout (new FlowLayout())
    这个方法创建Flow布局管理器的一个实例,并将它安装在框架中。对于每个Frame、Border布局来说,都有一个布局管理器,但本例中没有使用。Flow布局管理器在AWT中是最简单的,它在某种程度上象一个页面中的单词被安排成一行一行的那样来定位组件。请注意,Flow布局缺省地将每一行居中。
    new Button(“Press Me”)
    这个方法创建Java.awt.Button类的一个实例。按钮是从本地窗口工具包中取出的一个标准按钮。按钮标签是由构造程序的字符串参数定义的。
    f.add(b1)
    这个方法告诉框架f(它是一个容器),它将包容组件b1。b1的大小和位置受从这一点向前的Frame布局管理器的控制。
    f.pack()
    这个方法告诉框架来设定大小,能恰好密封它所包含的组件。为了确定框架要用多大,f.pack()询问布局管理器,在框架中哪个负责所有组件的大小和位置。
    f.setVisible(true)
    这个方法使框架以及其所有的内容变成用户看得见的东西。
    第190页代码的最终结果是:

8.9.1  Flow布局管理器
    第190页例子中所用的Flow布局对组件逐行地定位。每完成一行,一个新行便又开始。
    与其它布局管理器不一样,Flow布局管理器不限制它所管理的组件的大小,而是允许它们有自己的最佳大小。
    如果想将组件设定缺省居中的话,Flow布局构造程序参数允许将组件左对齐或右对齐。
    如果想在组件之间创建一个更大的最小间隔,可以规定一个界限。
    当用户对由Flow布局管理的区域进行缩放时,布局就发生变化。如:

TOP

SUN JAVA标准教程

) {
10.        FrameWithPanel fr =
11.        new FrameWithPanel ("Frame with Panel");
12.        Panel pan = new Panel();
13.        
14.        fr.setSize(200,200);
15.        fr.setBackground(Color.blue);
16.        fr.setLayout(null); //override default layout mgr
17.        pan.setSize (100,100);
18.        pan.setBackground(Color.yellow);
19.
20.        fr.add(pan);
21.        fr.setVisible(true);
22.     }
23.    ....
24.

TOP

SUN JAVA标准教程

) {
6.MyFrame fr = new MyFrame("Hello Out There!");
7.fr.setSize(500,500);
4.fr.setBackground(Color.blue);
5.        fr.setVisible(true);
6.     }
7.    public MyFrame (String str) {
8.         super(str);
9.    }
10.}
    上述程序创建了下述框架,它有一个具体的标题、大小及背景颜色。

TOP

SUN JAVA标准教程

第八章  建立GUIs
  本模块讲述图形用户界面的建立及布局。它介绍了抽象视窗工具包,一种建立GUIs的类包。
第一节  相关问题
  讨论—下述问题与本模块中出现的材料相关。
-Java编程语言是一个具有独立平台的编程语言。GUI环境通常是从属平台。那么,为了使GUI平台独立,Java技术是如何接近这个主题的呢?
第二节  目 的
    完成本模块学习时,将能:
-描述AWT包及其组件
-定义Container、Component及Layout Manager等术语,以及它们是如何在一起来建立GUI的
-使用Layout Manager
-使用Flow、Border、Gird及Card布局管理器来获得期望的动态布局
-增加组件到Container
-正确运用Frame及Panel容器
-描述如何使用嵌套容器来完成复杂的布局
-在Java软件程序中,确认如下内容:
-容器
-相关布局管理器
-所有组件的布局层次
第三节  AWT
AWT
-提供基本的GUI组件,用在所有的Java applets及应用程序中
-具有可以扩展的超类,它们的属性是继承的,类也可被抽象化
-确保显示在屏幕上的每个GUI组件都是抽象类组件的子类
-Contaner,它是一个Component的抽象子类,而且包括两个子类
-Panel
-window
    AWT提供用于所有Java applets及应用程序中的基本GUI组件,还为应用程序提供与机器的界面。这将保证一台计算机上出现的东西与另一台上的相一致。
    在学AWT之前,简单回顾一下对象层次。记住,超类是可以扩展的,它们的属性是可继承的。而且,类可以被抽象化,这就是说,它们是可被分成子类的模板,子类用于类的具体实现。
    显示在屏幕上的每个GUI组件都是抽象类组件的子类。也就是说,每个从组件类扩展来的图形对象都与允许它们运行的大量方法和实例变量共享。
    Container是Component的一个抽象子类,它允许其它的组件被嵌套在里面。这些组件也可以是允许其它组件被嵌套在里面的容器,于是就创建了一个完整的层次结构。在屏幕上布置GUI组件,容器是很有用的。Panel是Container的最简单的类。Container的另一个子类是Window。
第四节  Java.awt包
    Java.awt包包含生成WIDGETS和GUI组件的类。该包的基本情况如下图所示。黑体字的类表明该模块的要点。

TOP

SUN JAVA标准教程

第五节  异常分类
    在Java编程语言中,异常有三种分类。Java.lang.Throwable类充当所有对象的父类,可以使用异常处理机制将这些对象抛出并捕获。在Throwable类中定义方法来检索与异常相关的错误信息,并打印显示异常发生的栈跟踪信息。它有Error和Exception两个基本子类,如下图所示:
    Throwable类不能使用,而使用子类异常中的一个来描述任何特殊异常。每个异常的目的描述如下:
-Error表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
-RuntimeException表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。比如,如果数组索引扩展不超出数组界限,那么,ArrayIndexOutOfBoundsException异常从不会抛出。比如,这也适用于取消引用一个空值对象变量。因为一个正确设计和实现的程序从不出现这种异常,通常对它不做处理。这会导致一个运行时信息,应确保能采取措施更正问题,而不是将它藏到谁也不注意的地方。
-其它异常表示一种运行时的困难,它通常由环境效果引起,可以进行处理。例子包括文件未找到或无效URL异常(用户打了一个错误的URL),如果用户误打了什么东西,两者都容易出现。这两者都可能因为用户错误而出现,这就鼓励程序员去处理它们。
第六节  共同异常
共同异常
-ArithmeticException
-NullPointerException
-NegativeArraySizeException
-ArrayIndexoutofBoundsException
-SecurityException
    Java编程语言提供几种预定义的异常。下面是可能遇到的更具共同性的异常中的几种:
-ArithmeticException—整数被0除,运算得出的结果。
-int I =12 / 0;
-NullPointerException—当对象没被实例化时,访问对象的属性或方法的尝试:
-Date d= null;
-System.out.println(d.toString());
-NegativeArraySizeException—创建带负维数大小的数组的尝试。
-ArrayIndexoutofBoundsException—访问超过数组大小范围的一个元素的尝试。
-SecurityException—典型地被抛出到浏览器中,SecurityManager类将抛出applets的一个异常,该异常企图做下述工作(除非明显地得到允许):
-访问一个本地文件
-打开主机的一个socket,这个主机与服务于applet的主机不是同一个。
-在运行时环境中执行另一个程序
第七节  处理或声明规则
处理或声明规则
-用try-catch-finally块来处理异常
-使用throws子句声明代码能引起一个异常
     为了写出健壮的代码,Java编程语言要求,当一个方法在栈(即,它已经被调用)上发生Exception(它与Error或RuntimeException不同)时,那么,该方法必须决定如果出现问题该采取什么措施。
    程序员可以做满足该要求的两件事:
    第一,通过将Try{}catch(){}块纳入其代码中,在这里捕获给被命名为属于某个超类的异常,并调用方法处理它。即使catch块是空的,这也算是处理情况。
    第二,让被调用的方法表示它将不处理异常,而且该异常将被抛回到它所遇到的调用方法中。它是按如下所示通过用throws子句标记的该调用方法的声明来实现的:
     public void troublesome() throws IOException
    关键字throws之后是所有异常的列表,方法可以抛回到它的调用程序中。尽管这里只显示了一个异常,如果有成倍的可能的异常可以通过该方法被抛出,那么,可以使用逗号分开的列表。
    是选择处理还是选择声明一个异常取决于是否给你自己或你的调用程序一个更合适的候选的办法来处理异常。
注—由于异常类象其它类一样被组编到层次中,而且由于无论何时想要使用超类都必须使用子类, 因此,可以捕获异常“组”并以相同的捕获代码来处理它们。例如,尽管IOExceptions(EOFException,FileNotFoundException等等)有几种不同的类型,通过俘获IOException,也可以捕获IOException任何子类的实例。
第八节  创建自己的异常
7.8.1  介绍
    用户定义异常是通过扩展Exception类来创建的。这种异常类可以包含一个“普通”类所包含的任何东西。下面就是一个用户定义异常类例子,它包含一个构造函数、几个变量以及方法:
1.public class ServerTimedOutException extends Exception {
2.    private String reason;
3.    private int port;
4.    public ServerTimedOutException (String reason,int port){
5.      this.reason = reason;
6.      this.port = port;
7.    }
8.    public String getReason() {
9.    return reason;
10.    }
11.    public int getPort() {
12.      return port;
13.    }
14. }
    使用语句来抛出已经创建的异常:
throw new ServerTimedOutException
("Could not connect", 80);
7.8.2  实例
    考虑一个客户服务器程序。在客户代码中,要与服务器连接,并希望服务器在5秒钟内响应。如果服务器没有响应,那么,代码就如下所述抛出一个异常(如一个用户定义的ServerTimedOutException)。
1.  public void connectMe(String serverName) throws
     ServerTimedOutException {
2.int success;
3.int portToConnect = 80;
4.success = open(serverName, portToConnect);
5.if (success == -1) {
6.throw new ServerTimedOutException(
7."Could not connect", 80);
8.}
9.}
    要捕获异常,使用try语句:
1.public void findServer() {
2.. . .
3.try {
4.connectMe(defaultServer);
5.} catch(ServerTimedOutException e) {
6.System.out.println("Server timed out, trying alternate");
7.try {
8.connectMe(alternateServer);
9.} catch (ServerTimedOutException e1) {
10.System.out.println("No server currently available");
11.}
12.}
13... .
注—try和catch块可以如前例所述那样被嵌套。
也可能部分地处理一个异常然后也将它抛出。如:
try {
.....
.....
} catch (ServerTimedOutException e) {
  System.out.println("Error caught ");
  throw e;
}
练习:处理并创建异常
    练习目的—通过编写可以创建并处理异常的Java软件程序,可以获得异常机制的经验。
一、准备
    为了成功地完成该实验,必须理解处理运行时错误的异常的概念。
二、任务
    一级实验:处理一个异常
    1. 使用第169页上的样板异常程序在数组索引超出数组大小时创建一个异常。(或修改自己的程序以便创建一个异常。)
    2. 使用try和catch语句从异常进行恢复。
    二级实验:创建自己的异常
使用模块5中创建的bank包并附加下述异常:
AccountOverdrawnException—当有了这个要取出比帐户上更多的钱的尝试时。
InvalidDepositException—当无效钱数(小于0)存入时。
三、练习总结
    讨论—花几分钟时间讨论实验练习中所取得的经验、问题或发现。
经验  解释 总结 应用
四、检查进步情况
    在继续下一个模块前,检查一下,确信能够:
-定义异常
-使用try,catch和finally语句
-描述异常分类
-确认共同异常
-开发程序来处理自己的异常
五、思考
Java应用环境有什么特征,使它支持用户界面的开发?

TOP

SUN JAVA标准教程

);
11.    } catch (ArrayIndexOutOfBoundsException e){
12.    System.out.println( "Re-setting Index Value");
13.    i = -1;
14.    } finally {
15.    System.out.println("This is always printed");
16.    }
17.    i++;
18.    } // end while()
19.    } // end main()
    当循环被执行时,下述在屏幕上出现的信息将改变。
1.Hello world!
2.This is always printed
3.No, I mean it!
4.This is always printed
5.HELLO WORLD!!
6.This is always printed
7.Re-setting Index Value
8.This is always printed

TOP

SUN JAVA标准教程

第十八节  反射API
反射API
    可以用作
      构造新类实例和新数组
      访问并修改对象和类的字段
      调用对象和类中的方法
      访问并修改数组的元素
    Java反射API提供一套类,可以用它们来决定一个类文件的变量和方法。因为被共同用于动态发现和执行代码的目的,因此API可以被用于:
  构造新类实例和新数组
  访问并修改对象和类的字段
  调用对象和类中的方法
  访问并修改数组的元素
    只要安全策略允许,这些操作是可能的。在需要运行时检索并处理信息的情况下,反射API是有用的。例如,如果正在编写一个Java软件解释程序或调试程序,可以使用它。
第十九节  反射API特征
反射API特征
Java.lang.Class
    Java.lang.reflect.Field
    Java.lang.reflect.Method
    Java.lang.reflect.Array
Java.lang.reflect.Constructor
    定义类和方法的核心反射API的主要特征如下:
      Java.lang.Class类提供方法,该方法可获得有关类及其字段、构造函数以及方法的信息。
      Java.lang.reflect.Field提供方法,该方法设定/获得有关类中的字段的信息。
      Java.lang.reflect.Method提供方法,该方法访问并调用类中的方法,并获得它们的签名。
      Java.lang.reflect.Array能使数组对象自省。
      Java.lang.reflect.Constructor提供反射访问到构造函数。
第二十节  反射API安全模型
反射API安全模型
Java安全管理器一个类接一个类地控制对核心API的访问。
    当下述情况发生时,标准的Java编程语言访问控制得到加强:
  Field被用来获得或设定一个字段值
  Method被用来调用一个方法
      Constructor被用来创建并初始化一个新的类的实例
    Java安全管理器一个类接一个类地控制对核心API的访问。当下述情况发生时,标准的Java编程语言访问控制得到加强:
  Field被用来获得或设定一个字段值
  Method被用来调用一个方法
      Constructor被用来创建并初始化一个新的类的实例
练习:用高级语言特征工作
    练习目的—使用银行帐户模型和采用高级面向对象特征,如:内部类,矢量类和接口等,重写、编译并运行三个程序。
一、准备
    为了成功地完成该实验,必须熟悉本模块及前面模块中所讲的面向对象概念。
二、任务
    一级实验:修改银行帐户问题
1.定义只包含两个方法deposit和withdraw的接口Personal。
2.从模块5中,运用Personal接口来定义一套不同的帐户类型,重新定义类Account.Java。它必须能处理个人帐户,进一步分成支票和存款两个帐户。
3.设计并开发提供保护的方法。例如,如果一个客户有一个存款和支票帐户,须确保支票帐户受存款帐户保护。
    二级实验:使用内部类
1.创建一个叫做BasicArray的类,声明并初始化一个叫做thisArray的数组,它包含四个整数。
2.创建一个名为Factorial的类,它包含一个计算它的参数的阶乘的方法。
3.从BasicArray的主要方法创建Factorial类的一个实例,然后调用其方法来计算四个整数中每一个的阶乘。
4.编译并测试该程序。
5.将Factorial类中的所有东西都移到BasicArray类中。Factorial现在就是BasicArray的一个内部类。
6.编译并测试该程序。
    三级实验:将find和delete方法附加到MyVector类中
1.将Find方法附加到MyVector类中,它将返回被作为参数传递的元素的位置。
如果未发现该参数,让方法返回-1。
例如:
$ java MyVectorFind 3.14
3.14 is located at index 1
Number of vector elements is 4 and are:
5
3.14
Hi there!
abcd
$ java MyVectorFind c
args[0]=c, not found in vector
Number of vector elements is 4 and are:
5
3.14
Hi there!
abcd
2.将delete方法附加到MyVector类中,该类将所有与参数相配的元素移走。
方法必须返回true或false:如果删除成功,为true;否则为false(元素存在或不存在于矢量中)。
例如:
$ java MyVectorDelete 3.14
Elements 3.14 successfully deleted from vector.
Number of vector elements is 3 and are:
5
Hi there!
abcd
三、练习总结
    讨论—花几分钟来讨论实验练习中遇到的经验、问题或发现。
经验  解释   总结  应用
四、检查进步情况
    在继续学习下个模块前,检查一下你确实能:
  描述static变量、方法和初始化程序
  描述final类、方法和变量
  列出访问控制级别
  确认降级类并解释如何从JDK1.0升迁到JDK1.1、JDK1.2。
  在Java软件程序中,确认:
    static方法和变量
    public,private,protected和缺省变量
  使用abstract类和方法
  解释如何及何时使用内部类
  解释如何及何时使用接口
  描述= =和equals()之间的不同
五、思考
    Java编程语言具有什么特征,从而可以直接处理运行时错误情况?

TOP

SUN JAVA标准教程

= { 'a', 'b', 'c', 'd'};
44.  String s = new String ("Hi there!");
45.
46.  v.addInt(digit);
47.  v.addFloat(real);
48.  v.addString(s);
49.  v.addCharArray(letters);
50.
51.  v.printVector();
52. }
53.}
    这个程序产生下列输出:
$ java MyVector
Number of vector elements is 4 and are:
5
3.14
Hi there!
Abcd

TOP

SUN JAVA标准教程

第十二节==运算符与equals()方法
==运算符与equals()方法
    equals()和==方法决定引用值是否指向同一对象
    equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
    Java.lang包中的Object类有public boolean equals (Object obj)方法。它比较两个对象是否相等。仅当被比较的两个引用指向同一对象时,对象的equals()方法返回true。
    ==运算符也进行等值比较。也就是说,对于任何引用值X和Y,当且仅当X和Y指向同一对象时, X==Y返回真。
    当两个分离的对象的内容和类型相配的话,String,Date,File类和所有其它override equals()的包装类(Integer,Double,等等)将返回真。
    例如,String类中的equals()方法返回true,当且仅当参数不为null并且是一个String对象,该对象与调用该方法的String对象具有相同的字符顺序。
String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);
方法s1.equals(s2)返回真,尽管s1和s2指向两个不同的对象。
第十三节toString()方法
toString()方法
    被用来将一个对象转换成String
    被用来将一个基本类型转换成String
    toString方法被用来将一个对象转换成String表达式。当自动字符串转换发生时,它被用作编译程序的参照。System.out.println()调用下述代码:
      Date now = new Date()
        System.out.println(now)
    将被翻译成:
          System.out.println(now.toString());
    对象类定义缺省的toString()方法,它返回类名称和它的引用的地址(通常情况下不是很有用)。许多类覆盖toString()以提供更有用的信息。例如,所有的包装类覆盖toString()以提供它们所代表的值的字符串格式。甚至没有字符串格式的类为了调试目的常常实现toString()来返回对象状态信息。
第十四节  内部类
内部类
    被附加到JDK1.1
    允许一个类定义被放到另一个类定义里
    把类在逻辑上组织在一起
    可访问它们所嵌套的类的范围
    内部类,有时叫做嵌套类,被附加到JDK1.1及更高版本中。内部类允许一个类定义被放到另一个类定义里。内部类是一个有用的特征,因为它们允许将逻辑上同属性的类组合到一起,并在另一个类中控制一个类的可视性。
6.14.1  内部类基础
    下述例子表示使用内部类的共同方法:
1.import java.awt.*;
2.import java.awt.event.*;
3.public class MyFrame extends Frame{
4.    Button myButton;
5.    TextArea myTextArea;
6.    int count;;
7.
8.    public MyFrame(){
9.        super("Inner Class Frame");
10.     myButton = new Button("click me");
11.     myTextArea = new TextArea();
12.     add(myButton,BorderLayout,CENTER);
13.     add(myTextArea,BorderLayout,NORTH);
14.     ButtonListener bList = new ButtonListener();
15.     myButton.addActionListener(bList);
16. }
17. class ButtonListener implements ActionListener{
18.   public void actionPerformed(ActionEvent e){
19.   count ++
20.     myTextArea.setText("button clicked" + {
21.         count + "times");
22.   }
23. }// end of innerclass ButtonListener
24.
25. public static void main(String args[]){
26.   MyFrame f = new MyFrame();
27.   f.setSize(300,300);
28.   f.setVisible(true);
29. }
30.} // end of class MyFrame
    前面的例子包含一个类MyFrame,它包括一个内部类ButtonListener。编译器生成一个类文件,MyFrame$ButtonListener.class以及toMyFrame.class。它包含在MyFrame.class中,是在类的外部创建的。
6.14.2  如何做内部类工作?
    内部类可访问它们所嵌套的类的范围。所嵌套的类的成员的访问性是关键而且很有用。对嵌套类的范围的访问是可能的,因为内部类实际上有一个隐含的引用指向外部类上下文(如外部类“this”)。
1.public class MyFrame extends Frame{
2.    Button myButton;
3.    TextArea myTextarea;
4.    public MyFrame(){
5.      ......................
6.      ......................
7.      MyFrame$ButtonListener bList = new
8.               MyFrame$ButtonListener(this);
9.      myButton.addActionListener(bList);
10.   }
11.   class MyFrame$ButtonListener implements
12.   ActionListener{
13.   private MyFrame outerThis;
14.   Myframe$ButtonListener(MyFrame outerThisArg){
15.      outerThis = outerThisArg;
16.   }
17.   
18.   public void actionPerformed(ActionEvent e) {
19.   outerThis.MyTextArea.setText("buttonclicked");
20.   ......................
21.   ......................
22.   }
23.   public static void main(String args[]){
24.     MyFrame f = new MyFrame();
25.     f.setSize(300,300);
26.     f.setVisible(true);
27.   }
28.}
    有时可能要从static方法或在没有this的某些其它情况下,创建一个内部类的一个实例(例如,main)。可以如下这么做:
public static void main(String args[]){
    MyFrame f = new MyFrame();
    MyFrame.ButtonListener bList =
           f.new ButtonListener();
    f.setSize(50,50);
    f.setVisible(true);
}
6.14.3  内部类属性
内部类属性
    类名称只能用在定义过的范围中,除非用限定的名称。
    内部类的名称必须与所嵌套的类不同。
    内部类可以被定义在方法中。
    任何变量,不论是本地变量还是正式参数,如果变量被标记为final,那么,就可以被内部类中的方法访问。
    内部类有如下属性:
    类名称只能用在定义过的范围中,除非用在限定的名称中。内部类的名称必须与所嵌套的类不同。
    内部类可以被定义在方法中。这条规则较简单,它支配到所嵌套类方法的变量的访问。任何变量,不论是本地变量还是正式参数,如果变量被标记为final,那么,就可以被内部类中的方法访问。
内部类可以使用所嵌套类的类和实例变量以及所嵌套的块中的本地变量。
内部类可以被定义为abstract.
    属性
    只有内部类可以被声明为private或protected,以便防护它们不受来自外部类的访问。访问保护不阻止内部类使用其它类的任何成员,只要一个类嵌套另一个。
    一个内部类可以作为一个接口,由另一个内部类实现。
    被自动地声明为static的内部类成为顶层类。这些内部类失去了在本地范围和其它内部类中使用数据或变量的能力。
    内部类不能声明任何static成员;只有顶层类可以声明static成员。因此,一个需求static成员的内部类必须使用来自顶层类的成员。
注-内部类有常常被用作创建事件适配器的方便特征。事件适配器将在后面模块中讨论。
第十五节  包装类
包装类
用来将基本数据元素看作对象,包装类可以被用作:
                                    
            基本数据类型     包装类
              boolean             Boolean
                   byte                Byte
                   char                Char
                   short               Short
                   int                 Int
                   long                Long
                   float               Float
                   double              Double
    Java编程语言不把基本数据类型看作对象。例如,在基本格式本身当中,数字、布尔及字符型数据都被看作是为了提高效率。Java编程语言提供包装类来将基本数据元素看作对象。这样的数据元素被包裹在创建于它们周围的对象中,每个Java基本数据类型在Java.lang包中都有一个相应的wrapper class。每个包装类对象封装一个基本值。
              包装类列表如下:
              表6-2  包装类
                                    
            基本数据类型     包装类
              boolean        Boolean
              byte           Byte
              char           Char
              short          Short
              int            Int
              long           Long
              float          Float
              double         Double
    可以通过将被包裹的值传递到合适的构造函数中来构造包装类对象。例如:
int pInt = 500;
Integer wInt = new Integer(pInt);
第十六节  收集API
收集API
    收集(或容器)是代表一个对象组的单个对象,被认为是它的元素。
    收集类Vector,Bits,Stack,Hashtable,LinkedList等等都被支持。
    收集API包括将对象保持为下述情况的界面:
      收集-没有具体顺序的一组对象
      设定-没有复制的一组对象
      列表-有序对象组,允许复制
    收集(或容器)是代表一个对象组的单个对象,被认为是它的元素。收集典型地处理许多对象的类型,所有的类型都有一个特殊的种类(也就是说,它们都是从一个共同父类型延续来的)。Java编程语言支持收集类Vector,Bits, Stack,Hashtable ,LinkedList等等。例如,Stack实现后进先出(LIFO)的顺序,Hashtable提供一个相关的对象数组。
    收集保持处理Object类型的对象。这允许在收集中贮存任何对象。它还可以,在使用对象前、从收集中检索到它之后,使用正确的类型转换。
    收集API典型地由将对象保持为下述情况的接口而组成:
      收集-没有具体顺序的一组对象
      设定-没有复制的一组对象
      列表-有序对象组,允许复制
    API还包括诸如HashSet, ArraySet, ArrayList, LinkedList和Vector等等的类,它们实现这些接口。API还提供了支持某些算法的方法,如:排序,二进制搜索,评估列表中的最小和最大,以及收集等。

TOP

SUN JAVA标准教程

第十节  高级访问控制
高级访问控制
  修饰符      同类       同包      子类      通用性
  公共        是         是        是          是
  受保护      是         是        是
  缺省        是         是
  私有        是                                   
    变量和方法可以处于四个访问级别的一个中;公共,受保护,缺省或私有。类可以在公共或缺省级别。
    变量、方法或类有缺省访问性,如果它没有显式受保护修饰符作为它的声明的一部分的话。这种访问性意味着,访问可以来自任何方法,当然这些方法只能在作为目标的同一个包中的成员类当中。
    以修饰符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;
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 =
20. new GregorianCalendar (TimeZone.getTimeZone ("EST"),         Locale.US);
21.c.setTime (d);
22.return(day_Of_The_Week
               [(c.get(Calendar.DAY_OF_WEEK)-1)]);
23.  }
24.}
     
在这里,1.2版本使用两个新类:SimpleDateFormat,用来采用任何String日期格式并创建一个Date对象的类;以及GregorianCalendar类,用来创建一个带有当地时区和场所的日历。

TOP

SUN JAVA标准教程

第七节  关键字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);
           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
       Runnable, MouseListener{
         "..."
       }
   下例表示一个简单的接口和实现它的一个类:
    interface SayHello {
        void printMessage();
    }
    class SayHelloImpl implements SayHello {
        void printMessage() {
            System.out.println("Hello");
        }
    }
    interface SayHello强制规定,实现它的所有的类必须有一个称做printMessage的方法,该方法带有一个void返回类型且没有输入参数。
接  口
    对于下述情况,界面是有用的:
    声明方法,期望一个或更多的类来实现该方法
    决定一个对象的编程界面,而不揭示类的实际程序体
    捕获无关类之间的相似性,而不强迫类关系
    描述“似函数”对象,它可以作为参数被传递到在其它对象上调用的方法中
    对于下述情况,接口是有用的:
    声明方法,期望一个或更多的类来实现该方法。
    揭示一个对象的编程接口,而不揭示类的实际程序体。(当将类的一个包输送到其它开发程序中时它是非常有用的。)
    捕获无关类之间的相似性,而不强迫类关系。
    描述“似函数”对象,它可以作为参数被传递到在其它对象上调用的方法中。它们是“函数指针”(用在C和C++中)用法的一个安全的替代用法。

TOP

SUN JAVA标准教程

){
23.  MyClass instance1 = new MyClass(1,2.0);
24.  MyClass instance2 = new MyClass(3,4.0);
25.  
26.  MyClass.statMethod(); //Outputs:statInt=4;
27.         //statDouble=16.0
28.
29.  instance1.instMethod(); //Outputs:instInt=1;
30.        //instDouble=2.0
31.  instance1.statMethod(); //Outputs:statInt=4;
32.        //statDouble=16.0
33.  
34.  instance2.instMethod(); //Outputs:instInt=3;
35.        //instDouble=4.0
36.  instance2.statMethod(); //Outputs:statInt=4;
37.        //statDouble=16.0
38.}
39.}
37.
    图6-1是MyClass类定义的框图。这个例子阐述了:
1.Static方法和数据的单个(共享)副本是因为类和该类的所有实例而存在。通过一个实例或通过类本身可以访问static成员。
2.非静态数据只限于实例,只能通过该实例的非静态方法对它进行访问。非静态数据定义对象之间互不相同的特点,非静态方法在它们所作用的非静态数据的基础上对每个对象的行为互不相同。
    考虑一下模仿汽车的特殊类型的一个对象的实例。轮子的大小,对该类型的所有汽车来说是个常量,可能被模仿成一个静态变量。颜色根据对象的不同而不同,其行为也根据对象的不同而不同,在它所作用的非静态数据的基础上对不同对象返回不同的颜色。

TOP

返回列表 回复 发帖