posts - 39,  comments - 44,  trackbacks - 0
           
          XML是eXtensible Markup Language的縮寫。擴(kuò)展標(biāo)記語言XML是一種簡單的數(shù)據(jù)存儲語言,使用一系列簡單的標(biāo)記描述數(shù)據(jù),而這些標(biāo)記可以用方便的方式建立,雖然XML占用的空間比二進(jìn)制數(shù)據(jù)要占用更多的空間,但XML極其簡單易于掌握和使用。

          XML與Access,Oracle和SQL Server等數(shù)據(jù)庫不同,數(shù)據(jù)庫提供了更強有力的數(shù)據(jù)存儲和分析能力,例如:數(shù)據(jù)索引、排序、查找、相關(guān)一致性等,XML僅僅是展示數(shù)據(jù)。事實上XML與其他數(shù)據(jù)表現(xiàn)形式最大的不同是:他極其簡單。這是一個看上去有點瑣細(xì)的優(yōu)點,但正是這點使XML與眾不同。

          XML的簡單使其易于在任何應(yīng)用程序中讀寫數(shù)據(jù),這使XML很快成為數(shù)據(jù)交換的唯一公共語言,雖然不同的應(yīng)用軟件也支持其它的數(shù)據(jù)交換格式,但不久之后他們都將支持XML,那就意味著程序可以更容易的與Windows、Mac OS, Linux以及其他平臺下產(chǎn)生的信息結(jié)合,然后可以很容易加載XML數(shù)據(jù)到程序中并分析他,并以XML格式輸出結(jié)果。

          XML的前身是SGML(The Standard Generalized Markup Language),是自IBM從60年代就開始發(fā)展的GML(Generalized Markup Language)

          HTML一樣, XML (可擴(kuò)展標(biāo)識語言)是通用標(biāo)識語言標(biāo)準(zhǔn)(SGML)的一個子集,它是描述網(wǎng)絡(luò)上的數(shù)據(jù)內(nèi)容和結(jié)構(gòu)的標(biāo)準(zhǔn)。盡管如此,XML不象HTML,HTML僅僅提供了在頁面上顯示信息的通用方法(沒有上下文相關(guān)和動態(tài)功能) ,XML則對數(shù)據(jù)賦予上下文相關(guān)功能,它繼承了SGML的大部分功能,卻使用了不太復(fù)雜的技術(shù)。.

          為了使得SGML顯得用戶友好,XML重新定義了SGML的一些內(nèi)部值和參數(shù),去掉了大量的很少用到的功能,這些繁雜的功能使得SGML在設(shè)計網(wǎng)站時顯得復(fù)雜化。XML保留了SGML的結(jié)構(gòu)化功能,這樣就使得網(wǎng)站設(shè)計者可以定義自己的文檔類型,XML同時也推出一種新型文檔類型,使得開發(fā)者也可以不必定義文檔類型。

          因為XML是W3C制定的,XML的標(biāo)準(zhǔn)化工作由W3C的XML工作組負(fù)責(zé),該小組成員由來自各個地方和行業(yè)的專家組成,他們通過email交流對XML標(biāo)準(zhǔn)的意見,并提出自己的看法 (www.w3.org/TR/WD-xml)。因為XML 是個公共格式, (它不專屬于任何一家公司),你不必?fù)?dān)心XML技術(shù)會成為少數(shù)公司的盈利工具,XML不是一個依附于特定瀏覽器的語言

          XML(可擴(kuò)展標(biāo)記語言)是從稱為SGML(標(biāo)準(zhǔn)通用標(biāo)記語言)的更加古老的語言派生出來的。SGML的主要目的是定義使用標(biāo)簽來表示數(shù)據(jù)的標(biāo)記語言的語法。

          標(biāo)簽由包圍在一個小于號(<)和一個大于號(>)之間的文本組成,例如<tag>。起始標(biāo)簽(start tag)表示一個特定區(qū)域的開始,例如<start>;結(jié)束標(biāo)簽(end tag)定義了一個區(qū)域的結(jié)束,除了在小于號之后緊跟著一個斜線(/)外,和起始標(biāo)簽基本一樣,例如</end>。SGML還定義了標(biāo)簽的特性(attribute),它們是定義在小于號和大于號之間的值,例如<img src="picture.jpg">中的src特性。如果你覺得它看起來很熟悉的話,應(yīng)該知道,基于SGML的語言的最著名實現(xiàn)就是原始的HTML。

          SGML常用來定義針對HTML的文檔類型定義(DTD),同時它也常用于編寫XML的DTD。SGML的問題就在于,它允許出現(xiàn)一些奇怪的語法,這讓創(chuàng)建HTML的解析器成為一個大難題:

          1  某些起始標(biāo)簽不允許出現(xiàn)結(jié)束標(biāo)簽,例如HTML中<img>標(biāo)簽。包含了結(jié)束標(biāo)簽就會出現(xiàn)錯誤。

          2  某些起始標(biāo)簽可以選擇性出現(xiàn)結(jié)束標(biāo)簽或者隱含了結(jié)束標(biāo)簽,例如HTML中<p>標(biāo)簽,當(dāng)出現(xiàn)另一個<p>標(biāo)簽或者某些其他標(biāo)簽時,便假設(shè)在這之前有一個結(jié)束標(biāo)簽。

          3  某些起始標(biāo)簽要求必須出現(xiàn)結(jié)束標(biāo)簽,例如HTML中<script>標(biāo)簽。

          4  標(biāo)簽可以以任何順序嵌套。即使結(jié)束標(biāo)簽不按照起始標(biāo)簽的逆序出現(xiàn)也是允許的,例如,<b>This is a <i> sample </b> string</i>是正確的。

          5  某些特性要求必須包含值,例如<img src="picture.jpg">中的src特性。

          6  某些特性不要求一定有值,例如<td nowrap>中的nowrap特性。

          7  定義特性的兩邊有沒有加上雙引號都是可以的,所以<img src="picture.jpg">和<img src=picture.jpg>都是允許的。

                這些問題使建立一個SGML語言的解析器變成了一項艱巨的任務(wù)。判斷何時應(yīng)用以上規(guī)則的困難導(dǎo)致了SGML語言的定義一直停滯不前。以這些問題作為出發(fā)點,XML逐漸步入我們的視野。

                XML去掉了之前令許多開發(fā)人員頭疼的SGML的隨意語法。在XML中,采用了如下的語法:

          8  任何的起始標(biāo)簽都必須有一個結(jié)束標(biāo)簽。

          9  可以采用另一種簡化語法,可以在一個標(biāo)簽中同時表示起始和結(jié)束標(biāo)簽。這種語法是在大于符號之前緊跟一個斜線(/),例如<tag />。XML解析器會將其翻譯成<tag></tag>。

          10  標(biāo)簽必須按合適的順序進(jìn)行嵌套,所以結(jié)束標(biāo)簽必須按鏡像順序匹配起始標(biāo)簽,例如<b>this is a <i>sample</i> string</b>。這好比是將起始和結(jié)束標(biāo)簽看作是數(shù)學(xué)中的左右括號:在沒有關(guān)閉所有的內(nèi)部括號之前,是不能關(guān)閉外面的括號的。

          11  所有的特性都必須有值。

          12  所有的特性都必須在值的周圍加上雙引號。

          這些規(guī)則使得開發(fā)一個XML解析器要簡便得多,而且也除去了解析SGML中花在判斷何時何地應(yīng)用那些奇怪語法規(guī)則上的工作。僅僅在XML出現(xiàn)后的前六年就衍生出多種不同的語言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同時也將HTML改進(jìn)為XHTML。

          如果需要關(guān)于SGML和XML具體技術(shù)上的對比,請查看W3C的注解,位于:http://www.w3. org/TR/NOTE-sgml-xml.html

          如今,XML已經(jīng)是世界上發(fā)展最快的技術(shù)之一。它的主要目的是使用文本以結(jié)構(gòu)化的方式來表示數(shù)據(jù)。在某些方面,XML文件也類似于數(shù)據(jù)庫,提供數(shù)據(jù)的結(jié)構(gòu)化視圖。這里是一個XML文件的例子:


          每個XML文檔都由XML序言開始,在前面的代碼中的第一行便是XML序言,<?xml version="1.0"?>。這一行代碼會告訴解析器和瀏覽器,這個文件應(yīng)該按照前面討論過的XML規(guī)則進(jìn)行解析。第二行代碼,<books>,則是文檔元素(document element),它是文件中最外面的標(biāo)簽(我們認(rèn)為元素(element)是起始標(biāo)簽和結(jié)束標(biāo)簽之間的內(nèi)容)。所有其他的標(biāo)簽必須包含在這個標(biāo)簽之內(nèi)來組成一個有效的XML文件。XML文件的第二行并不一定要包含文檔元素;如果有注釋或者其他內(nèi)容,文檔元素可以遲些出現(xiàn)。

          范例文件中的第三行代碼是注釋,你會發(fā)現(xiàn)它與HTML中使用的注釋風(fēng)格是一樣的。這是XML從SGML中繼承的語法元素之一。

          頁面再往下的一些地方,可以發(fā)現(xiàn)<desc>標(biāo)簽里有一些特殊的語法。<![CDATA[ ]]>代碼用于表示無需進(jìn)行解析的文本,允許諸如大于號和小于號之類的特殊字符包含在文本中,而無需擔(dān)心破壞XML的語法。文本必須出現(xiàn)在<![CDATA[和]]>之間才能合適地避免被解析。這樣的文本稱為Character Data Section,簡稱CData Section。

          下面的一行就是在第二本書的定義之前的:

          <?page render multiple authors ?>

          雖然它看上去很像XML序言,但實際上是一種稱為處理指令(processing instruction)的不同類型的語法。處理指令(以下簡稱PI)的目的是為了給處理頁面的程序(例如XML解析器)提供額外的信息。PI通常情況下是沒有固定格式的,唯一的要求是緊隨第一個問號必須至少有一個字母。在此之后,PI可以包含除了小于號和大于號之外的任何字符串序列。

          最常見的PI是用來指定XML文件的樣式表:



          這個PI一般會直接放在XML序言之后,通常由Web瀏覽器使用,來將XML數(shù)據(jù)以特殊的樣式顯示出來。
          posted @ 2008-05-06 14:09 礦礦 閱讀(286) | 評論 (0)編輯 收藏
          XML是eXtensible Markup Language的縮寫。擴(kuò)展標(biāo)記語言XML是一種簡單的數(shù)據(jù)存儲語言,使用一系列簡單的標(biāo)記描述數(shù)據(jù),而這些標(biāo)記可以用方便的方式建立,雖然XML占用的空間比二進(jìn)制數(shù)據(jù)要占用更多的空間,但XML極其簡單易于掌握和使用。

          XML與Access,Oracle和SQL Server等數(shù)據(jù)庫不同,數(shù)據(jù)庫提供了更強有力的數(shù)據(jù)存儲和分析能力,例如:數(shù)據(jù)索引、排序、查找、相關(guān)一致性等,XML僅僅是展示數(shù)據(jù)。事實上XML與其他數(shù)據(jù)表現(xiàn)形式最大的不同是:他極其簡單。這是一個看上去有點瑣細(xì)的優(yōu)點,但正是這點使XML與眾不同。

          XML的簡單使其易于在任何應(yīng)用程序中讀寫數(shù)據(jù),這使XML很快成為數(shù)據(jù)交換的唯一公共語言,雖然不同的應(yīng)用軟件也支持其它的數(shù)據(jù)交換格式,但不久之后他們都將支持XML,那就意味著程序可以更容易的與Windows、Mac OS, Linux以及其他平臺下產(chǎn)生的信息結(jié)合,然后可以很容易加載XML數(shù)據(jù)到程序中并分析他,并以XML格式輸出結(jié)果。

          XML的前身是SGML(The Standard Generalized Markup Language),是自IBM從60年代就開始發(fā)展的GML(Generalized Markup Language)

          HTML一樣, XML (可擴(kuò)展標(biāo)識語言)是通用標(biāo)識語言標(biāo)準(zhǔn)(SGML)的一個子集,它是描述網(wǎng)絡(luò)上的數(shù)據(jù)內(nèi)容和結(jié)構(gòu)的標(biāo)準(zhǔn)。盡管如此,XML不象HTML,HTML僅僅提供了在頁面上顯示信息的通用方法(沒有上下文相關(guān)和動態(tài)功能) ,XML則對數(shù)據(jù)賦予上下文相關(guān)功能,它繼承了SGML的大部分功能,卻使用了不太復(fù)雜的技術(shù)。.

          為了使得SGML顯得用戶友好,XML重新定義了SGML的一些內(nèi)部值和參數(shù),去掉了大量的很少用到的功能,這些繁雜的功能使得SGML在設(shè)計網(wǎng)站時顯得復(fù)雜化。XML保留了SGML的結(jié)構(gòu)化功能,這樣就使得網(wǎng)站設(shè)計者可以定義自己的文檔類型,XML同時也推出一種新型文檔類型,使得開發(fā)者也可以不必定義文檔類型。

          因為XML是W3C制定的,XML的標(biāo)準(zhǔn)化工作由W3C的XML工作組負(fù)責(zé),該小組成員由來自各個地方和行業(yè)的專家組成,他們通過email交流對XML標(biāo)準(zhǔn)的意見,并提出自己的看法 (www.w3.org/TR/WD-xml)。因為XML 是個公共格式, (它不專屬于任何一家公司),你不必?fù)?dān)心XML技術(shù)會成為少數(shù)公司的盈利工具,XML不是一個依附于特定瀏覽器的語言

          XML(可擴(kuò)展標(biāo)記語言)是從稱為SGML(標(biāo)準(zhǔn)通用標(biāo)記語言)的更加古老的語言派生出來的。SGML的主要目的是定義使用標(biāo)簽來表示數(shù)據(jù)的標(biāo)記語言的語法。

          標(biāo)簽由包圍在一個小于號(<)和一個大于號(>)之間的文本組成,例如<tag>。起始標(biāo)簽(start tag)表示一個特定區(qū)域的開始,例如<start>;結(jié)束標(biāo)簽(end tag)定義了一個區(qū)域的結(jié)束,除了在小于號之后緊跟著一個斜線(/)外,和起始標(biāo)簽基本一樣,例如</end>。SGML還定義了標(biāo)簽的特性(attribute),它們是定義在小于號和大于號之間的值,例如<img src="picture.jpg">中的src特性。如果你覺得它看起來很熟悉的話,應(yīng)該知道,基于SGML的語言的最著名實現(xiàn)就是原始的HTML。

          SGML常用來定義針對HTML的文檔類型定義(DTD),同時它也常用于編寫XML的DTD。SGML的問題就在于,它允許出現(xiàn)一些奇怪的語法,這讓創(chuàng)建HTML的解析器成為一個大難題:

          1  某些起始標(biāo)簽不允許出現(xiàn)結(jié)束標(biāo)簽,例如HTML中<img>標(biāo)簽。包含了結(jié)束標(biāo)簽就會出現(xiàn)錯誤。

          2  某些起始標(biāo)簽可以選擇性出現(xiàn)結(jié)束標(biāo)簽或者隱含了結(jié)束標(biāo)簽,例如HTML中<p>標(biāo)簽,當(dāng)出現(xiàn)另一個<p>標(biāo)簽或者某些其他標(biāo)簽時,便假設(shè)在這之前有一個結(jié)束標(biāo)簽。

          3  某些起始標(biāo)簽要求必須出現(xiàn)結(jié)束標(biāo)簽,例如HTML中<script>標(biāo)簽。

          4  標(biāo)簽可以以任何順序嵌套。即使結(jié)束標(biāo)簽不按照起始標(biāo)簽的逆序出現(xiàn)也是允許的,例如,<b>This is a <i> sample </b> string</i>是正確的。

          5  某些特性要求必須包含值,例如<img src="picture.jpg">中的src特性。

          6  某些特性不要求一定有值,例如<td nowrap>中的nowrap特性。

          7  定義特性的兩邊有沒有加上雙引號都是可以的,所以<img src="picture.jpg">和<img src=picture.jpg>都是允許的。

                這些問題使建立一個SGML語言的解析器變成了一項艱巨的任務(wù)。判斷何時應(yīng)用以上規(guī)則的困難導(dǎo)致了SGML語言的定義一直停滯不前。以這些問題作為出發(fā)點,XML逐漸步入我們的視野。

                XML去掉了之前令許多開發(fā)人員頭疼的SGML的隨意語法。在XML中,采用了如下的語法:

          8  任何的起始標(biāo)簽都必須有一個結(jié)束標(biāo)簽。

          9  可以采用另一種簡化語法,可以在一個標(biāo)簽中同時表示起始和結(jié)束標(biāo)簽。這種語法是在大于符號之前緊跟一個斜線(/),例如<tag />。XML解析器會將其翻譯成<tag></tag>。

          10  標(biāo)簽必須按合適的順序進(jìn)行嵌套,所以結(jié)束標(biāo)簽必須按鏡像順序匹配起始標(biāo)簽,例如<b>this is a <i>sample</i> string</b>。這好比是將起始和結(jié)束標(biāo)簽看作是數(shù)學(xué)中的左右括號:在沒有關(guān)閉所有的內(nèi)部括號之前,是不能關(guān)閉外面的括號的。

          11  所有的特性都必須有值。

          12  所有的特性都必須在值的周圍加上雙引號。

          這些規(guī)則使得開發(fā)一個XML解析器要簡便得多,而且也除去了解析SGML中花在判斷何時何地應(yīng)用那些奇怪語法規(guī)則上的工作。僅僅在XML出現(xiàn)后的前六年就衍生出多種不同的語言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同時也將HTML改進(jìn)為XHTML。

          如果需要關(guān)于SGML和XML具體技術(shù)上的對比,請查看W3C的注解,位于:http://www.w3. org/TR/NOTE-sgml-xml.html

          如今,XML已經(jīng)是世界上發(fā)展最快的技術(shù)之一。它的主要目的是使用文本以結(jié)構(gòu)化的方式來表示數(shù)據(jù)。在某些方面,XML文件也類似于數(shù)據(jù)庫,提供數(shù)據(jù)的結(jié)構(gòu)化視圖。這里是一個XML文件的例子:


          每個XML文檔都由XML序言開始,在前面的代碼中的第一行便是XML序言,<?xml version="1.0"?>。這一行代碼會告訴解析器和瀏覽器,這個文件應(yīng)該按照前面討論過的XML規(guī)則進(jìn)行解析。第二行代碼,<books>,則是文檔元素(document element),它是文件中最外面的標(biāo)簽(我們認(rèn)為元素(element)是起始標(biāo)簽和結(jié)束標(biāo)簽之間的內(nèi)容)。所有其他的標(biāo)簽必須包含在這個標(biāo)簽之內(nèi)來組成一個有效的XML文件。XML文件的第二行并不一定要包含文檔元素;如果有注釋或者其他內(nèi)容,文檔元素可以遲些出現(xiàn)。

          范例文件中的第三行代碼是注釋,你會發(fā)現(xiàn)它與HTML中使用的注釋風(fēng)格是一樣的。這是XML從SGML中繼承的語法元素之一。

          頁面再往下的一些地方,可以發(fā)現(xiàn)<desc>標(biāo)簽里有一些特殊的語法。<![CDATA[ ]]>代碼用于表示無需進(jìn)行解析的文本,允許諸如大于號和小于號之類的特殊字符包含在文本中,而無需擔(dān)心破壞XML的語法。文本必須出現(xiàn)在<![CDATA[和]]>之間才能合適地避免被解析。這樣的文本稱為Character Data Section,簡稱CData Section。

          下面的一行就是在第二本書的定義之前的:

          <?page render multiple authors ?>

          雖然它看上去很像XML序言,但實際上是一種稱為處理指令(processing instruction)的不同類型的語法。處理指令(以下簡稱PI)的目的是為了給處理頁面的程序(例如XML解析器)提供額外的信息。PI通常情況下是沒有固定格式的,唯一的要求是緊隨第一個問號必須至少有一個字母。在此之后,PI可以包含除了小于號和大于號之外的任何字符串序列。

          最常見的PI是用來指定XML文件的樣式表:



          這個PI一般會直接放在XML序言之后,通常由Web瀏覽器使用,來將XML數(shù)據(jù)以特殊的樣式顯示出來。
          posted @ 2008-05-06 14:09 礦礦 閱讀(276) | 評論 (0)編輯 收藏
          //frame版程序源代碼如下,疏漏之處,望批評指正。
          //數(shù)字分組沒有編寫,科學(xué)型計算器沒有編寫,其他已經(jīng)完善。
          import java.awt.*;
          import java.lang.*;
          import javax.swing.*;
          import javax.swing.event.*;
          import java.awt.event.*;
          import java.text.DecimalFormat;
          public class Calculator
          implements ActionListener { //導(dǎo)入動作監(jiān)聽接口
          //設(shè)計面板中的單位
          JFrame frame;
          JTextField textAnswer;
          JPanel panel, panel1, panel2, panel3;
          JMenuBar mainMenu;
          JTextField textMemory;
          JLabel labelMemSpace; //labelMemSpace單純做擺設(shè),控制面板的形狀
          JButton buttonBk, buttonCe, buttonC;
          JButton button[];
          JButton buttonMC, buttonMR, buttonMS, buttonMAdd;
          JButton buttonDot, buttonAddAndSub, buttonAdd, buttonSub, buttonMul,
          buttonDiv, buttonMod;
          JButton buttonSqrt, buttonDao, buttonEqual;
          JMenu editMenu, viewMenu, helpMenu;
          JMenuItem copyItem, pasteItem, tItem, sItem, numberGroup, topHelp, aboutCal;
          DecimalFormat df; //設(shè)置數(shù)據(jù)輸出精度
          boolean clickable; //控制當(dāng)前能否按鍵
          double memoryd; //使用內(nèi)存中存儲的數(shù)字
          int memoryi;
          double vard, answerd; //用來保存double型數(shù)據(jù)的中間值(vard)和最后結(jié)果(answerd)
          short key = -1, prekey = -1; //key用來保存當(dāng)前進(jìn)行何種運算,prekey用來保存前次進(jìn)行何種運算
          String copy; //做復(fù)制用
          JTextArea help; //幫助
          JScrollPane scrollHelp;
          //構(gòu)造函數(shù)
          public Calculator() {
          clickable = true;
          answerd = 0;
          frame = new JFrame("計算器");
          df = new DecimalFormat("0.##############"); //設(shè)置數(shù)據(jù)輸出精度(對于double型值)
          textAnswer = new JTextField(15);
          textAnswer.setText("");
          textAnswer.setEditable(false);
          textAnswer.setBackground(new Color(255, 255, 255));
          panel = new JPanel();
          frame.getContentPane().add(panel);
          panel1 = new JPanel();
          panel2 = new JPanel();
          panel.setLayout(new BorderLayout());
          //設(shè)計整個面板
          mainMenu = new JMenuBar();
          editMenu = new JMenu("編輯(E)");
          viewMenu = new JMenu("查看(V)");
          helpMenu = new JMenu("幫助(H)");
          copyItem = new JMenuItem(" 復(fù)制(C) Ctrl+C");
          copyItem.addActionListener(this);
          pasteItem = new JMenuItem(" 粘貼(V) Ctrl+V");
          pasteItem.addActionListener(this);
          editMenu.add(copyItem);
          editMenu.add(pasteItem);
          tItem = new JMenuItem("●標(biāo)準(zhǔn)型(T)");
          tItem.addActionListener(this);
          sItem = new JMenuItem(" 科學(xué)型(S)");
          sItem.addActionListener(this);
          numberGroup = new JMenuItem(" 數(shù)字分組(I)");
          numberGroup.addActionListener(this);
          viewMenu.add(tItem);
          viewMenu.add(sItem);
          viewMenu.add(numberGroup);
          topHelp = new JMenuItem(" 幫助主題(H)");
          topHelp.addActionListener(this);
          help = new JTextArea(5, 20);
          scrollHelp = new JScrollPane(help);
          help.setEditable(false);
          help.append("執(zhí)行簡單計算\n");
          help.append("1. 鍵入計算的第一個數(shù)字。\n");
          help.append("2. 單擊“+”執(zhí)行加、“-”執(zhí)行減、“*”執(zhí)行乘或“/”執(zhí)行除。\n");
          help.append("3. 鍵入計算的下一個數(shù)字。\n");
          help.append("4. 輸入所有剩余的運算符和數(shù)字。\n");
          help.append("5. 單擊“=”。\n");
          aboutCal = new JMenuItem(" 關(guān)于計算器(A)");
          aboutCal.addActionListener(this);
          helpMenu.add(topHelp);
          helpMenu.add(aboutCal);
          mainMenu.add(editMenu);
          mainMenu.add(viewMenu);
          mainMenu.add(helpMenu);
          panel.add(mainMenu, BorderLayout.NORTH);
          panel.add(textAnswer, BorderLayout.CENTER);
          panel.add(panel1, BorderLayout.SOUTH);
          panel1.setLayout(new BorderLayout());
          textMemory = new JTextField(3);
          textMemory.setEditable(false);
          textMemory.setBackground(new Color(217, 217, 217));
          labelMemSpace = new JLabel(" ");
          buttonBk = new JButton("Backspace");
          buttonBk.setForeground(new Color(255, 0, 0));
          buttonCe = new JButton("CE");
          buttonCe.setForeground(new Color(255, 0, 0));
          buttonC = new JButton("C");
          buttonC.setForeground(new Color(255, 0, 0));
          buttonBk.addActionListener(this);
          buttonCe.addActionListener(this);
          buttonC.addActionListener(this);
          panel1.add(panel2, BorderLayout.NORTH);
          panel2.setLayout(new FlowLayout(FlowLayout.RIGHT));
          panel2.add(textMemory);
          panel2.add(labelMemSpace);
          panel2.add(buttonBk);
          panel2.add(buttonCe);
          panel2.add(buttonC);
          panel3 = new JPanel();
          panel1.add(panel3, BorderLayout.CENTER);
          button = new JButton[10];
          for (int i = 0; i < button.length; i++) {
          button[i] = new JButton(Integer.toString(i));
          button[i].setForeground(new Color(0, 0, 255));
          }
          buttonMC = new JButton("MC");
          buttonMC.setForeground(new Color(255, 0, 0));
          buttonMR = new JButton("MR");
          buttonMR.setForeground(new Color(255, 0, 0));
          buttonMS = new JButton("MS");
          buttonMS.setForeground(new Color(255, 0, 0));
          buttonMAdd = new JButton("M+");
          buttonMAdd.setForeground(new Color(255, 0, 0));
          buttonDot = new JButton(".");
          buttonDot.setForeground(new Color(0, 0, 255));
          buttonAddAndSub = new JButton("+/-");
          buttonAddAndSub.setForeground(new Color(0, 0, 255));
          buttonAdd = new JButton("+");
          buttonAdd.setForeground(new Color(255, 0, 0));
          buttonSub = new JButton("-");
          buttonSub.setForeground(new Color(255, 0, 0));
          buttonMul = new JButton("*");
          buttonMul.setForeground(new Color(255, 0, 0));
          buttonDiv = new JButton("/");
          buttonDiv.setForeground(new Color(255, 0, 0));
          buttonMod = new JButton("%");
          buttonMod.setForeground(new Color(0, 0, 255));
          buttonSqrt = new JButton("sqrt");
          buttonSqrt.setForeground(new Color(0, 0, 255));
          buttonDao = new JButton("1/x");
          buttonDao.setForeground(new Color(0, 0, 255));
          buttonEqual = new JButton("=");
          buttonEqual.setForeground(new Color(255, 0, 0));
          //將所有行為與監(jiān)聽綁定
          panel3.setLayout(new GridLayout(4, 6));
          panel3.add(buttonMC);
          buttonMC.addActionListener(this);
          panel3.add(button[7]);
          button[7].addActionListener(this);
          panel3.add(button[8]);
          button[8].addActionListener(this);
          panel3.add(button[9]);
          button[9].addActionListener(this);
          panel3.add(buttonDiv);
          buttonDiv.addActionListener(this);
          panel3.add(buttonSqrt);
          buttonSqrt.addActionListener(this);
          panel3.add(buttonMR);
          buttonMR.addActionListener(this);
          panel3.add(button[4]);
          button[4].addActionListener(this);
          panel3.add(button[5]);
          button[5].addActionListener(this);
          panel3.add(button[6]);
          button[6].addActionListener(this);
          panel3.add(buttonMul);
          buttonMul.addActionListener(this);
          panel3.add(buttonMod);
          buttonMod.addActionListener(this);
          panel3.add(buttonMS);
          buttonMS.addActionListener(this);
          panel3.add(button[1]);
          button[1].addActionListener(this);
          panel3.add(button[2]);
          button[2].addActionListener(this);
          panel3.add(button[3]);
          button[3].addActionListener(this);
          panel3.add(buttonSub);
          buttonSub.addActionListener(this);
          panel3.add(buttonDao);
          buttonDao.addActionListener(this);
          panel3.add(buttonMAdd);
          buttonMAdd.addActionListener(this);
          panel3.add(button[0]);
          button[0].addActionListener(this);
          panel3.add(buttonAddAndSub);
          buttonAddAndSub.addActionListener(this);
          panel3.add(buttonDot);
          buttonDot.addActionListener(this);
          panel3.add(buttonAdd);
          buttonAdd.addActionListener(this);
          panel3.add(buttonEqual);
          buttonEqual.addActionListener(this);
          frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
          frame.pack();
          frame.show();
          }
          //設(shè)置各個按鈕行為
          public void actionPerformed(ActionEvent event) {
          boolean sign = false; //判斷是否是double型數(shù)參與運算,是為true,不是為false
          Object temp = event.getSource();
          try {
          //如果按下數(shù)據(jù)按鈕,將按下的按鈕代表的數(shù)據(jù)插入的當(dāng)前文本框字符串之后
          for (int i = 0; i <= 9; i++)
          if (temp == button[i] && clickable == true)
          textAnswer.setText(textAnswer.getText() + Integer.toString(i));
          //按下'.'按鈕時,判斷當(dāng)前文本框內(nèi)字符串中含不含'.',如果已含,則不允許再插入'.'
          if (temp == buttonDot && clickable == true) {
          boolean isDot = false;
          if (textAnswer.getText().length() == 0)
          isDot = true;
          for (int i = 0; i < textAnswer.getText().length(); i++)
          if ('.' == textAnswer.getText().charAt(i)) {
          isDot = true;
          break;
          }
          if (isDot == false)
          textAnswer.setText(textAnswer.getText() + ".");
          }
          if ( (temp == buttonAdd || temp == buttonSub || temp == buttonMul ||
          temp == buttonDiv) && clickable == true) {
          //'+'操作
          if (temp == buttonAdd) {
          switch (prekey) {
          case 0:
          answerd += Double.parseDouble(textAnswer.getText());
          break;
          case 1:
          answerd -= Double.parseDouble(textAnswer.getText());
          break;
          case 2:
          answerd *= Double.parseDouble(textAnswer.getText());
          break;
          case 3:
          if (Double.parseDouble(textAnswer.getText()) == 0) {
          textAnswer.setText("除數(shù)不能為零");
          clickable = false;
          }
          else
          answerd /= Double.parseDouble(textAnswer.getText());
          break;
          default:
          answerd = Double.parseDouble(textAnswer.getText());
          }
          textAnswer.setText("");
          prekey = key = 0;
          }
          //'-'操作
          if (temp == buttonSub) {
          switch (prekey) {
          case 0:
          answerd += Double.parseDouble(textAnswer.getText());
          break;
          case 1:
          answerd -= Double.parseDouble(textAnswer.getText());
          break;
          case 2:
          answerd *= Double.parseDouble(textAnswer.getText());
          break;
          case 3:
          if (Double.parseDouble(textAnswer.getText()) == 0) {
          textAnswer.setText("除數(shù)不能為零");
          clickable = false;
          }
          else
          answerd /= Double.parseDouble(textAnswer.getText());
          break;
          default:
          answerd = Double.parseDouble(textAnswer.getText());
          }
          textAnswer.setText("");
          prekey = key = 1;
          }
          //'*'操作
          if (temp == buttonMul) {
          switch (prekey) {
          case 0:
          answerd += Double.parseDouble(textAnswer.getText());
          break;
          case 1:
          answerd -= Double.parseDouble(textAnswer.getText());
          break;
          case 2:
          answerd *= Double.parseDouble(textAnswer.getText());
          break;
          case 3:
          if (Double.parseDouble(textAnswer.getText()) == 0) {
          textAnswer.setText("除數(shù)不能為零");
          clickable = false;
          }
          else
          answerd /= Double.parseDouble(textAnswer.getText());
          break;
          default:
          answerd = Double.parseDouble(textAnswer.getText());
          }
          textAnswer.setText("");
          prekey = key = 2;
          }
          //'/'操作
          if (temp == buttonDiv) {
          switch (prekey) {
          case 0:
          answerd += Double.parseDouble(textAnswer.getText());
          break;
          case 1:
          answerd -= Double.parseDouble(textAnswer.getText());
          break;
          case 2:
          answerd *= Double.parseDouble(textAnswer.getText());
          break;
          case 3:
          if (Double.parseDouble(textAnswer.getText()) == 0) {
          textAnswer.setText("除數(shù)不能為零");
          clickable = false;
          }
          else
          answerd /= Double.parseDouble(textAnswer.getText());
          break;
          default:
          answerd = Double.parseDouble(textAnswer.getText());
          }
          textAnswer.setText("");
          prekey = key = 3;
          }
          }
          //'='操作
          if (temp == buttonEqual && clickable == true) {
          //如果連續(xù)按'=',則進(jìn)行連續(xù)運算
          if (prekey == 5) {
          if (key == 0) {
          answerd += vard;
          textAnswer.setText(df.format(answerd));
          }
          if (key == 1) {
          answerd -= vard;
          textAnswer.setText(df.format(answerd));
          }
          if (key == 2) {
          answerd *= vard;
          textAnswer.setText(df.format(answerd));
          }
          if (key == 3) {
          if (Double.parseDouble(textAnswer.getText()) == 0) {
          textAnswer.setText("除數(shù)不能為零");
          clickable = false;
          }
          else {
          answerd /= vard;
          textAnswer.setText(df.format(answerd));
          }
          }
          }
          else {
          vard = Double.parseDouble(textAnswer.getText());
          if (key == 0) {
          prekey = -1;
          answerd += Double.parseDouble(textAnswer.getText());
          textAnswer.setText(df.format(answerd));
          }
          if (key == 1) {
          prekey = -1;
          answerd -= Double.parseDouble(textAnswer.getText());
          textAnswer.setText(df.format(answerd));
          }
          if (key == 2) {
          prekey = -1;
          answerd *= Double.parseDouble(textAnswer.getText());
          textAnswer.setText(df.format(answerd));
          }
          if (key == 3) {
          prekey = -1;
          if (Double.parseDouble(textAnswer.getText()) == 0) {
          textAnswer.setText("除數(shù)不能為零");
          clickable = false;
          }
          else {
          answerd /= Double.parseDouble(textAnswer.getText());
          textAnswer.setText(df.format(answerd));
          }
          }
          }
          prekey = 5;
          }
          //'%'操作,對第二個操作數(shù)除以100
          if (temp == buttonMod && clickable == true) {
          if (answerd == 0) {
          String s = textAnswer.getText();
          textAnswer.setText(s);
          }
          else {
          boolean isDot = false;
          for (int i = 0; i < textAnswer.getText().length(); i++)
          if ('.' == textAnswer.getText().charAt(i)) {
          isDot = true;
          break;
          }
          //如果是double數(shù),除100
          if (isDot == true) {
          double dtemp = Double.parseDouble(textAnswer.getText());
          dtemp = dtemp / 100.0;
          textAnswer.setText(Double.toString(dtemp));
          }
          else {
          //如果是int數(shù)但能被100整除,則去掉末尾兩個零
          if (Integer.parseInt(textAnswer.getText()) % 100 == 0) {
          int itemp = Integer.parseInt(textAnswer.getText());
          itemp /= 100;
          textAnswer.setText(Integer.toString(itemp));
          }
          //如果是int數(shù),但不能被100整除,則按double數(shù)處理
          else {
          double dtemp = Double.parseDouble(textAnswer.getText());
          dtemp = dtemp / 100.0;
          textAnswer.setText(Double.toString(dtemp));
          }
          }
          }
          }
          //開根號運算
          if (temp == buttonSqrt && clickable == true) {
          String s = textAnswer.getText();
          if (s.charAt(0) == '-') {
          textAnswer.setText("負(fù)數(shù)不能開根號");
          clickable = false;
          }
          else
          textAnswer.setText(Double.toString(java.lang.Math.sqrt(Double.
          parseDouble(textAnswer.getText()))));
          }
          //倒數(shù)運算
          if (temp == buttonDao && clickable == true) {
          if (textAnswer.getText().charAt(0) == '0' &&
          textAnswer.getText().length() == 1) {
          textAnswer.setText("零不能求倒數(shù)");
          clickable = false;
          }
          else {
          boolean isDec = true;
          int i, j, k;
          String s = Double.toString(1 / Double.parseDouble(textAnswer.getText()));
          for (i = 0; i < s.length(); i++)
          if (s.charAt(i) == '.')
          break;
          for (j = i + 1; j < s.length(); j++)
          if (s.charAt(j) != '0') {
          isDec = false;
          break;
          }
          if (isDec == true) {
          String stemp = "";
          for (k = 0; k < i; k++)
          stemp += s.charAt(k);
          textAnswer.setText(stemp);
          }
          else
          textAnswer.setText(s);
          }
          }
          //按下'+/-'按鈕時處理
          if (temp == buttonAddAndSub && clickable == true) {
          boolean isNumber = true;
          String s = textAnswer.getText();
          for (int i = 0; i < s.length(); i++)
          if (! (s.charAt(i) >= '0' && s.charAt(i) <= '9' || s.charAt(i) == '.' ||
          s.charAt(i) == '-')) {
          isNumber = false;
          break;
          }
          if (isNumber == true) {
          //如果當(dāng)前字符串首字母有'-'號,代表現(xiàn)在是個負(fù)數(shù),再按下時,則將首符號去掉
          if (s.charAt(0) == '-') {
          textAnswer.setText("");
          for (int i = 1; i < s.length(); i++) {
          char a = s.charAt(i);
          textAnswer.setText(textAnswer.getText() + a);
          }
          }
          //如果當(dāng)前字符串第一個字符不是符號,則添加一個符號在首字母處
          else
          textAnswer.setText('-' + s);
          }
          }
          //計算器有關(guān)內(nèi)存操作
          //'MC'的操作,將內(nèi)存清0
          if (temp == buttonMC && clickable == true) {
          memoryd = memoryi = 0;
          textMemory.setText("");
          }
          //'MS'的操作,將當(dāng)前文本框內(nèi)容保存入內(nèi)存,顯示'M'
          if (temp == buttonMS && clickable == true) {
          boolean isDot = false;
          textMemory.setText(" M");
          for (int i = 0; i < textAnswer.getText().length(); i++)
          if ('.' == textAnswer.getText().charAt(i)) {
          isDot = true;
          break;
          }
          //如果是double,則存入memoryd(double存儲器)
          if (isDot == true) {
          memoryd = Double.parseDouble(textAnswer.getText());
          memoryi = 0; //保證存儲器中存放最新的值
          }
          //如果是int,則存入memoryi(int存儲器)
          else {
          memoryi = Integer.parseInt(textAnswer.getText());
          memoryd = 0; //保證存儲器中存放最新的值
          }
          }
          //'MR'的操作,將存儲器中的信息輸出
          if (temp == buttonMR && clickable == true) {
          if (memoryd != 0)
          textAnswer.setText(Double.toString(memoryd));
          if (memoryi != 0)
          textAnswer.setText(Integer.toString(memoryi));
          }
          //'M+'的功能,將當(dāng)前文本框里的數(shù)據(jù)和存儲器中數(shù)據(jù)相加后,再存入存儲器
          if (temp == buttonMAdd && clickable == true) {
          boolean isDot = false;
          for (int i = 0; i < textAnswer.getText().length(); i++)
          if ('.' == textAnswer.getText().charAt(i)) {
          isDot = true;
          break;
          }
          if (memoryi != 0) { //存儲中是一個int型數(shù)
          if (isDot == false) //被加數(shù)是一個int型數(shù)
          memoryi += Integer.parseInt(textAnswer.getText());
          else { //被加數(shù)是一個double型數(shù),則將int存儲器中數(shù)傳入double存儲器與當(dāng)前數(shù)相加,int存儲器清零
          memoryd = memoryi + Double.parseDouble(textAnswer.getText());
          memoryi = 0;
          }
          }
          else
          memoryd += Double.parseDouble(textAnswer.getText());
          }
          //按下'Backspace'鍵,利用循環(huán)將當(dāng)前字符串中的最后一個字母刪除
          if (temp == buttonBk && clickable == true) {
          String s = textAnswer.getText();
          textAnswer.setText("");
          for (int i = 0; i < s.length() - 1; i++) {
          char a = s.charAt(i);
          textAnswer.setText(textAnswer.getText() + a);
          }
          }
          //按下'CE'按鈕,將當(dāng)前文本框內(nèi)數(shù)據(jù)清除
          if (temp == buttonCe) {
          textAnswer.setText("");
          clickable = true;
          }
          //按下'C'按鈕,文本框內(nèi)數(shù)據(jù)清除,同時var,answer清0
          if (temp == buttonC) {
          vard = answerd = 0;
          textAnswer.setText("");
          clickable = true;
          }
          //按下'復(fù)制'菜單欄
          if (temp == copyItem) {
          copy = textAnswer.getText();
          }
          //按下'粘貼'菜單欄
          if (temp == pasteItem) {
          textAnswer.setText(copy);
          }
          if (temp == sItem) {
          JOptionPane.showMessageDialog(panel, "當(dāng)前是標(biāo)準(zhǔn)型計算器,\n科學(xué)型計算器有待更新。");
          }
          //按下'幫助主題'菜單欄
          if (temp == topHelp) {
          JOptionPane.showMessageDialog(panel, scrollHelp);
          }
          //按下'數(shù)字分組'菜單欄
          if (temp == numberGroup) {
          if (numberGroup.getText().compareTo(" 數(shù)字分組(I)") == 0)
          numberGroup.setText("√數(shù)字分組(I)");
          else
          numberGroup.setText(" 數(shù)字分組(I)");
          }
          //按下'關(guān)于'菜單欄
          if (temp == aboutCal) {
          JOptionPane.showMessageDialog(panel, "計算器1.00版\n開發(fā)者:礦礦");
          }
          }
          //輸入中如果有操作非法,比如按下兩次'+',捕獲異常
          catch (Exception e) {
          textAnswer.setText("操作非法");
          clickable = false;
          }
          }
          //主函數(shù)
          public static void main(String args[]) {
          new Calculator();
          }
          }
          posted @ 2008-04-21 20:44 礦礦 閱讀(3314) | 評論 (3)編輯 收藏
          package t06;

          import java.awt.BorderLayout;
          import java.awt.Container;
          import java.awt.Dimension;
          import java.awt.Toolkit;

          import javax.swing.ImageIcon;
          import javax.swing.JButton;
          import javax.swing.JCheckBox;
          import javax.swing.JComboBox;
          import javax.swing.JFrame;
          import javax.swing.JLabel;
          import javax.swing.JPanel;
          import javax.swing.JPasswordField;
          import javax.swing.JTextField;

          public class Demo extends JFrame{

              Container contentPane;
              ImageIcon img = new ImageIcon("002.jpg");
             
              JPanel paneTop = new JPanel();
              JPanel paneMid = new JPanel();
              JPanel paneBut = new JPanel();
              JPanel paneAll = new JPanel();
             
              JLabel lblTop = new JLabel();
              JLabel lblName = new JLabel();
              JLabel lblPwd = new JLabel();
              JLabel lblApply = new JLabel();
              JLabel lblForget = new JLabel();
              JLabel lblModel = new JLabel();
              JLabel lblNull = new JLabel();
             
              JTextField txtName = new JTextField(15);
              JPasswordField txtPwd = new JPasswordField(15);
             
              JComboBox cmb = new JComboBox();
             
              JCheckBox chk = new JCheckBox();
             
              JButton btnKill = new JButton("查殺木馬");
              JButton btnSet = new JButton("設(shè)置");
              JButton btnLogin = new JButton("登錄");
             
             
             
              Demo(){
                  lblTop.setIcon(img);
                  paneTop.add(lblTop);
                 
                  lblName.setText("QQ帳號:");
                  lblApply.setText("申請帳號   ");
                  lblPwd.setText("QQ密碼:");
                  lblForget.setText("忘記密碼?");
                  lblModel.setText("狀態(tài):");
                 
                  String[] s1 = {"隱身","在線","忙碌"};
                  cmb.addItem(s1[0]);
                  cmb.addItem(s1[1]);
                  cmb.addItem(s1[2]);
                 
                  chk.setText("自動登錄");
                 
                  paneMid.add(lblName);
                  paneMid.add(txtName);
                  paneMid.add(lblApply);
                 
                  paneMid.add(lblPwd);
                  paneMid.add(txtPwd);
                  paneMid.add(lblForget);
                 
                  paneMid.add(lblModel);
                  paneMid.add(cmb);
                  paneMid.add(chk);
                 
                  paneBut.add(btnKill);
                  paneBut.add(btnSet);
                  paneBut.add(btnLogin);
                 
                  contentPane = this.getContentPane();
                 
                  contentPane.add(paneTop,BorderLayout.NORTH);
                  contentPane.add(paneMid,BorderLayout.CENTER);
                  contentPane.add(paneBut,BorderLayout.SOUTH);
                 
                 
                 
                  setTitle("歡迎使用QQ");
                  setSize(330,240);
                  Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
                  setLocation((screen.width - getSize().width)/2,(screen.height - getSize().height)/2 );
                  setVisible(true);
                  setResizable(false);
                  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
              }
             
              public static void main(String args[]){
                  Demo d = new Demo();
              }
             
          }


          posted @ 2008-04-18 21:42 礦礦 閱讀(5428) | 評論 (17)編輯 收藏
          Java語言中, abstract class 和在一個面向?qū)ο蟮南到y(tǒng)中,系統(tǒng)的各種功能是由許許多多的不同對象協(xié)作完成的。在這種情況下,各個對象內(nèi)部是如何實現(xiàn)自己的對系統(tǒng)設(shè)計人員來講就不那么重要了;而各個對象之間的協(xié)作關(guān)系則成為系統(tǒng)設(shè)計的關(guān)鍵。小到不同類之間的通信,大到各模塊之間的交互,在系統(tǒng)設(shè)計之初都是要著重考慮的,這也是系統(tǒng)設(shè)計的主要工作內(nèi)容。面向接口編程我想就是指按照這種思想來編程吧!實際上,在日常工作中,你已經(jīng)按照接口編程了,只不過如果你沒有這方面的意識,那么你只是在被動的實現(xiàn)這一思想;表現(xiàn)在頻繁的抱怨別人改的代碼影響了你(接口沒有設(shè)計到),表現(xiàn)在某個模塊的改動引起其他模塊的大規(guī)模調(diào)整(模塊接口沒有很好的設(shè)計)等等。

            Booch先生那天談到Interaction Designer,它就是指做這類設(shè)計的人,只不過層次更高一些。我想目前我們的軟件設(shè)計隊伍中,這類人是最缺乏的人才之一。

            非接口編程?是不是就是面向過程的編程思想?

            1.關(guān)于接口的理解。

            接口從更深層次的理解,應(yīng)是定義(規(guī)范,約束)與實現(xiàn)(名實分離的原則)的分離。

            我們在一般實現(xiàn)一個系統(tǒng)的時候,通常是將定義與實現(xiàn)合為一體,不加分離的,我認(rèn)為最為理解的系統(tǒng)設(shè)計規(guī)范應(yīng)是所有的定義與實現(xiàn)分離,盡管這可能對系統(tǒng)中的某些情況有點繁煩。

            接口的本身反映了系統(tǒng)設(shè)計人員對系統(tǒng)的抽象理解。

            接口應(yīng)有兩類:第一類是對一個體的抽象,它可對應(yīng)為一個抽象體(abstract class);

            第二類是對一個體某一方面的抽象,即形成一個抽象面(interface);

            一個體有可能有多個抽象面。

            抽象體與抽象面是有區(qū)別的。

            2.設(shè)計接口的另一個不可忽視的因素是接口所處的環(huán)境(context,environment),系統(tǒng)論的觀點:環(huán)境是系統(tǒng)要素所處的空間與外部影響因素的總和。任何接口都是在一定的環(huán)境中產(chǎn)生的。因此環(huán)境的定義及環(huán)境的變化對接口的影響是不容忽視的,脫離原先的環(huán)境,所有的接口將失去原有的意義。

            3.按照組件的開發(fā)模型(3C),它們?nèi)呦噍o相成,各司一面,渾然一體,缺一不可。

            面向?qū)ο笫侵福覀兛紤]問題時,以對象為單位,考慮它的屬性及方法

            面向過程是指,我們考慮問題時,以一個具體的流程(事務(wù)過程)為單位,考慮它的實現(xiàn)

            接口設(shè)計與非接口設(shè)計是針對復(fù)用技術(shù)而言的,與面向?qū)ο?過程)不是一個問題

            我認(rèn)為:UML里面所說的interface是協(xié)議的另一種說法。并不是指com的interface,CORBA的interface,Java的interface,Delphi的interface,人機界面的interface或NIC的interface。

            在具體實現(xiàn)中,是可以把UML的interface實現(xiàn)為語言的interface,分布式對象環(huán)境的interface或其它什么interface,但就理解UML的interface而言,指的是系統(tǒng)每部分的實現(xiàn)和實現(xiàn)之間,通過interface所確定的協(xié)議來共同工作。

            所以我認(rèn)為,面向interface編程,原意是指面向抽象協(xié)議編程,實現(xiàn)者在實現(xiàn)時要嚴(yán)格按協(xié)議來辦。也就是Bill Joy同志說的,一邊翻rfc,一邊寫代碼的意思。面向?qū)ο缶幊淌侵该嫦虺橄蠛途呦蟆3橄蠛途呦笫敲艿慕y(tǒng)一體,不可能只有抽象沒有具象。一般懂得抽象的人都明白這個道理。 但有的人只知具象卻不知抽象為何物。

            所以只有interface沒有實現(xiàn),或只有實現(xiàn)而沒有interface者是沒有用的,反OO的。

            所以還是老老實實面向?qū)ο缶幊蹋嫦騾f(xié)議編程,或者什么都不面向,老老實實編程。

          是支持抽象類定義的兩種機制。正是由于這兩種機制的存在,才賦予了Java強大的 面向?qū)ο竽芰Αbstract class和interface之間在對于抽象類定義的支持方面具有很大的相似性,甚至可以相互替換,因此很多開發(fā)者在進(jìn) 行抽象類定義時對于abstract class和interface的選擇顯得比較隨意。其實,兩者之間還是有很大的區(qū)別的,對于它們的選擇甚至反映出對 于問題領(lǐng)域本質(zhì)的理解、對于設(shè)計意圖的理解是否正確、合理。本文將對它們之間的區(qū)別進(jìn)行一番剖析,試圖給開發(fā)者提供一個在二者之間進(jìn)行選擇的依據(jù)。

            理解抽象類

            abstract class和interface在Java語言中都是用來進(jìn)行抽象類(本文 中的抽象類并非從abstract class翻譯而來,它表示的是一個抽象體,而abstract class為Java語言中用于定義抽象類的一種方法, 請讀者注意區(qū)分)定義的,那么什么是抽象類,使用抽象類能為我們帶來什么好處呢?

            在 面向?qū)ο蟮母拍钪校覀冎浪械膶ο蠖际峭ㄟ^類來描繪的,但是反過來卻不是這樣。并不是 所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。抽象類往往用來表征我們在對問題領(lǐng)域進(jìn)行分析、 設(shè)計中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。比如:如果我們進(jìn)行一個圖形編輯軟件的開發(fā),就會發(fā)現(xiàn)問題領(lǐng)域存在著圓、 三角形這樣一些具體概念,它們是不同的,但是它們又都屬于形狀這樣一個概念,形狀這個概念在問題領(lǐng)域是不存在的,它就是一個抽象概念。正是因為抽象的概念 在問題領(lǐng)域沒有對應(yīng)的具體概念,所以用以表征抽象概念的抽象類是不能夠?qū)嵗摹?br />
            在面向?qū)ο箢I(lǐng)域,抽象類主要用來進(jìn)行類型隱藏。 我們可以構(gòu)造出一個固定的一組行為的抽象描 述,但是這組行為卻能夠有任意個可能的具體實現(xiàn)方式。這個抽象描述就是抽象類,而這一組任意個可能的具體實現(xiàn)則表現(xiàn)為所有可能的派生類。模塊可以操作一個 抽象體。由于模塊依賴于一個固定的抽象體,因此它可以是不允許修改的;同時,通過從這個抽象體派生,也可擴(kuò)展此模塊的行為功能。熟悉OCP的讀者一定知 道,為了能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計的一個最核心的原則OCP(Open-Closed Principle),抽象類是其中的關(guān)鍵所在。

            從語法定義層面看abstract class 和 interface

            在語法層面,Java語言對于abstract class和interface給出了不同的定義方式,下面以定義一個名為Demo的抽象類為例來說明這種不同。

            使用abstract class的方式定義Demo抽象類的方式如下:

          abstract class Demo{
          abstract void method1();
          abstract void method2();


            使用interface的方式定義Demo抽象類的方式如下:

          interface Demo{
          void method1();
          void method2();

          }

            在abstract class方式中,Demo可以有自己的數(shù)據(jù)成員,也可以有非 abstract的成員方法,而在interface方式的實現(xiàn)中,Demo只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員(也就是必須是static final 的,不過在interface中一般不定義數(shù)據(jù)成員),所有的成員方法都是abstract的。從某種意義上說,interface是一種特殊形式的 abstract class。

            從編程的角度來看,abstract class和interface都可以用來實現(xiàn) "design by contract" 的思想。但是在具體的使用上面還是有一些區(qū)別的。

            首先,abstract class 在 Java 語言中表示的是一種繼承關(guān)系,一個類只能使用一次繼承關(guān)系(因為Java不支持多繼承 -- 轉(zhuǎn)注)。但是,一個類卻可以實現(xiàn)多個interface。也許,這是Java語言的設(shè)計者在考慮Java對于多重繼承的支持方面的一種折中考慮吧。

            其次,在abstract class的定義中,我們可以賦予方法的默認(rèn)行為。但是在interface的定義中,方法卻不能擁有默認(rèn)行為,為了繞過這個限制,必須使用委托,但是這會增加一些復(fù)雜性,有時會造成很大的麻煩。

            在 抽象類中不能定義默認(rèn)行為還存在另一個比較嚴(yán)重的問題,那就是可能會造成維護(hù)上的麻煩。因 為如果后來想修改類的界面(一般通過 abstract class 或者interface來表示)以適應(yīng)新的情況(比如,添加新的方法或者給已用的方法中添 加新的參數(shù))時,就會非常的麻煩,可能要花費很多的時間(對于派生類很多的情況,尤為如此)。但是如果界面是通過abstract class來實現(xiàn)的,那 么可能就只需要修改定義在abstract class中的默認(rèn)行為就可以了。

            同樣,如果不能在抽象類中定義默認(rèn)行為,就會導(dǎo)致同樣的方法實現(xiàn)出現(xiàn)在該抽象類的每一個派生類中,違反了 "one rule,one place" 原則,造成代碼重復(fù),同樣不利于以后的維護(hù)。因此,在abstract class和interface間進(jìn)行選擇時要非常的小心。

            從設(shè)計理念層面看 abstract class 和 interface

            上面主要從語法定義和編程的角度論述了abstract class和interface的區(qū) 別,這些層面的區(qū)別是比較低層次的、非本質(zhì)的。本小節(jié)將從另一個層面:abstract class和interface所反映出的設(shè)計理念,來分析一下二者的區(qū)別。作者認(rèn)為,從這個層面進(jìn)行分析才能理解二者概念的本質(zhì)所在。

            前面已經(jīng)提到過,abstract class在Java語言中體現(xiàn)了一種繼承關(guān)系,要想使得 繼承關(guān)系合理,父類和派生類之間必須存在"is-a"關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對于interface來說則不然,并不要求interface的實現(xiàn)者和interface定義在概念本質(zhì)上是一致的, 僅僅是實現(xiàn)了interface定義的契約而已。為了使論述便于理解,下面將通過一個簡單的實例進(jìn)行說明。

            考慮這樣一個例子,假設(shè)在我們的問題領(lǐng)域中有一個關(guān)于Door的抽象概念,該Door具有執(zhí)行兩個動作open和close,此時我們可以通過abstract class或者interface來定義一個表示該抽象概念的類型,定義方式分別如下所示:

            使用abstract class方式定義Door:

          abstract class Door{
          abstract void open();
          abstract void close();
          }

            使用interface方式定義Door:

          interface Door{
          void open();
          void close();
          }

            其他具體的Door類型可以extends使用abstract class方式定義的Door或者implements使用interface方式定義的Door。看起來好像使用abstract class和interface沒有大的區(qū)別。

            如果現(xiàn)在要求Door還要具有報警的功能。我們該如何設(shè)計針對該例子的類結(jié)構(gòu)呢(在本例中, 主要是為了展示 abstract class 和interface 反映在設(shè)計理念上的區(qū)別,其他方面無關(guān)的問題都做了簡化或者忽略)?下面將羅列出可能的解 決方案,并從設(shè)計理念層面對這些不同的方案進(jìn)行分析。

            解決方案一:

            簡單的在Door的定義中增加一個alarm方法,如下:

          abstract class Door{
          abstract void open();
          abstract void close();
          abstract void alarm();
          }

            或者

          interface Door{
          void open();
          void close();
          void alarm();
          }

            那么具有報警功能的AlarmDoor的定義方式如下:

          class AlarmDoor extends Door{
          void open(){…}
          void close(){…}
          void alarm(){…}
          }

            或者

          class AlarmDoor implements Door{
          void open(){…}
          void close(){…}
          void alarm(){…}

            這種方法違反了面向?qū)ο笤O(shè)計中的一個核心原則 ISP (Interface Segregation Principle),在Door的定義中把Door概念本身固有的行為方法和另外一個概念"報警器"的行為方 法混在了一起。這樣引起的一個問題是那些僅僅依賴于Door這個概念的模塊會因為"報警器"這個概念的改變(比如:修改alarm方法的參數(shù))而改變,反 之依然。

            解決方案二:

            既然open、close和alarm屬于兩個不同的概念,根據(jù)ISP原則應(yīng)該把它們分別定 義在代表這兩個概念的抽象類中。定義方式有:這兩個概念都使用 abstract class 方式定義;兩個概念都使用interface方式定義;一個概念 使用 abstract class 方式定義,另一個概念使用interface方式定義。

            顯然,由于Java語言不支持多重繼承,所以兩個概念都使用abstract class方式定義是不可行的。后面兩種方式都是可行的,但是對于它們的選擇卻反映出對于問題領(lǐng)域中的概念本質(zhì)的理解、對于設(shè)計意圖的反映是否正確、合理。我們一一來分析、說明。

            如果兩個概念都使用interface方式來定義,那么就反映出兩個問題:1、我們可能沒有 理解清楚問題領(lǐng)域,AlarmDoor在概念本質(zhì)上到底是Door還是報警器?2、如果我們對于問題領(lǐng)域的理解沒有問題,比如:我們通過對于問題領(lǐng)域的分 析發(fā)現(xiàn)AlarmDoor在概念本質(zhì)上和Door是一致的,那么我們在實現(xiàn)時就沒有能夠正確的揭示我們的設(shè)計意圖,因為在這兩個概念的定義上(均使用 interface方式定義)反映不出上述含義。

            如果我們對于問題領(lǐng)域的理解是:AlarmDoor在概念本質(zhì)上是Door,同時它有具有報 警的功能。我們該如何來設(shè)計、實現(xiàn)來明確的反映出我們的意思呢?前面已經(jīng)說過,abstract class在Java語言中表示一種繼承關(guān)系,而繼承關(guān)系 在本質(zhì)上是"is-a"關(guān)系。所以對于Door這個概念,我們應(yīng)該使用abstarct class方式來定義。另外,AlarmDoor又具有報警功能,說 明它又能夠完成報警概念中定義的行為,所以報警概念可以通過interface方式定義。如下所示:

          abstract class Door{
          abstract void open();
          abstract void close();
          }
          interface Alarm{
          void alarm();
          }
          class Alarm Door extends Door implements Alarm{
          void open(){…}
          void close(){…}
          void alarm(){…}
          }

            這種實現(xiàn)方式基本上能夠明確的反映出我們對于問題領(lǐng)域的理解,正確的揭示我們的設(shè)計意圖。其 實abstract class表示的是"is-a"關(guān)系,interface表示的是"like-a"關(guān)系,大家在選擇時可以作為一個依據(jù),當(dāng)然這是建立在對問題領(lǐng)域的理解上的,比如:如果我們認(rèn)為AlarmDoor在概念本質(zhì)上是報警器,同時又具有Door的功能,那么上述的定義方式就要反過來了。

            小結(jié)

            1.abstract class 在 Java 語言中表示的是一種繼承關(guān)系,一個類只能使用一次繼承關(guān)系。但是,一個類卻可以實現(xiàn)多個interface。

            2.在abstract class 中可以有自己的數(shù)據(jù)成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員(也就是必須是static final的,不過在 interface中一般不定義數(shù)據(jù)成員),所有的成員方法都是abstract的。

            3.abstract class和interface所反映出的設(shè)計理念不同。其實abstract class表示的是"is-a"關(guān)系,interface表示的是"like-a"關(guān)系。

            4.實現(xiàn)抽象類和接口的類必須實現(xiàn)其中的所有方法。抽象類中可以有非抽象方法。接口中則不能有實現(xiàn)方法。

            5.接口中定義的變量默認(rèn)是public static final 型,且必須給其初值,所以實現(xiàn)類中不能重新定義,也不能改變其值。

            6.抽象類中的變量默認(rèn)是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。

            7.接口中的方法默認(rèn)都是 public,abstract 類型的。

            結(jié)論

            abstract class 和 interface 是 Java語言中的兩種定義抽象類的方式,它們之間有很大的相似性。但是對于它們的選擇卻又往往反映出對于問題領(lǐng)域中的概 念本質(zhì)的理解、對于設(shè)計意圖的反映是否正確、合理,因為它們表現(xiàn)了概念間的不同的關(guān)系(雖然都能夠?qū)崿F(xiàn)需求的功能)。這其實也是語言的一種的慣用法,希望讀者朋友能夠細(xì)細(xì)體會。
          jack jones/杰克瓊斯/馬克華菲
          posted @ 2008-04-08 15:14 礦礦 閱讀(717) | 評論 (0)編輯 收藏
          在一個面向?qū)ο蟮南到y(tǒng)中,系統(tǒng)的各種功能是由許許多多的不同對象協(xié)作完成的。在這種情況下,各個對象內(nèi)部是如何實現(xiàn)自己的對系統(tǒng)設(shè)計人員來講就不那么重要了;而各個對象之間的協(xié)作關(guān)系則成為系統(tǒng)設(shè)計的關(guān)鍵。小到不同類之間的通信,大到各模塊之間的交互,在系統(tǒng)設(shè)計之初都是要著重考慮的,這也是系統(tǒng)設(shè)計的主要工作內(nèi)容。面向接口編程我想就是指按照這種思想來編程吧!實際上,在日常工作中,你已經(jīng)按照接口編程了,只不過如果你沒有這方面的意識,那么你只是在被動的實現(xiàn)這一思想;表現(xiàn)在頻繁的抱怨別人改的代碼影響了你(接口沒有設(shè)計到),表現(xiàn)在某個模塊的改動引起其他模塊的大規(guī)模調(diào)整(模塊接口沒有很好的設(shè)計)等等。

            Booch先生那天談到Interaction Designer,它就是指做這類設(shè)計的人,只不過層次更高一些。我想目前我們的軟件設(shè)計隊伍中,這類人是最缺乏的人才之一。

            非接口編程?是不是就是面向過程的編程思想?

            1.關(guān)于接口的理解。

            接口從更深層次的理解,應(yīng)是定義(規(guī)范,約束)與實現(xiàn)(名實分離的原則)的分離。

            我們在一般實現(xiàn)一個系統(tǒng)的時候,通常是將定義與實現(xiàn)合為一體,不加分離的,我認(rèn)為最為理解的系統(tǒng)設(shè)計規(guī)范應(yīng)是所有的定義與實現(xiàn)分離,盡管這可能對系統(tǒng)中的某些情況有點繁煩。

            接口的本身反映了系統(tǒng)設(shè)計人員對系統(tǒng)的抽象理解。

            接口應(yīng)有兩類:第一類是對一個體的抽象,它可對應(yīng)為一個抽象體(abstract class);

            第二類是對一個體某一方面的抽象,即形成一個抽象面(interface);

            一個體有可能有多個抽象面。

            抽象體與抽象面是有區(qū)別的。

            2.設(shè)計接口的另一個不可忽視的因素是接口所處的環(huán)境(context,environment),系統(tǒng)論的觀點:環(huán)境是系統(tǒng)要素所處的空間與外部影響因素的總和。任何接口都是在一定的環(huán)境中產(chǎn)生的。因此環(huán)境的定義及環(huán)境的變化對接口的影響是不容忽視的,脫離原先的環(huán)境,所有的接口將失去原有的意義。

            3.按照組件的開發(fā)模型(3C),它們?nèi)呦噍o相成,各司一面,渾然一體,缺一不可。

            面向?qū)ο笫侵福覀兛紤]問題時,以對象為單位,考慮它的屬性及方法

            面向過程是指,我們考慮問題時,以一個具體的流程(事務(wù)過程)為單位,考慮它的實現(xiàn)

            接口設(shè)計與非接口設(shè)計是針對復(fù)用技術(shù)而言的,與面向?qū)ο?過程)不是一個問題

            我認(rèn)為:UML里面所說的interface是協(xié)議的另一種說法。并不是指com的interface,CORBA的interface,Java的interface,Delphi的interface,人機界面的interface或NIC的interface。

            在具體實現(xiàn)中,是可以把UML的interface實現(xiàn)為語言的interface,分布式對象環(huán)境的interface或其它什么interface,但就理解UML的interface而言,指的是系統(tǒng)每部分的實現(xiàn)和實現(xiàn)之間,通過interface所確定的協(xié)議來共同工作。

            所以我認(rèn)為,面向interface編程,原意是指面向抽象協(xié)議編程,實現(xiàn)者在實現(xiàn)時要嚴(yán)格按協(xié)議來辦。也就是Bill Joy同志說的,一邊翻rfc,一邊寫代碼的意思。面向?qū)ο缶幊淌侵该嫦虺橄蠛途呦蟆3橄蠛途呦笫敲艿慕y(tǒng)一體,不可能只有抽象沒有具象。一般懂得抽象的人都明白這個道理。 但有的人只知具象卻不知抽象為何物。

            所以只有interface沒有實現(xiàn),或只有實現(xiàn)而沒有interface者是沒有用的,反OO的。

            所以還是老老實實面向?qū)ο缶幊蹋嫦騾f(xié)議編程,或者什么都不面向,老老實實編程。

          posted @ 2008-04-08 15:07 礦礦 閱讀(207) | 評論 (0)編輯 收藏
          一.誰在做Garbage Collection?

            一種流行的說法:在C++里,是系統(tǒng)在做垃圾回收;而在Java里,是Java自身在做。

            在C++里,釋放內(nèi)存是手動處理的,要用delete運算符來釋放分配的內(nèi)存。這是流行的說法。確切地說,是應(yīng)用認(rèn)為不需要某實體時,就需用delete告訴系統(tǒng),可以回收這塊空間了。這個要求,對編碼者來說,是件很麻煩、很難做到的事。隨便上哪個BBS,在C/C++版塊里總是有一大堆關(guān)于內(nèi)存泄漏的話題。

            Java采用一種不同的,很方便的方法:Garbage Collection。垃圾回收機制放在JVM里。JVM完全負(fù)責(zé)垃圾回收事宜,應(yīng)用只在需要時申請空間,而在拋棄對象時不必關(guān)心空間回收問題。

            二.對象在啥時被丟棄?

            在C++里,當(dāng)對象離開其作用域時,該對象即被應(yīng)用拋棄。

            是對象的生命期不再與其作用域有關(guān),而僅僅與引用有關(guān)。

            Java的垃圾回收機制一般包含近十種算法。對這些算法中的多數(shù),我們不必予以關(guān)心。只有其中最簡單的一個:引用計數(shù)法,與編碼有關(guān)。

            一個對象,可以有一個或多個引用變量指向它。當(dāng)一個對象不再有任何一個引用變量指向它時,這個對象就被應(yīng)用拋棄了。或者說,這個對象可以被垃圾回收機制回收了。

            這就是說,當(dāng)不存在對某對象的任何引用時,就意味著,應(yīng)用告訴JVM:我不要這個對象,你可以回收了。

            JVM的垃圾回收機制對堆空間做實時檢測。當(dāng)發(fā)現(xiàn)某對象的引用計數(shù)為0時,就將該對象列入待回收列表中。但是,并不是馬上予以銷毀。

            三.丟棄就被回收?

            該對象被認(rèn)定為沒有存在的必要了,那么它所占用的內(nèi)存就可以被釋放。被回收的內(nèi)存可以用于后續(xù)的再分配。

            但是,并不是對象被拋棄后當(dāng)即被回收的。JVM進(jìn)程做空間回收有較大的系統(tǒng)開銷。如果每當(dāng)某應(yīng)用進(jìn)程丟棄一個對象,就立即回收它的空間,勢必會使整個系統(tǒng)的運轉(zhuǎn)效率非常低下。

            前面說過,JVM的垃圾回收機制有多個算法。除了引用計數(shù)法是用來判斷對象是否已被拋棄外,其它算法是用來確定何時及如何做回收。JVM的垃圾回收機制要在時間和空間之間做個平衡。

            因此,為了提高系統(tǒng)效率,垃圾回收器通常只在滿足兩個條件時才運行:即有對象要回收且系統(tǒng)需要回收。切記垃圾回收要占用時間,因此,Java運行時系統(tǒng)只在需要的時候才使用它。因此你無法知道垃圾回收發(fā)生的精確時間。

            四.沒有引用變量指向的對象有用嗎?

            前面說了,沒掛上引用變量的對象是被應(yīng)用丟棄的,這意味著,它在堆空間里是個垃圾,隨時可能被JVM回收。

            不過,這里有個不是例外的例外。對于一次性使用的對象(有些書稱之為臨時對象),可以不用引用變量指向它。舉個最簡單也最常見的例子:

            System.out.println(“I am Java!”);

            就是創(chuàng)建了一個字符串對象后,直接傳遞給println()方法。

            五.應(yīng)用能干預(yù)垃圾回收嗎?

            許多人對Java的垃圾回收不放心,希望在應(yīng)用代碼里控制JVM的垃圾回收運作。這是不可能的事。對垃圾回收機制來說,應(yīng)用只有兩個途徑發(fā)消息給JVM。第一個前面已經(jīng)說了,就是將指向某對象的所有引用變量全部移走。這就相當(dāng)于向JVM發(fā)了一個消息:這個對象不要了。第二個是調(diào)用庫方法System.gc(),多數(shù)書里說調(diào)用它讓Java做垃圾回收。

            第一個是一個告知,而調(diào)用System.gc()也僅僅是一個請求。JVM接受這個消息后,并不是立即做垃圾回收,而只是對幾個垃圾回收算法做了加權(quán),使垃圾回收操作容易發(fā)生,或提早發(fā)生,或回收較多而已。

            希望JVM及時回收垃圾,是一種需求。其實,還有相反的一種需要:在某段時間內(nèi)最好不要回收垃圾。要求運行速度最快的實時系統(tǒng),特別是嵌入式系統(tǒng),往往希望如此。

            Java的垃圾回收機制是為所有Java應(yīng)用進(jìn)程服務(wù)的,而不是為某個特定的進(jìn)程服務(wù)的。因此,任何一個進(jìn)程都不能命令垃圾回收機制做什么、怎么做或做多少。

            六.對象被回收時要做的事

            一個對象在運行時,可能會有一些東西與其關(guān)連。因此,當(dāng)對象即將被銷毀時,有時需要做一些善后工作。可以把這些操作寫在finalize()方法(常稱之為終止器)里。

            protected void finalize()

            {

            // finalization code here

            }

            這個終止器的用途類似于C++里的析構(gòu)函數(shù),而且都是自動調(diào)用的。但是,兩者的調(diào)用時機不一樣,使兩者的表現(xiàn)行為有重大區(qū)別。C++的析構(gòu)函數(shù)總是當(dāng)對象離開作用域時被調(diào)用。這就是說,C++析構(gòu)函數(shù)的調(diào)用時機是確定的,且是可被應(yīng)用判知的。但是,Java終止器卻是在對象被銷毀時。由上所知,被丟棄的對象何時被銷毀,應(yīng)用是無法獲知的。而且,對于大多數(shù)場合,被丟棄對象在應(yīng)用終止后仍未銷毀。

            在編碼時,考慮到這一點。譬如,某對象在運作時打開了某個文件,在對象被丟棄時不關(guān)閉它,而是把文件關(guān)閉語句寫在終止器里。這樣做對文件操作會造成問題。如果文件是獨占打開的,則其它對象將無法訪問這個文件。如果文件是共享打開的,則另一訪問該文件的對象直至應(yīng)用終結(jié)仍不能讀到被丟棄對象寫入該文件的新內(nèi)容。

            至少對于文件操作,編碼者應(yīng)認(rèn)清Java終止器與C++析構(gòu)函數(shù)之間的差異。

            那么,當(dāng)應(yīng)用終止,會不會執(zhí)行應(yīng)用中的所有finalize()呢?據(jù)Bruce Eckel在Thinking in Java里的觀點:“到程序結(jié)束的時候,并非所有收尾模塊都會得到調(diào)用”。這還僅僅是指應(yīng)用正常終止的場合,非正常終止呢?

            因此,哪些收尾操作可以放在finalize()里,是需要酌酎的。

          posted @ 2008-04-08 14:55 礦礦 閱讀(306) | 評論 (0)編輯 收藏
          重要知識點總結(jié)如下:

            1,抽象,封裝,繼承,多態(tài)是面向?qū)ο蟪绦蛟O(shè)計中得四個特點.

            2,面向?qū)ο蟮密浖_發(fā)大體分為:面向?qū)ο蟮姆治觯嫦驅(qū)ο蟮脑O(shè)計,面向?qū)ο蟮膶崿F(xiàn).

            可概括為如下過程:分析用戶需求,從問題中抽取對象模型;細(xì)化模型,設(shè)計類,包括類的屬性和類間的

            相互關(guān)系,同時觀察是否有可以直接引用的已有類或部件;選定一種面向?qū)ο蟮木幊陶Z言,具體編碼實現(xiàn)

            上一階段類的設(shè)計,并在開發(fā)過程中引入測試,完善整個解決方案.

            3,面向?qū)ο蟪绦蛟O(shè)計方法的優(yōu)點是:可重用性,可擴(kuò)展性,可管理性.

            4,類的定義:class前的修飾符分為訪問控制符和非訪問控制符兩大類.訪問控制符包括public和private.

            非訪問控制符包括abstract(抽象),final(最終).

            5,final類是最終類,是不能有子類的類.abstract和final不能同時修飾一個類,因為抽象類本身沒有具體對象,

            需要派生出子類后在創(chuàng)建子類的對象.而最終類不可能有子類.

            6,創(chuàng)建對象的格式為: 類名 對象名=new 構(gòu)造方法(參數(shù));注意前面是類名后面是構(gòu)造方法.

            注意構(gòu)造方法沒有返回類型,也不能寫void,主要用于完成類對象的初始化工作,一般不能直接由編程

            直接調(diào)用,而是用new運算符來調(diào)用.

            7,如果class前面由public修飾符,則默認(rèn)構(gòu)造方法的前面也應(yīng)該有public修飾符.

            8,類中有static修飾的域或方法,可用類名或?qū)ο竺L問,否則只能用對象名訪問.

            9,修飾域的訪問控制符可以是:public,private,protected,private protected.非訪問控制符可以是:

            static,final,volatile(易失域)

            10,類變量的最本質(zhì)的特點是:他們是類的域,不屬于任何一個類的具體對象實例.不是保存在某個對象實例的內(nèi)存空間中,而是保存在類的內(nèi)存區(qū)域的公共存儲單元中.

                  11,局部變量是在方法體內(nèi)聲明的,只有當(dāng)方法被調(diào)用時他們才存在,因而只能在本方法內(nèi)使用,不存在訪問控制符,也不能聲明為靜態(tài)變量(static),但可以聲明為final變量.局部變量必須初始化.

            12,修飾方法的訪問控制符可以是:public,private,protected,private protected,修飾方法的非訪問控制符可以是:static,final,abstract,native(本地方法),synchronized(同步方法)。

            13,用static修飾的變量或方法都為類成員,類成員可以用類名或?qū)嵗L問,實例成員只能用實例名來訪問。

            14,如果一個類中含有抽象方法,則此類必須為抽象類,如果抽象類的子類不為抽象類,則子類必須實現(xiàn)父類的所有抽象方法。抽象方法不能用靜態(tài)方法和最終方法。抽想方法只有函數(shù)頭的聲明,而用分號來替代方法體,沒有大括號。如abstract void abstractmethod();

            15,this變量用在一個方法的內(nèi)部,指向當(dāng)前對象,當(dāng)前對象指的是調(diào)用當(dāng)前正在執(zhí)行的方法的那個對象。super變量是直接指向父類的構(gòu)造方法,用來引用父類種的變量和方法。(由于他們指的是對象,所以不能通過它來引用類變量和類方法)

            16,如果要引用一個包中的多個類,可以用星號來代替。使用星號只能表示本層次的所有類,而不包括子層次下的類。所以經(jīng)常需要用兩條語句來引入兩個層次的類:import java.awt.*;import java.awt.event.*;

            17,訪問修飾符:

            --類中限定為public的成員可以被所有的類訪問。

            --類中先定位private的成員只能被這個類本身訪問。同一個類的不同對象可以訪問對方的private域變量或調(diào)用對方的域方法,這是因為訪問保護(hù)控制在類的級別上,而不是對象的級別上。

            --類中限定為protected的成員可以被這個類本身,它的子類(包括同一個包中和不同包中的子類),以及同一個包中的其他類訪問。

            --用private protected修飾的成員可以被該類本身訪問,也可以被該類的所有子類訪問。

            --默認(rèn)訪問控制符規(guī)定只能被同一個包中的類訪問和引用,而不能被其他包的類訪問。即他的訪問權(quán)限是friendly。

            18,注意:

            ----abstract和private,static,final,native不能并列修飾同一個方法。

            ----abstract類中不能有private修飾的域和方法

            ----static方法不能處理非static的域。

            19,重載方法的參數(shù)必須不同,或者是參數(shù)個數(shù)不同,或者是參數(shù)類型不同。重載的多個方法必須返回相同的數(shù)據(jù)類型。

            20,在java中,一個類獲取某一接口定義的功能并不是通過直接繼承這個接口的屬性和方法來實現(xiàn)的。因為接口中的屬性都是常量,接口的方法都是沒有方法體的抽象方法,沒有具體定義操作。

          posted @ 2008-04-08 14:42 礦礦 閱讀(2415) | 評論 (0)編輯 收藏
          不走彎路,就是捷徑

          可以這么說吧,學(xué)習(xí)JAVA沒有什么捷徑,學(xué)習(xí)什么語言都沒有什么捷徑

          最好的方法就是,多看書,多寫代碼,多思考

          沒有程序基礎(chǔ)沒有關(guān)系,成事開頭難,我相信你會學(xué)好的,加油吧!

          對于風(fēng)接觸JAVA的人,可以按照下面的路線開始學(xué)(僅供參考)

          基本數(shù)據(jù)類型-操作符-流程控制語句(這些是所有編程語言的基礎(chǔ))

          然后上面這些掌握了之后,看面向?qū)ο螅ㄟ@個是重點)

          在這個過程中可以先搞明白public,private,protected,static等關(guān)鍵詞的用法,什么時候用,什么時候不用,這些對于你以后的學(xué)習(xí)很有幫助

          然后就是仔細(xì)研究面向?qū)ο罅耍@個是重點 !

          當(dāng)上面這些你都搞明白后,就不用我說了,你自己就會有一定的自學(xué)的經(jīng)驗了,就知道自己該看什么,不看什么了

          推薦兩本書

          java2 核心技術(shù)卷(基礎(chǔ)篇)、java編程思想(也就是Thinking in java) 后者在你有了一定的基礎(chǔ)后再看,不然不容易明白的
          posted @ 2008-04-02 22:36 礦礦 閱讀(136) | 評論 (0)編輯 收藏

          1.public class Calculator{
           static int sum=0;
           static void add(int a,int b){
           // int sum=0;
            sum =a+b;
            System.out.println (sum);
           }
           static void sub(int a,int b){
              //int sum=0;
            sum=a-b;
            System.out.println (sum);
           }
           static void mul(int a,int b){
           // int sum=0;
            sum=a*b;
            System.out.println (sum);
           }
           static void div(int a,int b){
           // int sum=0;
            sum=a/b;
            System.out.println (sum);
           }
           public static void main(String[] args){
            add(1,2);
            sub(2,1);
            mul(1,2);
            div(2,1);
           }
          }


          2.public class Polygon{
           void printRec(int height,int width){
            for(int a=0;a<=height;a++){
             for(int j=0;j<=width;j++){
             System.out.print ("*");
             }
             System.out.println ();
            } 
           }
           void printTri(int height){
            for(int a=0;a<=height;a++){
             for(int j=a;j<height;j++){
              System.out.print("*");
             }
             System.out.println ();
            }
           }
            public static void main(String[] args){
             Polygon p=new Polygon();
             p.printRec(5,4);
             System.out.println ();
             p.printTri(5);
            }
          }


          3.public class Worker{
           String name;
           int price;
           int num;
           String place;
           Worker(String name,int price,int num,String place){
            this.name=name;
            this.price=price;
            this.num=num;
            this.place=place; 
           }
           void dispaly(){
            System.out.println ("姓名:"+name);
            System.out.println ("工資:"+price);
            System.out.println ("工號:"+num);
            System.out.println ("工作地:"+place);
           }
           

           public static void main(String[] args){
            Worker w=new Worker("DK",1000,99,"wuhan");
            w.dispaly();
           
           }
          }

           

           

          4.public class Compare{
           int num1,num2,num3;
           void max(){
            if(num1>num2){
             if(num1>num3){
              System.out.println (num1);
             }else{
              System.out.println (num3);
             }
            }else{
             if(num2>num3){
              System.out.println (num2);
             }else{
              System.out.println (num3);
             }
            }
           }
           void min(){
            if(num1>num2){
             if(num2>num3){
              System.out.println (num3);
             }else{
              System.out.println (num2);
             }
            }else{
             if(num1>num3){
              System.out.println (num3);
             }else{
              System.out.println (num1);
             }
            }
           }
           void avg(){
           
             System.out.println ((num1+num2+num3)/3);
           }
            public static void main(String[] args){
             Compare c=new Compare();
             c.num1=1;
             c.num2=2;
             c.num3=3;
             c.max();
             c.min();
             c.avg();
            }
          }

           

           

          5.public class User{
           String 用戶名;
           String 密碼;
           String 用戶權(quán)限;
           User(String name,String password,String quanxian){
            用戶名=name;
            密碼=password;
            用戶權(quán)限=quanxian;
           }
           void login(){
            if(用戶名=="admin"&&密碼=="123"){
             System.out.println ("登陸成功");
             System.out.println (用戶權(quán)限="administrator");
            }else{
             if(用戶名=="snake"&&密碼=="123456"){
              System.out.println ("登陸失敗");
              System.out.println (用戶權(quán)限="user");
             }
            }
           }
           public static void main(String[] args){
            User u= new User("snake","123456"," ");
            u.login();
           }
          }

           

           

          posted @ 2008-04-01 19:51 礦礦 閱讀(1437) | 評論 (7)編輯 收藏
          僅列出標(biāo)題
          共4頁: 上一頁 1 2 3 4 下一頁 
          主站蜘蛛池模板: 修武县| 呼伦贝尔市| 买车| 镇巴县| 宁波市| 黄龙县| 凯里市| 云林县| 乌什县| 武义县| 洪湖市| 察雅县| 井研县| 武定县| 石阡县| 镇康县| 新蔡县| 田林县| 慈利县| 三门县| 阜宁县| 南投县| 南宁市| 霞浦县| 吕梁市| 米脂县| 浙江省| 新和县| 云霄县| 文水县| 宜阳县| 乌审旗| 清水县| 兴城市| 江口县| 思茅市| 古浪县| 永济市| 鄂托克前旗| 南部县| 上思县|