JSPCN主页 | JSP空间 | 网站制作 | JSP下载 | JSP论坛 | JSP教程 | 关于JSPCN | 联系我们
JSP虚拟主机,jsp空间,java空间,java虚拟空间,详细请点击进入
做最专业的JSP中文网站 当前位置首页--JAVA技术--JAVA类  
文章搜索:
关键字 标题
  
JSP中文网内容管理系统(JCMS)
JSP虚拟主机
网络笔记本
网摘,图片,笔记收藏
虚拟服务器

JSPCN文章目录分类
JSP配置[219]JSP基础[136]
中文问题[69]上传问题[27]
JAVABEAN[46]数据库[212]
文件操作[126]图片声音[17]
JSP其他[57]时间相关[16]
JAVAMAIL[72]STRUTS[144]
开发工具[28]教程系列[157]
JSP实例[89]
JAVA基础[421]APPLET[78]
JAVA网络[179]Applica[115]
Servlet[98]XML[163]
J2ME[257]J2EE[374]
考试相关[63]JAVA线程[90]
EJB[261]Swing[26]
Java API[141]声音图片[28]
异常处理[33]JAVA实例[290]
JAVA类[139]SUN[89]
Hibernate[6]JMX[8]
Spring[34]
本版推荐文章 
本版热点文章 
相关文章链接 
 
Java面向对象编程实例详解
作者:未知     文章来源:www.jspcn.net
访问次数:2129次     加入时间:2005年01月19日
Java是一种面向对象的语言,是实现面向对象编程的强大工具。但如何在编程中实际运用并发挥其最大效能呢?本文通过一个实际Java程序的开发过程,详细说明了如何使用面向对象实现Java编程。

我们要实现的Java应用程序是:当用户输入一个球体的半径,程序将显示该球体的体积与表面积。在您阅读下文以前,请您自己思考一分钟,您将如何设计该Java应用程序。



一、普通实现方法
我相信大多数程序员要实现上述功能的程序,非常迅速地、自信地将采用下面的实现代码:
class Sphere

{

public static void main(String[] args)

{

EasyReader console = new EasyReader();

System.out.print("Enter the radius: ");

double radius = console.readDouble();

System.out.println("Radius = " + radius);

double volume = 4.0 / 3.0 * Math.PI * radius * radius * radius;

System.out.println("Volume = " + volume);

double surfArea = 4.0 * Math.PI * radius * radius;

System.out.println("Surface area = " + surfArea);

}

}

EasyReader类代码如下:
import java.io.*;

public class EasyReader

{

protected String myFileName;

protected BufferedReader myInFile;

protected int myErrorFlags = 0;

protected static final int OPENERROR = 0x0001;

protected static final int CLOSEERROR = 0x0002;

protected static final int READERROR = 0x0004;

protected static final int EOF = 0x0100;



/**

* Constructor. Prepares console (System.in) for reading

*/

public EasyReader()

{

myFileName = null;

myErrorFlags = 0;

myInFile = new BufferedReader(

new InputStreamReader(System.in), 128);

}



/**

* Constructor. opens a file for reading

* @param fileName the name or pathname of the file

*/

public EasyReader(String fileName)

{

myFileName = fileName;

myErrorFlags = 0;

try

{

myInFile = new BufferedReader(new FileReader(fileName), 1024);

}

catch (FileNotFoundException e)

{

myErrorFlags |= OPENERROR;

myFileName = null;

}

}



/**

* Closes the file

*/

public void close()

{

if (myFileName == null)

return;

try

{

myInFile.close();

}

catch (IOException e)

{

System.err.println("Error closing " + myFileName + " ");

myErrorFlags |= CLOSEERROR;

}

}



/**

* Checks the status of the file

* @return true if en error occurred opening or reading the file,

* false otherwise

*/

public boolean bad()

{

return myErrorFlags != 0;

}



/**

* Checks the EOF status of the file

* @return true if EOF was encountered in the previous read

* operation, false otherwise

*/

public boolean eof()

{

return (myErrorFlags & EOF) != 0;

}



private boolean ready() throws IOException

{

return myFileName == null || myInFile.ready();

}



/**

* Reads the next character from a file (any character including

* a space or a newline character).

* @return character read or 〈code〉null〈/code〉 character

* (Unicode 0) if trying to read beyond the EOF

*/

public char readChar()

{

char ch = ´u0000´;



try

{

if (ready())

{

ch = (char)myInFile.read();

}

}

catch (IOException e)

{

if (myFileName != null)

System.err.println("Error reading " + myFileName + " ");

myErrorFlags |= READERROR;

}



if (ch == ´u0000´)

myErrorFlags |= EOF;



return ch;

}



/**

* Reads from the current position in the file up to and including

* the next newline character. The newline character is thrown away

* @return the read string (excluding the newline character) or

* null if trying to read beyond the EOF

*/

public String readLine()

{

String s = null;



try

{

s = myInFile.readLine();

}

catch (IOException e)

{

if (myFileName != null)

System.err.println("Error reading " + myFileName + " ");

myErrorFlags |= READERROR;

}



if (s == null)

myErrorFlags |= EOF;

return s;

}



/**

* Skips whitespace and reads the next word (a string of consecutive

* non-whitespace characters (up to but excluding the next space,

* newline, etc.)

* @return the read string or null if trying to read beyond the EOF

*/

public String readWord()

{

StringBuffer buffer = new StringBuffer(128);

char ch = ´ ´;

int count = 0;

String s = null;



try

{

while (ready() && Character.isWhitespace(ch))

ch = (char)myInFile.read();

while (ready() && !Character.isWhitespace(ch))

{

count++;

buffer.append(ch);

myInFile.mark(1);

ch = (char)myInFile.read();

};



if (count 〉 0)

{

myInFile.reset();

s = buffer.toString();

}

else

{

myErrorFlags |= EOF;

}

}



catch (IOException e)

{

if (myFileName != null)

System.err.println("Error reading " + myFileName + " ");

myErrorFlags |= READERROR;

}



return s;

}



/**

* Reads the next integer (without validating its format)

* @return the integer read or 0 if trying to read beyond the EOF

*/

public int readInt()

{

String s = readWord();

if (s != null)

return Integer.parseInt(s);

else

return 0;

}



/**

* Reads the next double (without validating its format)

* @return the number read or 0 if trying to read beyond the EOF

*/

public double readDouble()

{

String s = readWord();

if (s != null)

return Double.parseDouble(s);

// in Java 1, use: return Double.valueOf(s).doubleValue();

else

return 0.0;

}

}

以下是程序的输出结果画面。


screen.width-333)this.width=screen.width-333;">



在上述程序中,实现了球体表面积和体积的算法,并通过EasyReader类轻松实现了控制台的输入,但是该程序只是完成了程序所要求的功能,并计算出了结果。该程序不是一个好的设计程序,它既没采用结构化编程,也没有发挥Java语言的强大效能,更不是面向对象编程。

实际上,从程序设计的角度来看,以上程序是一个非常糟糕的设计程序。首先,用户界面与计算公式混合在一起。请记住:对于任何编程语言,用户界面必须与计算或处理过程分离开来。另外,输出的结果太难看,数值包括太多的小数。

二、结构化编程方法
在以下的程序代码中,我们添加了2个方法,分别实现球体表面积与体积的计算,并通过相应的类控制数值的输出格式。
import java.text.DecimalFormat;

class Sphere

{

// Computes the volume of a sphere with radius r.

private static double volume(double r)

{

return 4.0 / 3.0 * Math.PI * r * r * r;

}



// Computes the surface area of a sphere with radius r.

private static double surfaceArea(double r)

{

return 4.0 * Math.PI * r * r;

}



public static void main(String[] args)

{

EasyReader console = new EasyReader();

System.out.print("Enter the radius: ");

double radius = console.readDouble();



DecimalFormat f3 = new DecimalFormat("0.000");



System.out.println(); // displays a blank line



System.out.println("Radius = " + f3.format(radius));

System.out.println("Volume = " + f3.format(volume(radius)));

System.out.println("Surface area = " + f3.format(surfaceArea(radius)));



System.out.println();

}

}

以下是输出结果。


screen.width-333)this.width=screen.width-333;">


上述经过修改后的程序,其输出结果看起来漂亮多了,但它仍只是一个勉强可以通过的设计程序。该程序采用了结构化编程的风格,并不是面向对象编程。首先,计算过程仍与用户界面实现在同一个类中。另外,对于不同的用户界面,不能体现出面向对象编程的好处,即不能重用这些计算过程。
三、面向对象编程方法

要实现上述程序的面向对象编程,我们必须注意:Java应用程序中的每一个类或对象,必须单独实现自己的任务。具体来说,在本程序中,一个类定义球体,即模型或数据表示(Model),另一个类就是实现用户界面(UI)。

另外更重要的,也是中国程序员常常忽视的,就是要考虑到团体的开发与管理,实现面向对象编程,就是让开发组中的每个程序员能独立开发不同的类,非常迅速地提高开发效率。

因此,对于本程序来说,面向对象编程的设计方法就是将Model与UI分别是实现在不同的类中。其示意图如下:


screen.width-333)this.width=screen.width-333;">




以下分别是该程序的UML类图设计与程序代码。有关UML类图的设计与应用,请查阅作者的另文(《利用UML类图设计Java应用程序详解一、二》)

Sphere的类图设计为:



screen.width-333)this.width=screen.width-333;">



其代码为:
class Sphere

{

private double myRadius;

private double myCenterX;

private double myCenterY;



// Constructors:



public Sphere (double x, double y, double r)

{

myCenterX = x;

myCenterY = y;

myRadius = r;

}



// etc...



// Accessors and modifiers:



public double getRadius()

{

return myRadius;

}



public void setRadius(double r)

{

myRadius = r;

}



// etc...



// Other public methods:



public double volume()

{

return 4.0 / 3.0 * Math.PI * myRadius * myRadius * myRadius;

}





public double surfaceArea()

{

return 4.0 * Math.PI * myRadius * myRadius;

}



public String toString()

{

return "Sphere [Center = (" + myCenterX + ", " + myCenterY + ") Radius = " + myRadius

+ "]";

}

}

TestSphere的类图为:



screen.width-333)this.width=screen.width-333;">



其实现代码为:
import java.text.DecimalFormat;



class TestSphere

{

public static void main(String[] args)

{

EasyReader console = new EasyReader();

System.out.print("Enter the radius: ");

double radius = console.readDouble();



DecimalFormat f3 = new DecimalFormat("0.000");

Sphere balloon = new Sphere(0, 0, radius);



System.out.println();



System.out.println(balloon);

System.out.println("Volume = " + f3.format(balloon.volume()));

System.out.println("Surface area = " + f3.format(balloon.surfaceArea()));



System.out.println();

}

}

该程序的各类之间的相互关系可以表示为:


screen.width-333)this.width=screen.width-333;">




该程序的UML序列图可以表示如下。有关UML序列图的设计与应用,请查阅作者的另文(《利用UML序列图设计Java应用程序详解》)



screen.width-333)this.width=screen.width-333;">



以下是程序的输出结果。



screen.width-333)this.width=screen.width-333;">



四、设计图形用户界面(GUI)

以上程序利用面向对象编程的设计方法,较好地实现了Java应用程序。但美中不足的是,没有图形用户界面供用户使用。

如果我们要增加设计图形用户界面,我们就可以将类Sphere交给一个程序员去实现,将用户界面SphereWindow交给另外一个程序员去开发,这就是面向对象编程的好处,可以进行团队开发,而不是作坊式的传统的程序开发方式。

以下是用户界面SphereWindow的实现代码:
import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.*;

import java.text.DecimalFormat;



public class SphereWindow extends JFrame

implements ActionListener

{

private JTextField radiusIn, volumeOut, surfAreaOut;

private Sphere balloon;

private DecimalFormat f3 = new DecimalFormat("0.000");



public SphereWindow()

{

super("Spheres: volume and surface area");



JPanel view = new JPanel();

view.setLayout(new GridLayout(6, 2, 10, 10));

view.setBorder(new EmptyBorder(10, 10, 10, 10));



view.add(new JLabel("Radius = ", SwingConstants.RIGHT));



radiusIn = new JTextField(8);

radiusIn.setBackground(Color.yellow);

radiusIn.addActionListener(this);

view.add(radiusIn);



view.add(new JLabel("Volume = ", SwingConstants.RIGHT));



volumeOut = new JTextField(8);

volumeOut.setEditable(false);

volumeOut.setBackground(Color.white);

view.add(volumeOut);



view.add(new JLabel("Surface area = ", SwingConstants.RIGHT));



surfAreaOut = new JTextField(8);

surfAreaOut.setEditable(false);

surfAreaOut.setBackground(Color.white);

view.add(surfAreaOut);



view.add (new JPanel()); // reserved



Container c = getContentPane();

c.add(view, BorderLayout.CENTER);



balloon = new Sphere(0,0,100);

}



public void actionPerformed(ActionEvent e)

// Called automatically when the user

// strikes Enter on the input field

{

String s = radiusIn.getText();

double r = Double.parseDouble(s);

balloon.setRadius(r);



radiusIn.setText(" " + f3.format(r));

volumeOut.setText(" " + f3.format(balloon.volume()));

surfAreaOut.setText(" " + f3.format(balloon.surfaceArea()));

}



public static void main(String[] args)

{

SphereWindow w = new SphereWindow();

w.setSize(300, 250);

w.addWindowListener(new ExitButtonListener());

w.show();

}

}

ExitButtonListener类的代码为:
import java.awt.event.*;

public class ExitButtonListener extends WindowAdapter

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

}
通过实现上述程序,利用面向对象编程的设计方法,我们将Model(模型,这里是Sphere)与view(视图,这里是SphereWindow)分离开来。并较好地实现了类的封装,类的重用(Sphere)。便于团队开发,迅速提高开发效率。





摘自:ZDnet   时间:2003年9月10日
 
Copyright © 2002-2005 JSPCN.net. All rights reserved.
JSP中文网    备案序号:蜀ICP备05001583号
成都恒海科技发展有限公司    成都市一环路南二段6号新瑞楼三楼8号