资源描述
第5章 编写问题域类定义,课程回顾 UML 三层设计,第5章 编写问题域类定义,开发PD类定义 测试PD类 编写构造函数方法 编写toString方法 为Slip类编写定义 编写自定义方法 格式化输出 使用静态变量和静态方法 重载方法 处理异常,第5章 编写问题域类定义,编写规范 类名:大写字母开头,Customer 属性名:小写字母开头,但后面的字可用大写字母,phoneNo 方法名:动词在前,名次在后,小写字母开头,setAddress,第5章 编写问题域类定义,首先以客户类为例子 定义Customer类 定义属性: private String name; private String address; private String phoneNo; 定义方法:get方法,set方法。,5.1 开发PD类定义,5.1 开发PD类定义,Java类的结构定义,public class Customer / attribute definitions private String name; private String address; private String phoneNo; / get方法 public String getName() return name; public String getAddress() return address; public String getPhoneNo() return phoneNo;,5.1 开发PD类定义,/ set方法 public void setName(String newName) name = newName; public void setAddress(String newAddress) address = newAddress; public void setPhoneNo(String newPhoneNo) phoneNo = newPhoneNo; ,5.1 开发PD类定义,5.1 开发PD类定义,public class TesterOne public static void main(String args) Customer firstCustomer = new Customer(); / create instance / invoke set accessors to populate attributes firstCustomer.setName(Eleanor); firstCustomer.setAddress(Atlanta); firstCustomer.setPhoneNo(123-4567); / define variables to contain attribute values retrieved String customerName, customerAddress, customerPhoneNo;,5.2 测试PD类,/ invoke get accessors to retrieve attribute values customerName = firstCustomer.getName(); customerAddress = firstCustomer.getAddress(); customerPhoneNo = firstCustomer.getPhoneNo(); / display the retrieved attribute values System.out.println(The name is + customerName); System.out.println(The address is + customerAddress); System.out.println(The phone is + customerPhoneNo); ,5.2 测试PD类,TesterOne序列图,5.2 测试PD类,创建多个实例?,5.2 测试PD类,构造方法:默认的构造方法,自定义构造方法。 默认的构造方法仅由头和一个空的代码块组成。 Public Customer() ,5.3 编写构造方法,自定义构造函数(参数化的构造函数): public Customer(String aName, String anAddress, String aPhoneNo) / invoke setters to populate attributes this.name = aName; address = anAddress; phoneNo = aPhoneNo; ,5.3 编写构造方法,创建多个实例: 姓名: Eleanor Mike JoAnn 地址: Atlanta Boston St.Louis 电话号码:123-4567 456-1234 765-4321,5.3 编写构造方法,编写TesterThree类对Customer类中的构造函数方法进行测试: public class TesterThree public static void main(String args) / define the reference variables Customer firstCustomer, secondCustomer, thirdCustomer; / create three Customer instances with attribute values firstCustomer = new Customer(Eleanor, Atlanta, 123-4567); secondCustomer = new Customer(Mike, Boston, 467-1234); thirdCustomer = new Customer(JoAnn, St. Louis, 765-4321); / retrieve ,5.3 编写构造方法,作用:检索实例所有的属性值,将它们置于一个String对象中。 public String toString() String info; info = Customer name = + getName() + , Address = + getAddress() + , Phone Number = + getPhoneNo(); return info; ,5.4 编写toString方法,public class TesterFour public static void main(String args) / define the reference variables Customer firstCustomer, secondCustomer, thirdCustomer; / create three Customer instances with attribute values firstCustomer = new Customer(Eleanor, Atlanta, 123-4567); secondCustomer = new Customer(Mike, Boston, 467-1234); thirdCustomer = new Customer(JoAnn, St. Louis, 765-4321); / invoke tellAbutSelf for all three customers ,5.4 编写toString方法,Slip slipId width slipLength,5.5 为Slip类编写定义,Slip类的类图,public class Slip / attributes private int slipId; private int width; private double slipLength; / constructor with 3 parameters public Slip(int anId, int aWidth, double aSlipLength) / invoke setters to populate attributes setSlipId(anId); setWidth(aWidth); setSlipLength(aSlipLength); ,5.5 为Slip类编写定义,/ set methods public void setSlipId(int anId) slipId = anId; public void setWidth(int aWidth) width = aWidth; public void setSlipLength(double aSlipLength) slipLength = aSlipLength; / get methods public int getSlipId() return slipId; public int getWidth() return width; public double getSlipLength() return slipLength;,5.5 为Slip类编写定义,/ custom method toString public String toString() String info; info = Slip: Id = + getSlipId() + , Width = + getWidth() + , Length = + getSlipLength(); return info; ,5.5 为Slip类编写定义,编写tester类(TestOne)来测试代码的正确性: TestOne 类仅有一个单一方法main, 在mian中定义具有三个元素的数组slips来保存Slip实例。 Slip slips = new Slip3; / 构造函数的三个参数分别表示slipId, width, slipLength。 Slips0 = new Slip(1,10,20); Slips1 = new Slip(2,12,25); Slips2 = new Slip(3,14,30);,5.5 为Slip类编写定义,public class TesterOne public static void main(String args) / create an array to hold three Slip references Slip slips = new Slip3; / create 3 Slip instances slips0 = new Slip(1, 10, 20); slips1= new Slip(2, 12, 25); slips2= new Slip(3, 14, 30); / retrieve ,5.5 为Slip类编写定义,5.5 为Slip类编写定义,Slip: Id = 1, Width = 10, Length = 20.0 Slip: Id = 2, Width = 12, Length = 25.0 Slip: Id = 3, Width = 14, Length = 30.0 Press any key to continue.,5.5 为Slip类编写定义,编写自定义方法leaseSlip,计算船台的出租费用。 出租费用: 船台宽度 年租金 10 $800 12 $900 14 $1100 16 $1500,5.6 编写自定义方法,/ custom method to lease a Slip public double leaseSlip() double fee; switch(width) case 10: fee = 800; break; case 12: fee = 900; break; case 14: fee = 1100; break; case 16: fee = 1500; break; default: fee = 0; return fee; ,5.6 编写自定义方法,public class TesterTwo public static void main(String args) / create an array to hold three Slip references Slip slips = new Slip3; / create 3 Slip instances slips0 = new Slip(1, 10, 20); slips1= new Slip(2, 12, 25); slips2= new Slip(3, 14, 30); / compute ,5.6 编写自定义方法,Fee is 800.0 for slip 1 Fee is 900.0 for slip 2 Fee is 1100.0 for slip 3 Press any key to continue.,5.6 编写自定义方法,使用NumberFormat和DecimalFormat(在java.text包中): NumberFormat类提供将数字数据作为货币(带有逗号,货币符号和小数点)进行格式化的方法,以及不同国家格式化货币的方法。 使用DecimalFormat类对带有逗号和小数点,但未带有美元符号的数字进行格式化。,5.7 格式化输出,Class NumberFormat java.lang.Object | +-java.text.Format | +- 在使用NumberFormat类之前,需要使用import语句: import java.text.*;,java.text.NumberFormat,5.7 格式化输出,public abstract class NumberFormat extends Format 静态方法:getInstance public static final NumberFormat getInstance(),5.7 格式化输出,使用getInstance方法,格式化数据: NumberFormat general = NumberFormat.getInstance(); myString = general.format(myNumber); 格式化多个数据: NumberFormat nf = NumberFormat.getInstance(); for (int i = 0; i a.length; +i) System.out.println(nf.format(myNumberi) + ; ); ,5.7 格式化输出,import java.text.*; public class TesterThree public static void main(String args) / create a Slip instance Slip aSlip = new Slip(3, 14, 30); / compute lease fee double fee = aSlip.leaseSlip(); System.out.println(fee); / illustrate number format NumberFormat nf = NumberFormat.getInstance(); System.out.println(number: + nf.format(fee); ,5.7 格式化输出,1100.0 number: 1,100 Press any key to continue.,5.7 格式化输出,getCurrencyInstance 方法: public static final NumberFormat getCurrencyInstance() /Returns a currency format for the current default locale. public static NumberFormat getCurrencyInstance(LocaleinLocale) /Returns a currency format for the specified locale.,5.7 格式化输出,import java.text.*; import java.util.*; public class TesterThree public static void main(String args) / create a Slip instance Slip aSlip = new Slip(3, 14, 30); / compute lease fee double fee = aSlip.leaseSlip(); / illustrate currency format NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(); System.out.println(Currency: + currencyFormat.format(fee); NumberFormat ccFormat = NumberFormat. getCurrencyInstance(Locale.US); System.out.println(Currency: + ccFormat.format(fee); ,5.7 格式化输出,Currency: ¥1,100.00 Currency: $1,100.00 Press any key to continue.,5.7 格式化输出,java.text Class DecimalFormat java.lang.Object | +-java.text.Format | +- java.text.NumberFormat | +- java.text.DecimalFormat,5.7 格式化输出,public class DecimalFormat extends NumberFormat /DecimalFormat is a concrete subclass of NumberFormat that formats decimal numbers. It also supports different kinds of numbers, including integers (123), fixed-point numbers (123.4), scientific notation (1.23E4), percentages (12%).,5.7 格式化输出,DecimalFormat d1Format = new DecimalFormat(#,#0.00); #要显示的数字保留位置,会取消所有的前导零 0强制显示某个字符,即使字符的值为零,5.7 格式化输出,import java.text.*; import java.util.*; public class TesterThree public static void main(String args) / create a Slip instance Slip aSlip = new Slip(3, 14, 30); double fee = aSlip.leaseSlip(); DecimalFormat d1Format = new DecimalFormat(#,#0.00); System.out.println(Decimal: + d1Format.format(fee); DecimalFormat d2Format = new DecimalFormat(#,#0.00); System.out.println(Decimal: + d2Format.format(fee); DecimalFormat d3Format = new DecimalFormat(00000.00); System.out.println(Decimal: + d3Format.format(fee); ,5.7 格式化输出,Decimal: 1,100.00 Decimal: 11,00.00 Decimal: 01100.00 Press any key to continue.,5.7 格式化输出,使用换码顺序: n (newline) b (backspace) f (form feed ) (single quote) t (tab) r (return) (backslash) (double quote),5.7 格式化输出,import java.text.*; public class TesterThree public static void main(String args) / create a Slip instance Slip aSlip = new Slip(3, 14, 30); / compute lease fee double fee = aSlip.leaseSlip(); / illustrate escape sequences System.out.println(Before tab t after tab); System.out.println(Before new line n after new line); System.out.println(Display double quote ); ,5.7 格式化输出,Before tab after tab Before new line after new line Display double quote Press any key to continue.,5.7 格式化输出,静态变量:类变量; 静态方法:类方法; 关键字:static 所有实例共享,每个实例没有自己的副本,5.8 使用静态变量和静态方法,在Slip类中加入静态变量船台数量: private static int numberofSlips = 0; 在Slip类的构造函数中增加下面的语句: numberofSlips+; 编写getter方法返回numberofSlips的内容: public static int getNumberofSlips() return getNumberofSlips; ,5.8 使用静态变量和静态方法,public class Slip / attributes private int slipId; private int width; private double slipLength; / static attribute variable private static int numberOfSlips = 0; / constructor with 3 parameters public Slip(int anId, int aWidth, double aSlipLength) / invoke setters to populate attributes setSlipId(anId); setWidth(aWidth); setSlipLength(aSlipLength); numberOfSlips+; ,5.8 使用静态变量和静态方法,/ custom method to lease a Slip public double leaseSlip() double fee; switch(width) case 10: fee = 800; break; case 12: fee = 900; break; case 14: fee = 1100; break; case 16: fee = 1500; break; default: fee = 0; return fee; ,5.8 使用静态变量和静态方法,/ setters public void setSlipId(int anId) slipId = anId; public void setWidth(int aWidth) width = aWidth; public void setSlipLength(double aSlipLength) slipLength = aSlipLength; / getters public int getSlipId() return slipId; public int getWidth() return width; public double getSlipLength() return slipLength; / static method public static int getNumberOfSlips() return numberOfSlips;,5.8 使用静态变量和静态方法,/ toString public String toString() String info; info = Slip: Id = + getSlipId() + , Width = + getWidth() + , Length = + getSlipLength(); return info; ,5.8 使用静态变量和静态方法,public class TesterFour public static void main(String args) Slip slips = new Slip3; slips0 = new Slip(1, 10, 20); System.out.println(Number of slips + Slip.getNumberOfSlips(); slips1= new Slip(2, 12, 25); System.out.println(Number of slips + Slip.getNumberOfSlips(); slips2= new Slip(3, 14, 30); System.out.println(Number of slips + Slip.getNumberOfSlips(); / retrieve ,5.8 使用静态变量和静态方法,Number of slips 1 Number of slips 2 Number of slips 3 Number of slips (ref var) 3 Press any key to continue.,5.8 使用静态变量和静态方法,方法签名(method signature)包括方法名及参数表 Java通过签名来识别方法。 方法重载( overloaded method ):在一个类中可以定义多个方法,它们具有相同的方法名及不同的参数表。,5.9 重载方法,与多态的区别: 多态:当一个类中的某方法与第二个类中的某方法具有相同签名 重载:同一个类中有两个以上相同的方法名,但是参数表不同,5.9 重载方法,重载构造函数,有时需要多个构造函数,每一个构造函数有不同的参数表。 大多数船台有12英尺宽、25英尺长,但少数及个船台具有不同的宽度和长度。 目前的 Slip 构造函数需要3个实参:slipId, width , slipLength.,5.9 重载方法,改进:增加第二个构造函数,只有slipId一个形参。 另外两项使用默认值: 12 feet wide and 25 feet long.,5.9 重载方法,此外,为了方便以后代码维护,设置静态常量 private static final int DEFAULT_WIDTH = 12; private static final int DEFAULT_SLIP_LENGTH = 25;,5.9 重载方法,第二个构造函数方法除了只有一个形参用来接收船台ID值。 public Slip(int anId) / invoke 3-parameter constructor with default width ,5.9 重载方法,public class TesterFive public static void main(String args) / create 2 Slip instances using different constructors / first use original constructor passing 3 arguments Slip firstSlip = new Slip(1, 10, 20); / next, use 2nd constructor passing only 1 argument Slip secondSlip = new Slip(2); / retrieve ,5.9 重载方法,Slip: Id = 1, Width = 10, Length = 20.0 Slip: Id = 2, Width = 12, Length = 25.0,5.9 重载方法,重载自定义方法,如在特殊情况下,允许将租金打折。 编写leaseSlip方法的第二个版本:接受百分比折扣值。,5.9 重载方法,第一个leaseSlip方法具有一个空的参数表;第二个leaseSlip方法具有折扣的形参变量; public double leaseSlip(double aDiscountPercent) double fee = this.leaseSlip(); double discountedFee = fee * (100 - aDiscountPercent)/100; return discountedFee ; ,5.9 重载方法,public class TesterFive public static void main(String args) / create 2 Slip instances using different constructors Slip firstSlip = new Slip(1, 10, 20); Slip secondSlip = new Slip(2); / retrieve ,5.9 重载方法,Slip: Id = 1, Width = 10, Length = 20.0 Slip: Id = 2, Width = 12, Length = 25.0 Slip 1 fee is 800.0 with 10% discount is 720.0 Slip 2 fee is 900.0 with 20% discount is 720.0 Press any key to continue.,5.9 重载方法,Java使用异常来通知在系统运行时可能出现的错误、问题和其他异常情况 在Java中,异常也是对象,5.10 处理异常,Java 使用5个关键字来处理异常:try, catch, finally, throw, throws. 客户端使用try, catch,finally, 服务器端使用:throw,throws,5.10 处理异常,客户端每次调用可能会创建和抛出异常的方法时,都要将其调用的代码放置于try代码块中。 服务器方法会通过关键字throws包含在其头内来抛出异常 客户端会在catch代码块中捕获异常并处理 final代码块可选,一旦包含在内,不管是否捕获异常都会执行,5.10 处理异常,1.slipId的数据验证,设Bradshaw码头所连接的船台永远都不会多于50个。 需要在setSlipId setter method中验证传递给它的Id值是否在150范围内. 如果某方法准备创建和抛出异常,其头必须包含关键字throws.,5.10 处理异常,扩展后的setSlipId为: public void setSlipId(int anId) throws Exception 在此方法中检查接收到的参数值是否在合理的范围内,如果超出了范围,则对Exception进行实例化,并将其抛出。 注意不要在if语句中编写数字50,可以向Slip类中添加常量MAXIMUM_NUMBER_OF_SLIPS.,5.10 处理异常,public void setSlipId(int anId) throws Exception / reject slip Id if maximum if (anId MAXIMUM_NUMBER_OF_SLIPS) Exception e = new Exception(Slip ID not between 1 ,5.10 处理异常,2. width的数据验证,setWidth方法中的width参数值为:10,12,14,16。 首先向Slip类中添加数组来存储有效的宽度值: private static final int VALID_SLIP_WIDTHS = 10,12,14,16; 下面向setWidth头中添加throws Exception. public void setWidth(int aWidth) throws Exception;,5.10 处理异常,public void setWidth(int aWidth) throws Exception boolean validWidth = false; for (int i = 0; i VALID_SLIP_WIDTHS.length ,5.10 处理异常,带有数据验证的Slip类定义: 在此示例中,构造函数方法实际调用的是setter方法。 由于setter方法可能会抛出异常,因此构造方法头必须包括 throws Exception.,5.10 处理异常,public class Slip / attributes private int slipId; private int width; private double slipLength; / static attribute variable private static int numberOfSlips = 0; / static constants for default attribute values private static final int DEFAULT_WIDTH = 12; private static final int DEFAULT_SLIP_LENGTH = 25; / static constants for data validation private static final int MAXIMUM_NUMBER_OF_SLIPS = 50; private static final int VALID_SLIP_WIDTHS = 10,12,14,16;,5.10 处理异常,/ constructor with 3 parameters public Slip(int anId, int aWidth, double aSlipLength) throws Exception / invoke setters to populate attributes setSlipId(anId); setWidth(aWidth); setSlipLength(aSlipLength); numberOfSlips+; / constructor with 1 parameter public Slip(int anId) throws Exception / invoke 3-parameter constructor with default width ,5.10 处理异常,public double leaseSlip() double fee; switch(width) case 10: fee = 800; break; case 12: fee = 900; break; case 14: fee = 1100; break; case 16: fee = 1500; break; default: fee = 0; return fee; / override leaseSlip public double leaseSlip(double aDiscountPercent) double fee = this.leaseSlip(); double discountedFee = fee * (100 - aDiscountPercent)/100; return discountedFee ; ,5.10 处理异常,/ setter methods public void setSlipId(int anId) throws Exception / reject slip Id if maximum if (anId MAXIMUM_NUMBER_OF_SLIPS) Exception e = new Exception(Slip ID not between 1 ,5.10 处理异常,public void setWidth(int aWidth)throws Exception boolean validWidth = false; for(int i = 0; i VALID_SLIP_WIDTHS.length ,5.10 处理异常,public void setSlipLength(double aSlipLength) slipLength = aSlipLength; / getter methods public int getSlipId() return slipId; public int getWidth() return width; public double getSlipLength() return slipLength; / static method public static int getNumberOfSlips() return numberOfSlips;,5.10 处理异常,/ toString public String toString() String info; info = Slip: Id = + getSlipId() + , Width = + getWidth() + , Length = + getSlipLength(); return info; ,5.10 处理异常,public class TesterSix public static void main(String args) Slip firstSlip = null; try / force exception with invalid slip Id firstSlip = new Slip(150, 10, 25);System.out.println(firstSlip.tellAboutSelf(); catch (Exception n) / display exception message System.out.println(n); try / force exception with invalid width firstSlip = new Slip(1, 15, 25); System.out.println(firstSlip.tellAboutSelf(); ,5.10 处理异常,catch (Exception n) / display exception message System.out.println(n); finally System.out.println(finally block is always executed); try / create a slip using valid id ,5.10 处理异常,java.lang.Exception: Slip ID not between 1 & 50 java.lang.Exception: Invalid Slip Width finally block is always executed Slip: Id = 2, Width = 10, Length = 25.0 finally block is always executed Press any key to continue.,5.10 处理异常,
展开阅读全文