█
XML是eXtensible Markup Language的缩写。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。 
XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引、排序、查找、相关一致性等,XML仅仅是展示数据。事实上XML与其他数据表现形式最大的不同是:他极其简单。这是一个看上去有点琐细的优点,但正是这点使XML与众不同。 
XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其它的数据交换格式,但不久之后他们都将支持XML,那就意味着程序可以更容易的与Windows、Mac OS, Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。
XML的前身是
SGML(The Standard Generalized Markup Language),是自IBM从60年代就开始发展的
GML(Generalized Markup Language) 
同
HTML一样, XML (可扩展标识语言)是通用标识语言标准(SGML)的一个子集,它是描述网络上的数据内容和结构的标准。尽管如此,XML不象HTML,HTML仅仅提供了在页面上显示信息的通用方法(没有上下文相关和动态功能) ,XML则对数据赋予上下文相关功能,它继承了SGML的大部分功能,却使用了不太复杂的技术。. 
为了使得SGML显得用户友好,XML重新定义了SGML的一些内部值和参数,去掉了大量的很少用到的功能,这些繁杂的功能使得SGML在设计网站时显得复杂化。XML保留了SGML的结构化功能,这样就使得网站设计者可以定义自己的文档类型,XML同时也推出一种新型文档类型,使得开发者也可以不必定义文档类型。 
因为XML是W3C制定的,XML的标准化工作由W3C的XML工作组负责,该小组成员由来自各个地方和行业的专家组成,他们通过email交流对XML标准的意见,并提出自己的看法 (
www.w3.org/TR/WD-xml)。因为XML 是个公共格式, (它不专属于任何一家公司),你不必担心XML技术会成为少数公司的盈利工具,XML不是一个依附于特定浏览器的语言
XML(可扩展标记语言)是从称为SGML(标准通用标记语言)的更加古老的语言派生出来的。SGML的主要目的是定义使用标签来表示数据的标记语言的语法。
标签由包围在一个小于号(<)和一个大于号(>)之间的文本组成,例如<tag>。起始标签(start tag)表示一个特定区域的开始,例如<start>;结束标签(end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如</end>。SGML还定义了标签的特性(attribute),它们是定义在小于号和大于号之间的值,例如<img src="picture.jpg">中的src特性。如果你觉得它看起来很熟悉的话,应该知道,基于SGML的语言的最著名实现就是原始的HTML。
SGML常用来定义针对HTML的文档类型定义(DTD),同时它也常用于编写XML的DTD。SGML的问题就在于,它允许出现一些奇怪的语法,这让创建HTML的解析器成为一个大难题:
1  某些起始标签不允许出现结束标签,例如HTML中<img>标签。包含了结束标签就会出现错误。
2  某些起始标签可以选择性出现结束标签或者隐含了结束标签,例如HTML中<p>标签,当出现另一个<p>标签或者某些其他标签时,便假设在这之前有一个结束标签。
3  某些起始标签要求必须出现结束标签,例如HTML中<script>标签。
4  标签可以以任何顺序嵌套。即使结束标签不按照起始标签的逆序出现也是允许的,例如,<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语言的解析器变成了一项艰巨的任务。判断何时应用以上规则的困难导致了SGML语言的定义一直停滞不前。以这些问题作为出发点,XML逐渐步入我们的视野。
      XML去掉了之前令许多开发人员头疼的SGML的随意语法。在XML中,采用了如下的语法:
8  任何的起始标签都必须有一个结束标签。
9  可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<tag />。XML解析器会将其翻译成<tag></tag>。
10  标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如<b>this is a <i>sample</i> string</b>。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
11  所有的特性都必须有值。
12  所有的特性都必须在值的周围加上双引号。
这些规则使得开发一个XML解析器要简便得多,而且也除去了解析SGML中花在判断何时何地应用那些奇怪语法规则上的工作。仅仅在XML出现后的前六年就衍生出多种不同的语言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同时也将HTML改进为XHTML。
如果需要关于SGML和XML具体技术上的对比,请查看W3C的注解,位于:
http://www.w3. org/TR/NOTE-sgml-xml.html
如今,XML已经是世界上发展最快的技术之一。它的主要目的是使用文本以结构化的方式来表示数据。在某些方面,XML文件也类似于数据库,提供数据的结构化视图。这里是一个XML文件的例子:
每个XML文档都由XML序言开始,在前面的代码中的第一行便是XML序言,<?xml version="1.0"?>。这一行代码会告诉解析器和浏览器,这个文件应该按照前面讨论过的XML规则进行解析。第二行代码,<books>,则是文档元素(document element),它是文件中最外面的标签(我们认为元素(element)是起始标签和结束标签之间的内容)。所有其他的标签必须包含在这个标签之内来组成一个有效的XML文件。XML文件的第二行并不一定要包含文档元素;如果有注释或者其他内容,文档元素可以迟些出现。
范例文件中的第三行代码是注释,你会发现它与HTML中使用的注释风格是一样的。这是XML从SGML中继承的语法元素之一。
页面再往下的一些地方,可以发现<desc>标签里有一些特殊的语法。<![CDATA[ ]]>代码用于表示无需进行解析的文本,允许诸如大于号和小于号之类的特殊字符包含在文本中,而无需担心破坏XML的语法。文本必须出现在<![CDATA[和]]>之间才能合适地避免被解析。这样的文本称为Character Data Section,简称CData Section。
下面的一行就是在第二本书的定义之前的:
<?page render multiple authors ?>
虽然它看上去很像XML序言,但实际上是一种称为处理指令(processing instruction)的不同类型的语法。处理指令(以下简称PI)的目的是为了给处理页面的程序(例如XML解析器)提供额外的信息。PI通常情况下是没有固定格式的,唯一的要求是紧随第一个问号必须至少有一个字母。在此之后,PI可以包含除了小于号和大于号之外的任何字符串序列。
最常见的PI是用来指定XML文件的样式表:
这个PI一般会直接放在XML序言之后,通常由Web浏览器使用,来将XML数据以特殊的样式显示出来。
			
posted @ 
2008-05-06 14:09 矿矿 阅读(292) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			█
XML是eXtensible Markup Language的缩写。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。 
XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引、排序、查找、相关一致性等,XML仅仅是展示数据。事实上XML与其他数据表现形式最大的不同是:他极其简单。这是一个看上去有点琐细的优点,但正是这点使XML与众不同。 
XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其它的数据交换格式,但不久之后他们都将支持XML,那就意味着程序可以更容易的与Windows、Mac OS, Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。
XML的前身是
SGML(The Standard Generalized Markup Language),是自IBM从60年代就开始发展的
GML(Generalized Markup Language) 
同
HTML一样, XML (可扩展标识语言)是通用标识语言标准(SGML)的一个子集,它是描述网络上的数据内容和结构的标准。尽管如此,XML不象HTML,HTML仅仅提供了在页面上显示信息的通用方法(没有上下文相关和动态功能) ,XML则对数据赋予上下文相关功能,它继承了SGML的大部分功能,却使用了不太复杂的技术。. 
为了使得SGML显得用户友好,XML重新定义了SGML的一些内部值和参数,去掉了大量的很少用到的功能,这些繁杂的功能使得SGML在设计网站时显得复杂化。XML保留了SGML的结构化功能,这样就使得网站设计者可以定义自己的文档类型,XML同时也推出一种新型文档类型,使得开发者也可以不必定义文档类型。 
因为XML是W3C制定的,XML的标准化工作由W3C的XML工作组负责,该小组成员由来自各个地方和行业的专家组成,他们通过email交流对XML标准的意见,并提出自己的看法 (
www.w3.org/TR/WD-xml)。因为XML 是个公共格式, (它不专属于任何一家公司),你不必担心XML技术会成为少数公司的盈利工具,XML不是一个依附于特定浏览器的语言
XML(可扩展标记语言)是从称为SGML(标准通用标记语言)的更加古老的语言派生出来的。SGML的主要目的是定义使用标签来表示数据的标记语言的语法。
标签由包围在一个小于号(<)和一个大于号(>)之间的文本组成,例如<tag>。起始标签(start tag)表示一个特定区域的开始,例如<start>;结束标签(end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如</end>。SGML还定义了标签的特性(attribute),它们是定义在小于号和大于号之间的值,例如<img src="picture.jpg">中的src特性。如果你觉得它看起来很熟悉的话,应该知道,基于SGML的语言的最著名实现就是原始的HTML。
SGML常用来定义针对HTML的文档类型定义(DTD),同时它也常用于编写XML的DTD。SGML的问题就在于,它允许出现一些奇怪的语法,这让创建HTML的解析器成为一个大难题:
1  某些起始标签不允许出现结束标签,例如HTML中<img>标签。包含了结束标签就会出现错误。
2  某些起始标签可以选择性出现结束标签或者隐含了结束标签,例如HTML中<p>标签,当出现另一个<p>标签或者某些其他标签时,便假设在这之前有一个结束标签。
3  某些起始标签要求必须出现结束标签,例如HTML中<script>标签。
4  标签可以以任何顺序嵌套。即使结束标签不按照起始标签的逆序出现也是允许的,例如,<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语言的解析器变成了一项艰巨的任务。判断何时应用以上规则的困难导致了SGML语言的定义一直停滞不前。以这些问题作为出发点,XML逐渐步入我们的视野。
      XML去掉了之前令许多开发人员头疼的SGML的随意语法。在XML中,采用了如下的语法:
8  任何的起始标签都必须有一个结束标签。
9  可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<tag />。XML解析器会将其翻译成<tag></tag>。
10  标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如<b>this is a <i>sample</i> string</b>。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
11  所有的特性都必须有值。
12  所有的特性都必须在值的周围加上双引号。
这些规则使得开发一个XML解析器要简便得多,而且也除去了解析SGML中花在判断何时何地应用那些奇怪语法规则上的工作。仅仅在XML出现后的前六年就衍生出多种不同的语言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同时也将HTML改进为XHTML。
如果需要关于SGML和XML具体技术上的对比,请查看W3C的注解,位于:
http://www.w3. org/TR/NOTE-sgml-xml.html
如今,XML已经是世界上发展最快的技术之一。它的主要目的是使用文本以结构化的方式来表示数据。在某些方面,XML文件也类似于数据库,提供数据的结构化视图。这里是一个XML文件的例子:
每个XML文档都由XML序言开始,在前面的代码中的第一行便是XML序言,<?xml version="1.0"?>。这一行代码会告诉解析器和浏览器,这个文件应该按照前面讨论过的XML规则进行解析。第二行代码,<books>,则是文档元素(document element),它是文件中最外面的标签(我们认为元素(element)是起始标签和结束标签之间的内容)。所有其他的标签必须包含在这个标签之内来组成一个有效的XML文件。XML文件的第二行并不一定要包含文档元素;如果有注释或者其他内容,文档元素可以迟些出现。
范例文件中的第三行代码是注释,你会发现它与HTML中使用的注释风格是一样的。这是XML从SGML中继承的语法元素之一。
页面再往下的一些地方,可以发现<desc>标签里有一些特殊的语法。<![CDATA[ ]]>代码用于表示无需进行解析的文本,允许诸如大于号和小于号之类的特殊字符包含在文本中,而无需担心破坏XML的语法。文本必须出现在<![CDATA[和]]>之间才能合适地避免被解析。这样的文本称为Character Data Section,简称CData Section。
下面的一行就是在第二本书的定义之前的:
<?page render multiple authors ?>
虽然它看上去很像XML序言,但实际上是一种称为处理指令(processing instruction)的不同类型的语法。处理指令(以下简称PI)的目的是为了给处理页面的程序(例如XML解析器)提供额外的信息。PI通常情况下是没有固定格式的,唯一的要求是紧随第一个问号必须至少有一个字母。在此之后,PI可以包含除了小于号和大于号之外的任何字符串序列。
最常见的PI是用来指定XML文件的样式表:
这个PI一般会直接放在XML序言之后,通常由Web浏览器使用,来将XML数据以特殊的样式显示出来。
			
posted @ 
2008-05-06 14:09 矿矿 阅读(283) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			//frame版程序源代码如下,疏漏之处,望批评指正。 
//数字分组没有编写,科学型计算器没有编写,其他已经完善。 
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 { //导入动作监听接口 
//设计面板中的单位 
JFrame frame; 
JTextField textAnswer; 
JPanel panel, panel1, panel2, panel3; 
JMenuBar mainMenu; 
JTextField textMemory; 
JLabel labelMemSpace; //labelMemSpace单纯做摆设,控制面板的形状 
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; //设置数据输出精度 
boolean clickable; //控制当前能否按键 
double memoryd; //使用内存中存储的数字 
int memoryi; 
double vard, answerd; //用来保存double型数据的中间值(vard)和最后结果(answerd) 
short key = -1, prekey = -1; //key用来保存当前进行何种运算,prekey用来保存前次进行何种运算 
String copy; //做复制用 
JTextArea help; //帮助 
JScrollPane scrollHelp; 
//构造函数 
public Calculator() { 
clickable = true; 
answerd = 0; 
frame = new JFrame("计算器"); 
df = new DecimalFormat("0.##############"); //设置数据输出精度(对于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()); 
//设计整个面板 
mainMenu = new JMenuBar(); 
editMenu = new JMenu("编辑(E)"); 
viewMenu = new JMenu("查看(V)"); 
helpMenu = new JMenu("帮助(H)"); 
copyItem = new JMenuItem(" 复制(C) Ctrl+C"); 
copyItem.addActionListener(this); 
pasteItem = new JMenuItem(" 粘贴(V) Ctrl+V"); 
pasteItem.addActionListener(this); 
editMenu.add(copyItem); 
editMenu.add(pasteItem); 
tItem = new JMenuItem("●标准型(T)"); 
tItem.addActionListener(this); 
sItem = new JMenuItem(" 科学型(S)"); 
sItem.addActionListener(this); 
numberGroup = new JMenuItem(" 数字分组(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("执行简单计算\n"); 
help.append("1. 键入计算的第一个数字。\n"); 
help.append("2. 单击“+”执行加、“-”执行减、“*”执行乘或“/”执行除。\n"); 
help.append("3. 键入计算的下一个数字。\n"); 
help.append("4. 输入所有剩余的运算符和数字。\n"); 
help.append("5. 单击“=”。\n"); 
aboutCal = new JMenuItem(" 关于计算器(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)); 
//将所有行为与监听绑定 
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(); 
} 
//设置各个按钮行为 
public void actionPerformed(ActionEvent event) { 
boolean sign = false; //判断是否是double型数参与运算,是为true,不是为false 
Object temp = event.getSource(); 
try { 
//如果按下数据按钮,将按下的按钮代表的数据插入的当前文本框字符串之后 
for (int i = 0; i <= 9; i++) 
if (temp == button[i] && clickable == true) 
textAnswer.setText(textAnswer.getText() + Integer.toString(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("除数不能为零"); 
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("除数不能为零"); 
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("除数不能为零"); 
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("除数不能为零"); 
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) { 
//如果连续按'=',则进行连续运算 
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("除数不能为零"); 
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("除数不能为零"); 
clickable = false; 
} 
else { 
answerd /= Double.parseDouble(textAnswer.getText()); 
textAnswer.setText(df.format(answerd)); 
} 
} 
} 
prekey = 5; 
} 
//'%'操作,对第二个操作数除以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数,除100 
if (isDot == true) { 
double dtemp = Double.parseDouble(textAnswer.getText()); 
dtemp = dtemp / 100.0; 
textAnswer.setText(Double.toString(dtemp)); 
} 
else { 
//如果是int数但能被100整除,则去掉末尾两个零 
if (Integer.parseInt(textAnswer.getText()) % 100 == 0) { 
int itemp = Integer.parseInt(textAnswer.getText()); 
itemp /= 100; 
textAnswer.setText(Integer.toString(itemp)); 
} 
//如果是int数,但不能被100整除,则按double数处理 
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("负数不能开根号"); 
clickable = false; 
} 
else 
textAnswer.setText(Double.toString(java.lang.Math.sqrt(Double. 
parseDouble(textAnswer.getText())))); 
} 
//倒数运算 
if (temp == buttonDao && clickable == true) { 
if (textAnswer.getText().charAt(0) == '0' && 
textAnswer.getText().length() == 1) { 
textAnswer.setText("零不能求倒数"); 
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) { 
//如果当前字符串首字母有'-'号,代表现在是个负数,再按下时,则将首符号去掉 
if (s.charAt(0) == '-') { 
textAnswer.setText(""); 
for (int i = 1; i < s.length(); i++) { 
char a = s.charAt(i); 
textAnswer.setText(textAnswer.getText() + a); 
} 
} 
//如果当前字符串第一个字符不是符号,则添加一个符号在首字母处 
else 
textAnswer.setText('-' + s); 
} 
} 
//计算器有关内存操作 
//'MC'的操作,将内存清0 
if (temp == buttonMC && clickable == true) { 
memoryd = memoryi = 0; 
textMemory.setText(""); 
} 
//'MS'的操作,将当前文本框内容保存入内存,显示'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+'的功能,将当前文本框里的数据和存储器中数据相加后,再存入存储器 
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型数 
if (isDot == false) //被加数是一个int型数 
memoryi += Integer.parseInt(textAnswer.getText()); 
else { //被加数是一个double型数,则将int存储器中数传入double存储器与当前数相加,int存储器清零 
memoryd = memoryi + Double.parseDouble(textAnswer.getText()); 
memoryi = 0; 
} 
} 
else 
memoryd += Double.parseDouble(textAnswer.getText()); 
} 
//按下'Backspace'键,利用循环将当前字符串中的最后一个字母删除 
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'按钮,将当前文本框内数据清除 
if (temp == buttonCe) { 
textAnswer.setText(""); 
clickable = true; 
} 
//按下'C'按钮,文本框内数据清除,同时var,answer清0 
if (temp == buttonC) { 
vard = answerd = 0; 
textAnswer.setText(""); 
clickable = true; 
} 
//按下'复制'菜单栏 
if (temp == copyItem) { 
copy = textAnswer.getText(); 
} 
//按下'粘贴'菜单栏 
if (temp == pasteItem) { 
textAnswer.setText(copy); 
} 
if (temp == sItem) { 
JOptionPane.showMessageDialog(panel, "当前是标准型计算器,\n科学型计算器有待更新。"); 
} 
//按下'帮助主题'菜单栏 
if (temp == topHelp) { 
JOptionPane.showMessageDialog(panel, scrollHelp); 
} 
//按下'数字分组'菜单栏 
if (temp == numberGroup) { 
if (numberGroup.getText().compareTo(" 数字分组(I)") == 0) 
numberGroup.setText("√数字分组(I)"); 
else 
numberGroup.setText(" 数字分组(I)"); 
} 
//按下'关于'菜单栏 
if (temp == aboutCal) { 
JOptionPane.showMessageDialog(panel, "计算器1.00版\n开发者:矿矿"); 
} 
} 
//输入中如果有操作非法,比如按下两次'+',捕获异常 
catch (Exception e) { 
textAnswer.setText("操作非法"); 
clickable = false; 
} 
} 
//主函数 
public static void main(String args[]) { 
new Calculator(); 
} 
} 
			
posted @ 
2008-04-21 20:44 矿矿 阅读(3324) | 
评论 (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("设置");
    JButton btnLogin = new JButton("登录");
    
    
    
    Demo(){
        lblTop.setIcon(img);
        paneTop.add(lblTop);
        
        lblName.setText("QQ帐号:");
        lblApply.setText("申请帐号   ");
        lblPwd.setText("QQ密码:");
        lblForget.setText("忘记密码?");
        lblModel.setText("状态:");
        
        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 矿矿 阅读(5434) | 
评论 (17) | 
编辑 收藏 
		
			
		
			
			在
Java语言中, abstract class 和
在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的对系统设计人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程我想就是指按照这种思想来编程吧!实际上,在日常工作中,你已经按照接口编程了,只不过如果你没有这方面的意识,那么你只是在被动的实现这一思想;表现在频繁的抱怨别人改的代码影响了你(接口没有设计到),表现在某个模块的改动引起其他模块的大规模调整(模块接口没有很好的设计)等等。
  Booch先生那天谈到Interaction Designer,它就是指做这类设计的人,只不过层次更高一些。我想目前我们的软件设计队伍中,这类人是最缺乏的人才之一。
  非接口编程?是不是就是面向过程的编程思想?
  1.关于接口的理解。
  接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
  我们在一般实现一个系统的时候,通常是将定义与实现合为一体,不加分离的,我认为最为理解的系统设计规范应是所有的定义与实现分离,尽管这可能对系统中的某些情况有点繁烦。
  接口的本身反映了系统设计人员对系统的抽象理解。
  接口应有两类:第一类是对一个体的抽象,它可对应为一个抽象体(abstract class);
  第二类是对一个体某一方面的抽象,即形成一个抽象面(interface);
  一个体有可能有多个抽象面。
  抽象体与抽象面是有区别的。
  2.设计接口的另一个不可忽视的因素是接口所处的环境(context,environment),系统论的观点:环境是系统要素所处的空间与外部影响因素的总和。任何接口都是在一定的环境中产生的。因此环境的定义及环境的变化对接口的影响是不容忽视的,脱离原先的环境,所有的接口将失去原有的意义。
  3.按照组件的开发模型(3C),它们三者相辅相成,各司一面,浑然一体,缺一不可。
  面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
  面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
  接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题
  我认为:UML里面所说的interface是协议的另一种说法。并不是指com的interface,CORBA的interface,Java的interface,Delphi的interface,人机界面的interface或NIC的interface。
  在具体实现中,是可以把UML的interface实现为语言的interface,分布式对象环境的interface或其它什么interface,但就理解UML的interface而言,指的是系统每部分的实现和实现之间,通过interface所确定的协议来共同工作。
  所以我认为,面向interface编程,原意是指面向抽象协议编程,实现者在实现时要严格按协议来办。也就是Bill Joy同志说的,一边翻rfc,一边写代码的意思。面向对象编程是指面向抽象和具象。抽象和具象是矛盾的统一体,不可能只有抽象没有具象。一般懂得抽象的人都明白这个道理。 但有的人只知具象却不知抽象为何物。
  所以只有interface没有实现,或只有实现而没有interface者是没有用的,反OO的。
  所以还是老老实实面向对象编程,面向协议编程,或者什么都不面向,老老实实编程。
是支持
抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进 行抽象类定义时对于abstract class和interface的选择显得比较随意。其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对 于问题领域本质的理解、对于设计意图的理解是否正确、合理。本文将对它们之间的区别进行一番剖析,试图给开发者提供一个在二者之间进行选择的依据。 
  
理解抽象类
  abstract class和interface在Java语言中都是用来进行抽象类(本文 中的抽象类并非从abstract class翻译而来,它表示的是一个抽象体,而abstract class为Java语言中用于定义抽象类的一种方法, 请读者注意区分)定义的,那么什么是抽象类,使用抽象类能为我们带来什么好处呢?
  在 面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是 所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、 三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念 在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。
  在面向对象领域,抽象类主要用来进行类型隐藏。 我们可以构造出一个固定的一组行为的抽象描 述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个 抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知 道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。
  
从语法定义层面看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可以有自己的数据成员,也可以有非 abstract的成员方法,而在interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final 的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊形式的 abstract class。
  从编程的角度来看,abstract class和interface都可以用来实现 "design by contract" 的思想。但是在具体的使用上面还是有一些区别的。
  首先,abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系(因为Java不支持多继承 -- 转注)。但是,一个类却可以实现多个interface。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。
  其次,在abstract class的定义中,我们可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会增加一些复杂性,有时会造成很大的麻烦。
  在 抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的麻烦。因 为如果后来想修改类的界面(一般通过 abstract class 或者interface来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添 加新的参数)时,就会非常的麻烦,可能要花费很多的时间(对于派生类很多的情况,尤为如此)。但是如果界面是通过abstract class来实现的,那 么可能就只需要修改定义在abstract class中的默认行为就可以了。
  同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了 "one rule,one place" 原则,造成代码重复,同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。
  
从设计理念层面看 abstract class 和 interface
  上面主要从语法定义和编程的角度论述了abstract class和interface的区 别,这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。
  前面已经提到过,abstract class在Java语言中体现了一种继承关系,要想使得 继承关系合理,父类和派生类之间必须存在"is-a"关系,即父类和派生类在概念本质上应该是相同的。对于interface来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的, 仅仅是实现了interface定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。
  考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作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没有大的区别。
  如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在本例中, 主要是为了展示 abstract class 和interface 反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解 决方案,并从设计理念层面对这些不同的方案进行分析。
  解决方案一:
  简单的在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(){…} 
            } | 
        
    
  这种方法违反了面向对象设计中的一个核心原则 ISP (Interface Segregation Principle),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方 法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变,反 之依然。
  解决方案二:
  既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定 义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用 abstract class 方式定义;两个概念都使用interface方式定义;一个概念 使用 abstract class 方式定义,另一个概念使用interface方式定义。
  显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。
  如果两个概念都使用interface方式来定义,那么就反映出两个问题:1、我们可能没有 理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分 析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用 interface方式定义)反映不出上述含义。
  如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报 警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系 在本质上是"is-a"关系。所以对于Door这个概念,我们应该使用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(){…} 
            } | 
        
    
  这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其 实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。
  
小结
  1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
  2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
  3.abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。 
  4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
  5.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
  6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。 
  7.接口中的方法默认都是 public,abstract 类型的。
  
结论
  abstract class 和 interface 是 Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概 念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。这其实也是语言的一种的惯用法,希望读者朋友能够细细体会。 
jack jones/杰克琼斯/马克华菲
			posted @ 
2008-04-08 15:14 矿矿 阅读(724) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的对系统设计人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程我想就是指按照这种思想来编程吧!实际上,在日常工作中,你已经按照接口编程了,只不过如果你没有这方面的意识,那么你只是在被动的实现这一思想;表现在频繁的抱怨别人改的代码影响了你(接口没有设计到),表现在某个模块的改动引起其他模块的大规模调整(模块接口没有很好的设计)等等。
  Booch先生那天谈到Interaction Designer,它就是指做这类设计的人,只不过层次更高一些。我想目前我们的软件设计队伍中,这类人是最缺乏的人才之一。
  非接口编程?是不是就是面向过程的编程思想?
  1.关于接口的理解。
  接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
  我们在一般实现一个系统的时候,通常是将定义与实现合为一体,不加分离的,我认为最为理解的系统设计规范应是所有的定义与实现分离,尽管这可能对系统中的某些情况有点繁烦。
  接口的本身反映了系统设计人员对系统的抽象理解。
  接口应有两类:第一类是对一个体的抽象,它可对应为一个抽象体(abstract class);
  第二类是对一个体某一方面的抽象,即形成一个抽象面(interface);
  一个体有可能有多个抽象面。
  抽象体与抽象面是有区别的。
  2.设计接口的另一个不可忽视的因素是接口所处的环境(context,environment),系统论的观点:环境是系统要素所处的空间与外部影响因素的总和。任何接口都是在一定的环境中产生的。因此环境的定义及环境的变化对接口的影响是不容忽视的,脱离原先的环境,所有的接口将失去原有的意义。
  3.按照组件的开发模型(3C),它们三者相辅相成,各司一面,浑然一体,缺一不可。
  面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
  面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
  接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题
  我认为:UML里面所说的interface是协议的另一种说法。并不是指com的interface,CORBA的interface,Java的interface,Delphi的interface,人机界面的interface或NIC的interface。
  在具体实现中,是可以把UML的interface实现为语言的interface,分布式对象环境的interface或其它什么interface,但就理解UML的interface而言,指的是系统每部分的实现和实现之间,通过interface所确定的协议来共同工作。
  所以我认为,面向interface编程,原意是指面向抽象协议编程,实现者在实现时要严格按协议来办。也就是Bill Joy同志说的,一边翻rfc,一边写代码的意思。面向对象编程是指面向抽象和具象。抽象和具象是矛盾的统一体,不可能只有抽象没有具象。一般懂得抽象的人都明白这个道理。 但有的人只知具象却不知抽象为何物。
  所以只有interface没有实现,或只有实现而没有interface者是没有用的,反OO的。
  所以还是老老实实面向对象编程,面向协议编程,或者什么都不面向,老老实实编程。
			posted @ 
2008-04-08 15:07 矿矿 阅读(209) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			一.谁在做Garbage Collection?
  一种流行的说法:在C++里,是系统在做垃圾回收;而在Java里,是Java自身在做。
  在C++里,释放内存是手动处理的,要用delete运算符来释放分配的内存。这是流行的说法。确切地说,是应用认为不需要某实体时,就需用delete告诉系统,可以回收这块空间了。这个要求,对编码者来说,是件很麻烦、很难做到的事。随便上哪个BBS,在C/C++版块里总是有一大堆关于内存泄漏的话题。
  Java采用一种不同的,很方便的方法:Garbage Collection。垃圾回收机制放在JVM里。JVM完全负责垃圾回收事宜,应用只在需要时申请空间,而在抛弃对象时不必关心空间回收问题。
  二.对象在啥时被丢弃?
  在C++里,当对象离开其作用域时,该对象即被应用抛弃。
  是对象的生命期不再与其作用域有关,而仅仅与引用有关。
  Java的垃圾回收机制一般包含近十种算法。对这些算法中的多数,我们不必予以关心。只有其中最简单的一个:引用计数法,与编码有关。
  一个对象,可以有一个或多个引用变量指向它。当一个对象不再有任何一个引用变量指向它时,这个对象就被应用抛弃了。或者说,这个对象可以被垃圾回收机制回收了。
  这就是说,当不存在对某对象的任何引用时,就意味着,应用告诉JVM:我不要这个对象,你可以回收了。
  JVM的垃圾回收机制对堆空间做实时检测。当发现某对象的引用计数为0时,就将该对象列入待回收列表中。但是,并不是马上予以销毁。
  三.丢弃就被回收?
  该对象被认定为没有存在的必要了,那么它所占用的内存就可以被释放。被回收的内存可以用于后续的再分配。
  但是,并不是对象被抛弃后当即被回收的。JVM进程做空间回收有较大的系统开销。如果每当某应用进程丢弃一个对象,就立即回收它的空间,势必会使整个系统的运转效率非常低下。
  前面说过,JVM的垃圾回收机制有多个算法。除了引用计数法是用来判断对象是否已被抛弃外,其它算法是用来确定何时及如何做回收。JVM的垃圾回收机制要在时间和空间之间做个平衡。
  因此,为了提高系统效率,垃圾回收器通常只在满足两个条件时才运行:即有对象要回收且系统需要回收。切记垃圾回收要占用时间,因此,Java运行时系统只在需要的时候才使用它。因此你无法知道垃圾回收发生的精确时间。
  四.没有引用变量指向的对象有用吗?
  前面说了,没挂上引用变量的对象是被应用丢弃的,这意味着,它在堆空间里是个垃圾,随时可能被JVM回收。
  不过,这里有个不是例外的例外。对于一次性使用的对象(有些书称之为临时对象),可以不用引用变量指向它。举个最简单也最常见的例子:
  System.out.println(“I am Java!”);
  就是创建了一个字符串对象后,直接传递给println()方法。
  五.应用能干预垃圾回收吗?
  许多人对Java的垃圾回收不放心,希望在应用代码里控制JVM的垃圾回收运作。这是不可能的事。对垃圾回收机制来说,应用只有两个途径发消息给JVM。第一个前面已经说了,就是将指向某对象的所有引用变量全部移走。这就相当于向JVM发了一个消息:这个对象不要了。第二个是调用库方法System.gc(),多数书里说调用它让Java做垃圾回收。
  第一个是一个告知,而调用System.gc()也仅仅是一个请求。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生,或回收较多而已。
  希望JVM及时回收垃圾,是一种需求。其实,还有相反的一种需要:在某段时间内最好不要回收垃圾。要求运行速度最快的实时系统,特别是嵌入式系统,往往希望如此。
  Java的垃圾回收机制是为所有Java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么、怎么做或做多少。
  六.对象被回收时要做的事
  一个对象在运行时,可能会有一些东西与其关连。因此,当对象即将被销毁时,有时需要做一些善后工作。可以把这些操作写在finalize()方法(常称之为终止器)里。
  protected void finalize()
  {
  // finalization code here
  }
  这个终止器的用途类似于C++里的析构函数,而且都是自动调用的。但是,两者的调用时机不一样,使两者的表现行为有重大区别。C++的析构函数总是当对象离开作用域时被调用。这就是说,C++析构函数的调用时机是确定的,且是可被应用判知的。但是,Java终止器却是在对象被销毁时。由上所知,被丢弃的对象何时被销毁,应用是无法获知的。而且,对于大多数场合,被丢弃对象在应用终止后仍未销毁。
  在编码时,考虑到这一点。譬如,某对象在运作时打开了某个文件,在对象被丢弃时不关闭它,而是把文件关闭语句写在终止器里。这样做对文件操作会造成问题。如果文件是独占打开的,则其它对象将无法访问这个文件。如果文件是共享打开的,则另一访问该文件的对象直至应用终结仍不能读到被丢弃对象写入该文件的新内容。
  至少对于文件操作,编码者应认清Java终止器与C++析构函数之间的差异。
  那么,当应用终止,会不会执行应用中的所有finalize()呢?据Bruce Eckel在Thinking in Java里的观点:“到程序结束的时候,并非所有收尾模块都会得到调用”。这还仅仅是指应用正常终止的场合,非正常终止呢?
  因此,哪些收尾操作可以放在finalize()里,是需要酌酎的。
			posted @ 
2008-04-08 14:55 矿矿 阅读(311) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			重要知识点总结如下:
  1,抽象,封装,继承,多态是面向对象程序设计中得四个特点.
  2,面向对象得软件开发大体分为:面向对象的分析,面向对象的设计,面向对象的实现.
  可概括为如下过程:分析用户需求,从问题中抽取对象模型;细化模型,设计类,包括类的属性和类间的
  相互关系,同时观察是否有可以直接引用的已有类或部件;选定一种面向对象的编程语言,具体编码实现
  上一阶段类的设计,并在开发过程中引入测试,完善整个解决方案.
  3,面向对象程序设计方法的优点是:可重用性,可扩展性,可管理性.
  4,类的定义:class前的修饰符分为访问控制符和非访问控制符两大类.访问控制符包括public和private.
  非访问控制符包括abstract(抽象),final(最终).
  5,final类是最终类,是不能有子类的类.abstract和final不能同时修饰一个类,因为抽象类本身没有具体对象,
  需要派生出子类后在创建子类的对象.而最终类不可能有子类.
  6,创建对象的格式为: 类名 对象名=new 构造方法(参数);注意前面是类名后面是构造方法.
  注意构造方法没有返回类型,也不能写void,主要用于完成类对象的初始化工作,一般不能直接由编程
  直接调用,而是用new运算符来调用.
  7,如果class前面由public修饰符,则默认构造方法的前面也应该有public修饰符.
  8,类中有static修饰的域或方法,可用类名或对象名访问,否则只能用对象名访问.
  9,修饰域的访问控制符可以是:public,private,protected,private protected.非访问控制符可以是:
  static,final,volatile(易失域)
  10,类变量的最本质的特点是:他们是类的域,不属于任何一个类的具体对象实例.不是保存在某个对象实例的内存空间中,而是保存在类的内存区域的公共存储单元中.
        11,局部变量是在方法体内声明的,只有当方法被调用时他们才存在,因而只能在本方法内使用,不存在访问控制符,也不能声明为静态变量(static),但可以声明为final变量.局部变量必须初始化.
  12,修饰方法的访问控制符可以是:public,private,protected,private protected,修饰方法的非访问控制符可以是:static,final,abstract,native(本地方法),synchronized(同步方法)。
  13,用static修饰的变量或方法都为类成员,类成员可以用类名或实例名访问,实例成员只能用实例名来访问。
  14,如果一个类中含有抽象方法,则此类必须为抽象类,如果抽象类的子类不为抽象类,则子类必须实现父类的所有抽象方法。抽象方法不能用静态方法和最终方法。抽想方法只有函数头的声明,而用分号来替代方法体,没有大括号。如abstract void abstractmethod();
  15,this变量用在一个方法的内部,指向当前对象,当前对象指的是调用当前正在执行的方法的那个对象。super变量是直接指向父类的构造方法,用来引用父类种的变量和方法。(由于他们指的是对象,所以不能通过它来引用类变量和类方法)
  16,如果要引用一个包中的多个类,可以用星号来代替。使用星号只能表示本层次的所有类,而不包括子层次下的类。所以经常需要用两条语句来引入两个层次的类:import java.awt.*;import java.awt.event.*;
  17,访问修饰符:
  --类中限定为public的成员可以被所有的类访问。
  --类中先定位private的成员只能被这个类本身访问。同一个类的不同对象可以访问对方的private域变量或调用对方的域方法,这是因为访问保护控制在类的级别上,而不是对象的级别上。
  --类中限定为protected的成员可以被这个类本身,它的子类(包括同一个包中和不同包中的子类),以及同一个包中的其他类访问。
  --用private protected修饰的成员可以被该类本身访问,也可以被该类的所有子类访问。
  --默认访问控制符规定只能被同一个包中的类访问和引用,而不能被其他包的类访问。即他的访问权限是friendly。
  18,注意:
  ----abstract和private,static,final,native不能并列修饰同一个方法。
  ----abstract类中不能有private修饰的域和方法
  ----static方法不能处理非static的域。
  19,重载方法的参数必须不同,或者是参数个数不同,或者是参数类型不同。重载的多个方法必须返回相同的数据类型。
  20,在java中,一个类获取某一接口定义的功能并不是通过直接继承这个接口的属性和方法来实现的。因为接口中的属性都是常量,接口的方法都是没有方法体的抽象方法,没有具体定义操作。
			posted @ 
2008-04-08 14:42 矿矿 阅读(2419) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			不走弯路,就是捷径 
可以这么说吧,学习JAVA没有什么捷径,学习什么语言都没有什么捷径 
最好的方法就是,多看书,多写代码,多思考 
没有程序基础没有关系,成事开头难,我相信你会学好的,加油吧! 
对于风接触JAVA的人,可以按照下面的路线开始学(仅供参考) 
基本数据类型-操作符-流程控制语句(这些是所有编程语言的基础) 
然后上面这些掌握了之后,看面向对象(这个是重点) 
在这个过程中可以先搞明白public,private,protected,static等关键词的用法,什么时候用,什么时候不用,这些对于你以后的学习很有帮助 
然后就是仔细研究面向对象了,这个是重点 !
当上面这些你都搞明白后,就不用我说了,你自己就会有一定的自学的经验了,就知道自己该看什么,不看什么了 
推荐两本书 
java2 核心技术卷(基础篇)、java编程思想(也就是Thinking in java) 后者在你有了一定的基础后再看,不然不容易明白的
			
posted @ 
2008-04-02 22:36 矿矿 阅读(139) | 
评论 (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 用户权限;
 User(String name,String password,String quanxian){
  用户名=name;
  密码=password;
  用户权限=quanxian;
 }
 void login(){
  if(用户名=="admin"&&密码=="123"){
   System.out.println ("登陆成功");
   System.out.println (用户权限="administrator");
  }else{
   if(用户名=="snake"&&密码=="123456"){
    System.out.println ("登陆失败");
    System.out.println (用户权限="user");
   }
  }
 }
 public static void main(String[] args){
  User u= new User("snake","123456"," ");
  u.login();
 }
}
 
 
			posted @ 
2008-04-01 19:51 矿矿 阅读(1448) | 
评论 (7) | 
编辑 收藏