第五章对象和类 本模块是Java编程语言中讨论面向对象语句及面向对象特征两部分中的第一部分。 object-Oriented Programming Develo ping Graphical User Interfaces ThaW avFondyice andO Nandang 第一节相关问题 讨论一下面的问题与本模块中出现的材料相关: 到目前为止学习的Java编程语言的元素存在于大部分语言中,不管它们是否是面向对象语言 Java编程语言拥有什么特征使它成为一个面向对象语言? 面向对象”这个术语真正的含义是什么? 第二节目标 学完本模块,你便能: 定义封装、多态性以及继承 使用 private及 public访问修饰符 开发程序段创建并初始化一个对象 对一个特殊对象调用一个方法 描述构造函数及方法重载 描述ths引用的用途 讨论为什么Java应用程序代码是可重复使用的 在一个Java程序中,确认 - package语句 Import语句
85 第五章 对象和类 本模块是 Java 编程语言中讨论面向对象语句及面向对象特征两部分中的第一部分。 第一节 相关问题 讨论—下面的问题与本模块中出现的材料相关: - 到目前为止学习的 Java 编程语言的元素存在于大部分语言中,不管它们是否是面向对象语言。 - Java 编程语言拥有什么特征使它成为一个面向对象语言? - “面向对象”这个术语真正的含义是什么? 第二节 目 标 学完本模块,你便能: - 定义封装、多态性以及继承 - 使用 private 及 public 访问修饰符 - 开发程序段创建并初始化一个对象 - 对一个特殊对象调用一个方法 - 描述构造函数及方法重载 - 描述 this 引用的用途 - 讨论为什么 Java 应用程序代码是可重复使用的 - 在一个 Java 程序中,确认: - package 语句 - import 语句
-类、成员函数以及变量 构造函数 重载方 覆盖方法 父类构造函数 第三节对象基础 面向对象程序(OOP)语句能使现实世界中的概念在计算机程序中变成模块。它包括构造程序的特征以及组织数据 和算法的机制。OOP语言有三个特征:封装、多态性及继承。所有这些特征与类的概念是息息相关的 531抽象数据类型 当数据类型是由数据项组成时,可以定义许多程序段或方法在该类型数据上专门运行。当程序语言定义一个基本类 如整数时,它同时也定义了许多运算方法(如加法、减法、乘法和除法),因而它可以在该类型的实例中运行。 在许多程序语言中,一旦一个集合数据类型已经定义,程序员定义应用函数在该类型的变量上运行,该变量在代 码和集合类型(除非可能在命名规则中)之间无任何联系。 有些程序语言,包括Java,允许在数据类型的声明和操作该类型变量的代码的声明之间有紧密的联系。这种联系通 常被称为抽象数据类型 532类和对象 Java编程语言中的抽象数据类型概念被认为是clas。类给对象的特殊类型提供定义。它规定对象内部的数据,创建 该对象的特性,以及对象在其自己的数据上运行的功能。因此类就是一块模板。 Objects是在其类模块上建立起来的,很 象根据建筑图纸来建楼。同样的图纸可用来建许多楼房,而每栋楼房是它自己的一个对象。 应该注意,类定义了对象是什么,但它本身不是一个对象。在程序中只能有类定义的一个副本,但可以有几个对象 作为该类的实例。在Java编程语言中使用new运算符实例化一个对象。 在类中定义的数据类型用途不大,除非有目的地使用它们。方法定义了可以在对象上进行的操作,换言之,方法定 义类来干什么。因此Java编程语言中的所有方法都属于一类。不象C++程序,Java软件程序不可能在类之外的全局区域 有方法。 看一个类的例子 class EmpInfo i string name String designation String department
86 - 类、成员函数以及变量 - 构造函数 - 重载方法 - 覆盖方法 - 父类构造函数 第三节 对象基础 面向对象程序(OOP)语句能使现实世界中的概念在计算机程序中变成模块。它包括构造程序的特征以及组织数据 和算法的机制。OOP 语言有三个特征:封装、多态性及继承。所有这些特征与类的概念是息息相关的。 5.3.1 抽象数据类型 当数据类型是由数据项组成时,可以定义许多程序段或方法在该类型数据上专门运行。当程序语言定义一个基本类 型如整数时,它同时也定义了许多运算方法(如加法、减法、乘法和除法),因而它可以在该类型的实例中运行。 在许多程序语言中,一旦一个集合数据类型已经定义,程序员定义应用函数在该类型的变量上运行,该变量在代 码和集合类型(除非可能在命名规则中)之间无任何联系。 有些程序语言,包括 Java,允许在数据类型的声明和操作该类型变量的代码的声明之间有紧密的联系。这种联系通 常被称为抽象数据类型。 5.3.2 类和对象 Java 编程语言中的抽象数据类型概念被认为是 class。类给对象的特殊类型提供定义。它规定对象内部的数据,创建 该对象的特性,以及对象在其自己的数据上运行的功能。因此类就是一块模板。Objects 是在其类模块上建立起来的,很 象根据建筑图纸来建楼。同样的图纸可用来建许多楼房,而每栋楼房是它自己的一个对象。 应该注意,类定义了对象是什么,但它本身不是一个对象。在程序中只能有类定义的一个副本,但可以有几个对象 作为该类的实例。在 Java 编程语言中使用 new 运算符实例化一个对象。 在类中定义的数据类型用途不大,除非有目的地使用它们。方法定义了可以在对象上进行的操作,换言之,方法定 义类来干什么。因此 Java 编程语言中的所有方法都属于一类。不象 C++程序,Java 软件程序不可能在类之外的全局区域 有方法。 看一个类的例子: class EmpInfo { String name; String designation; String department;
这些变量name, designation和 department)被称为类 Emplnfo的成员 实例化一个对象,创建它,然后如下所述对其成员赋值 EmpInfo employee new Emp Info();//creates ins tance employee name Robert Javaman // initializes employee des ignation ="Manager "; // the three employee department ="Co ffee shop ";// members Emplnfo类中的 employee对象现在就可以用了。例如: System. out. println(emp loyee name +"is"+ employee designation employee department) 打印结果如下 Robert Javaman is Manager at Coffee Shop 如下所述,现在可以在类中放入方法 printi()来打印数据了。数据和代码可以封装在一个单个实体中,这是面向对象语 言的一个基本特征。定名为prn()的代码段可以被作为一个方法而调用,它是术语“函数”的面向对象的称法 class EmpInfo string designation String depa d print()t System. out. println(name + is " designation t at department)i 旦对象被创建并被实例化,该方法就打印出类成员的数据。按下述步骤实现 EmpInfo employee new Emp Info();// creates instance employeename Robert Javaman "i// initializes employee designation =Manager / the three employee department ="Coffee Shop / membe employee. print()i// prints the details 看看集合数据类型 My Date和对下一个日期赋值的函数 tomorrow()
87 } 这些变量(name, designation 和 department)被称为类 EmpInfo 的成员。 实例化一个对象,创建它,然后如下所述对其成员赋值: EmpInfo employee = new EmpInfo(); //creates instance employee.name = Robert Javaman "; // initializes employee.designation = " Manager " ; // the three employee.department = " Coffee Shop " ; // members EmpInfo 类中的 employee 对象现在就可以用了。例如: System.out.println(employee.name + " is " + employee.designation + " at " + employee.department); 打印结果如下: Robert Javaman is Manager at Coffee Shop 如下所述,现在可以在类中放入方法 print( )来打印数据了。数据和代码可以封装在一个单个实体中,这是面向对象语 言的一个基本特征。定名为 print( )的代码段可以被作为一个方法而调用,它是术语“函数”的面向对象的称法。 class EmpInfo { String name; String designation; String department; void print() { System.out.println(name + " is " + designation + " at " + department); } } 一旦对象被创建并被实例化,该方法就打印出类成员的数据。按下述步骤实现: EmpInfo employee = new EmpInfo(); // creates instance employee.name = " Robert Javaman " ; // initializes employee.designation = " Manager " ; // the three employee.department = " Coffee Shop " ; // members employee.print();// prints the details 看看集合数据类型 MyDate 和对下一个日期赋值的函数 tomorrow( )
按如下所述在 My Date类型和 tomorrow()方法之间创建一种联系 public ncrement day 注一本声明中的“priv 方法不是(作为分离的实体)在数据上运行,而数据(作为对象的一部分)对它本身进行操作。 这个注释表明行为是由对象而不是在对象上完成的。记住,可以用点记号来指向 MyDate类中的字段。 这就意味着“ My Date对象的day字段由变量d调用。于是,前面的例子“ My Date对象的 tomorrow行为由变量d调 用”,换言之,就是d对象对它本身进行 tomorrow()运算 方法是一个对象的属性并且能作为单个单元的一部分与它所在对象的数据发生密切的相互作用,这个是一个关键的 面向对象的概念。(如果与这个概念不同,即,方法是分离的实体,从外部引入,作用在数据上。) message passing(消息 传递)这个术语通常用来表达这样一个概念,即:指示一个对象在它本身数据上做某项工作,一个对象的方法定义了该 对象能在它本身数据上做什么 533定义方法 定义方法 方法声明采取这样的格式 ([]) [throws ]i) public void addDays(int day s)t Java编程语言使用一种与其它语言,尤其是C和C++,非常相似的办法来定义方法。其声明采用以下格式: ([])[throws ][) 可以是任何合法标识符,并带有用己经使用的名称为基础的某些限制条件 return_type>表示方法返回值的类型。如果方法不返回任何值,它必须声明为void(空)。Java技术对返回值是很 严格的,例如,如果声明某方法返回一个int值,那么方法必须从所有可能的返回路径中返回一个nt(只能在等待返回该 int值的上下文中被调用。) 段能承载许多不同的修饰符,包括公共的、受保护的,以及私有的。公共访问修饰符表示方法可以从 任何其它代码调用。私有表示方法只可以由该类中的其它方法来调用。受保护将在以后的课程中讨论 允许将参数值传递到方法中。列举的元素由逗号分开,而每一个元素包含一个类型和一个标识
88 按如下所述在 MyDate 类型和 tomorrow( )方法之间创建一种联系: public class MyDate { private int day, month, year; public void tomorrow() { // code to increment day } } 注—本声明中的“private”一词将在后文描述。 方法不是(作为分离的实体)在数据上运行,而数据(作为对象的一部分)对它本身进行操作。 MyDate d = new MyDate(); d.tomorrow(); 这个注释表明行为是由对象而不是在对象上完成的。记住,可以用点记号来指向 MyDate 类中的字段。 这就意味着“MyDate 对象的 day 字段由变量 d.调用。于是,前面的例子“MyDate 对象的 tomorrow 行为由变量 d.调 用” ,换言之,就是 d 对象对它本身进行 tomorrow()运算。 方法是一个对象的属性并且能作为单个单元的一部分与它所在对象的数据发生密切的相互作用,这个是一个关键的 面向对象的概念。(如果与这个概念不同,即,方法是分离的实体,从外部引入,作用在数据上。)message passing(消息 传递)这个术语通常用来表达这样一个概念,即:指示一个对象在它本身数据上做某项工作,一个对象的方法定义了该 对象能在它本身数据上做什么。 5.3.3 定义方法 定义方法 方法声明采取这样的格式: ([]) [throws ] {} public void addDays(int days) { } Java 编程语言使用一种与其它语言,尤其是 C 和 C++,非常相似的办法来定义方法。其声明采用以下格式: ([]) [throws ] {} 可以是任何合法标识符,并带有用已经使用的名称为基础的某些限制条件。 表示方法返回值的类型。如果方法不返回任何值,它必须声明为 void(空)。Java 技术对返回值是很 严格的,例如,如果声明某方法返回一个 int 值,那么方法必须从所有可能的返回路径中返回一个 int(只能在等待返回该 int 值的上下文中被调用。) 段能承载许多不同的修饰符,包括公共的、受保护的,以及私有的。公共访问修饰符表示方法可以从 任何其它代码调用。私有表示方法只可以由该类中的其它方法来调用。受保护将在以后的课程中讨论。 允许将参数值传递到方法中。列举的元素由逗号分开,而每一个元素包含一个类型和一个标识
付 throws子句导致一个运行时错误(异常)被报告到调用的方法中,以便以合适的方式处理它。非正 常的情况在中有规定。 例如 public void addDa ys (int days)t 告诉方法的本体,用,来接受表示将天数增加到当前日期中的那个参数。在这种方法中,值是以标识符days 来引用的 534值传递 值传递 ava编程语言只由值传递参数 当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用 对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的 Java编程语言只由值传递参数,也就是说,参数不能由被调用的方法来改变。当一个对象实例作为一个参数传递到 方法中时,参数的值就是对象的引用。对象的内容可以在被调用的方法中改变,但对象引用是永远不会改变的 下面的代码例子可以阐明这一点: // Methods to change the current values public void changeInt (int value) t public void changestr (String value) value new string different )i public void changeobjValue (Pas sTest ref)t ref. ptvalue =99Of ublic static void main (String args[])t
89 符。 throws 子句导致一个运行时错误(异常)被报告到调用的方法中,以便以合适的方式处理它。非正 常的情况在中有规定。 例如: public void addDays(int days) { } 告诉方法的本体,用,来接受表示将天数增加到当前日期中的那个参数。 在这种方法中,值是以标识符 days 来引用的。 5.3.4 值传递 值传递 Java 编程语言只由值传递参数 当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。 对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。 Java 编程语言只由值传递参数,也就是说,参数不能由被调用的方法来改变。当一个对象实例作为一个参数传递到 方法中时,参数的值就是对象的引用。对象的内容可以在被调用的方法中改变,但对象引用是永远不会改变的。 下面的代码例子可以阐明这一点: 1 public class PassTest { 2 3 float ptValue; 4 5 // Methods to change the current values 6 public void changeInt (int value) { 7 value = 55; 8 } 9 10 public void changeStr (String value) { 11 value = new String ( " different " ); 12 } 13 14 public void changeObjValue (PassTest ref) { 15 ref.ptValue = 99.0f; 16 } 17 18 public static void main (String args[]) {
int //C Pass new PassTest ( // Assign the int 28 // Try to change it 30 pt. changeInt (val)i 31 / What is the current value? System. out. println ("Int value is 34 // Assign the stri str new string 38 //Try t It t. changeStr (str) / What is the current value? System. out str)i 43 / Now set the pt value pt. ptvalue =101.0f; // Now change the value of the float // th pt. changeob] Value (pt)i / What is the current value?
90 19 20 String str; 21 int val; 22 23 // Create an instance of the class 24 25 PassTest pt = new PassTest (); 26 // Assign the int 27 val = 11; 28 29 // Try to change it 30 pt.changeInt (val); 31 32 // What is the current value? 33 System.out.println ( " Int value is: " + val); 34 35 // Assign the string 36 str = new String ( " hello " ); 37 38 // Try to change it 39 pt.changeStr (str); 40 41 // What is the current value? 42 System.out.println ( " Str value is: " + str); 43 44 // Now set the ptValue 45 pt.ptValue = 101.0f; 46 47 48 // Now change the value of the float 49 // through the object reference 50 pt.changeObjValue (pt); 51 52 // What is the current value?
System. out. println ("Current ptvalue is:+ pt. ptvalue)i 这个代码输出如下内容: c: \student \source \ java PassTest Int value is: 11 Str value is: hello Current ptva lue is: 99.0 字符串对象是不会被 changer(改变的,但是, Pass Test对象的内容被改变了。 535this引用 s引用 public class Myl private int day, month, yeari public void tomor row()i this day this day li wrap around code 关键字this是用来指向当前对象或类实例的。这里, this day指的是当前对象的day字段 ublic class MyDate t private int day, month, yeari public void tomor row ()i this day this day 1 // wrap around code Java编程语言自动将所有实例变量和方法引用与his关键字联系在一起,因此,使用关键字在某些情况下是多余的。 下面的代码与前面的代码是等同的。 public class MyDate t private int day, month,year public void tomor row()( day day 1;// no this. before day // wrap around code 也有关键字ths使用不多余的情况。如,需要在某些完全分离的类中调用一个方法并将当前对象的一个引用作为参数传
91 53 System.out.println ( " Current ptValue is: " + 54 pt.ptValue); 55 } 56 } 这个代码输出如下内容: c:\student\source\> java PassTest Int value is: 11 Str value is: hello Current ptValue is: 99.0 字符串对象是不会被 changeStr()改变的,但是,PassTest 对象的内容被改变了。 5.3.5 this 引用 this 引用 public class MyDate { private int day, month, year; public void tomorrow() { this.day = this.day + 1; // wrap around code... } } 关键字 this 是用来指向当前对象或类实例的。这里,this.day 指的是当前对象的 day 字段。 public class MyDate { private int day, month, year; public void tomorrow() { this.day = this.day + 1; // wrap around code... } } Java 编程语言自动将所有实例变量和方法引用与 this 关键字联系在一起,因此,使用关键字在某些情况下是多余的。 下面的代码与前面的代码是等同的。 public class MyDate { private int day, month, year; public void tomorrow() { day = day + 1; // no ` this. ' before ` day ' // wrap around code... } } 也有关键字 this 使用不多余的情况。如,需要在某些完全分离的类中调用一个方法并将当前对象的一个引用作为参数传
递时。例如 Birthday bDay new Birthday (this) 5.3.6数据隐藏 pubic void tomorrow()i this da ublic class DateUser t public static void main(String args[])t Date my date new My Date ()i Mydate. day 21;//i11ega1 在 My Date类的day, month,year声明中使用关键字 private,使从除了在 My Date类本身的方法以外的任何代码中访问 这些成员成为不可能。因此,给 My Date类指定一个声明,下述代码是非法的 public class DateUser t public static void main(String args[])( My Date d= new My d day 21; //illegal! 防止直接访问数据变量看起来奇怪,但它实际上对使用 MyDate类的程序的质量有极大的好处。既然数据的单个项是 不可访问的,那么唯一的办法就是通过方法来读或写。因此,如果要求类成员的内部一致性,就可以通过类本身的方法 来处理。 思考一下允许从外部对其成员进行自由访问的 MyDate类。代码做如下工作将是非常容易的 MyDate d= new My Date () d day = 32: / invalid day d. month= d day = 30: / plausible but wrong d month d month l; // omit check for wrap round 警告一这些和其它类似的赋值导致了在 My Date对象字段中无效的或不一致的值。这种情形是不可能马上作为问题暴露出 来的,但肯定会在某个阶段终止程序 如果类的数据成员没有暴露(被封装在类里),那么,类的用户会被迫使用方法来修改成员变量。这些方法能进行有 效性检查。考虑将下述方法作为 MyDate类的一个部分 ublic void setDay (int targetDay)(
92 递时。例如: Birthday bDay = new Birthday (this); 5.3.6 数据隐藏 数据隐藏 public class Date { private int day, month, year; pubic void tomorrow(){ this.day = this.day +1; // wrap around code… } } public class DateUser { public static void main(String args[]) { Date mydate = new MyDate (); Mydate.day = 21; //illegal! } } 在 MyDate 类的 day,month,year 声明中使用关键字 private,使从除了在 MyDate 类本身的方法以外的任何代码中访问 这些成员成为不可能。因此,给 MyDate 类指定一个声明,下述代码是非法的: public class DateUser { public static void main(String args[]) { MyDate d = new MyDate (); d.day = 21; // illegal! } } 防止直接访问数据变量看起来奇怪,但它实际上对使用 MyDate 类的程序的质量有极大的好处。既然数据的单个项是 不可访问的,那么唯一的办法就是通过方法来读或写。因此,如果要求类成员的内部一致性,就可以通过类本身的方法 来处理。 思考一下允许从外部对其成员进行自由访问的 MyDate 类。代码做如下工作将是非常容易的: MyDate d = new MyDate (); d.day = 32; // invalid day d.month = 2; d.day = 30; // plausible but wrong d.month = d.month + 1; // omit check for wrap round 警告—这些和其它类似的赋值导致了在 MyDate 对象字段中无效的或不一致的值。这种情形是不可能马上作为问题暴露出 来的,但肯定会在某个阶段终止程序。 如果类的数据成员没有暴露(被封装在类里),那么,类的用户会被迫使用方法来修改成员变量。这些方法能进行有 效性检查。考虑将下述方法作为 MyDate 类的一个部分。 public void setDay(int targetDay) {
f (targetDay this days InMonth()) System. err println( invalid day "t targetDay) else i this day target Day. 方法检查就是要看所要求设定的日期是否有效。如果日期无效,方法忽略了请求并打印出了信息。后面将会看到Java编 程语言提供一个更有效的机制来处理溢出的方法参数。但现在,你可以看到Date类对无效日期是受到有效保护的。 -在上例中, days In Month0被指定为Date类中的一个方法。因此,它有一个this值,从这个值上,它可以提取回 所要求的 month和year。由于与成员变量一起使用, daysInMonthO方法的this的使用就多余了。 关于如何正确地调用方法,诸如“参数“月份”的值在对象中必须在有效范围内”的规则被叫做不变量(或前置和后 置条件)。谨慎使用前置条件测试,可使类更容易再次使用,而且在重用中更可靠,因为如果任何方法被误用,使用该类 的程序员能马上发现 537封装 封装 隐藏类的实现细节 迫使用户去使用一个界面去访问数据 使代码更好维护 除了保护对象的数据不被误修改外,在确保所要求的副作用被正确处理的情况下,迫使用户通过方法访问数据能使 类的重用变得更简单。比如,在 My Date类的情形之下,考虑如何构造 tomorrow方法 如果数据完全可以访问,那么类的每一个用户都需要增加day的值,测试当前月份的天数,并处理月终(而且可能 是年终)情形。这就毫无意义而且容易出错。仅管这些要求对日期来说是很好理解的,其它数据类型可能具有鲜为人知 的相似的限制。通过迫使类的用户去使用所提供的 tomorrow方法,保证每个人每次都能连续地并且正确地处理必要的副 作用 数据隐藏通常指的就是封装。它将类的外部界面与类的实现区分开来,隐藏实现细节。迫使用户去使用外部界面, 即使实现细节改变,还可通过界面承担其功能而保留原样,确保调用它的代码还继续工作。这使代码维护更简单。 第四节重载方法名称 重载方法名称 它可如下所示使用: public void println(int 1) public void println(float f) public void println( 参数表必须不同 返回类型可以不同
93 if (targetDay > this.daysInMonth()) { System.err.println( " invalid day " + targetDay); } else { this.day = targetDay; } } 方法检查就是要看所要求设定的日期是否有效。如果日期无效,方法忽略了请求并打印出了信息。后面将会看到 Java 编 程语言提供一个更有效的机制来处理溢出的方法参数。 但现在,你可以看到 Date 类对无效日期是受到有效保护的。 注—在上例中,daysInMonth()被指定为 Date 类中的一个方法。因此,它有一个 this 值,从这个值上,它可以提取回答 询问所要求的 month 和 year。由于与成员变量一起使用,daysInMonth()方法的 this 的使用就多余了。 关于如何正确地调用方法,诸如“参数“月份”的值在对象中必须在有效范围内”的规则被叫做不变量(或前置和后 置条件)。谨慎使用前置条件测试,可使类更容易再次使用,而且在重用中更可靠,因为如果任何方法被误用,使用该类 的程序员能马上发现。 5.3.7 封装 封装 隐藏类的实现细节 迫使用户去使用一个界面去访问数据 使代码更好维护 除了保护对象的数据不被误修改外,在确保所要求的副作用被正确处理的情况下,迫使用户通过方法访问数据能使 类的重用变得更简单。比如,在 MyDate 类的情形之下,考虑如何构造 tomorrow()方法。 如果数据完全可以访问,那么类的每一个用户都需要增加 day 的值,测试当前月份的天数,并处理月终(而且可能 是年终)情形。这就毫无意义而且容易出错。仅管这些要求对日期来说是很好理解的,其它数据类型可能具有鲜为人知 的相似的限制。通过迫使类的用户去使用所提供的 tomorrow()方法,保证每个人每次都能连续地并且正确地处理必要的副 作用。 数据隐藏通常指的就是封装。它将类的外部界面与类的实现区分开来,隐藏实现细节。迫使用户去使用外部界面, 即使实现细节改变,还可通过界面承担其功能而保留原样,确保调用它的代码还继续工作。这使代码维护更简单。 第四节 重载方法名称 重载方法名称 它可如下所示使用: public void println(int i) public void println(float f) public void println() 参数表必须不同 返回类型可以不同
在某些情况下,可能要在同一个类中写几种做同样工作但带有不同参数的方法。考虑一个简单方法,它试图输出参 数的文本表示法。这种方法被称做 printing 现在假设打印每个int,oat, String类型需要不同的打印方法。这是合情合理的,因为各种数据类型要求不同的格式 而且可能要求不同的处理。可以分别创建三种方法,即: println, printfloato和 printStringO。但这是很乏味的。 Java与其它几种编程语言一样,允许对不止一种方法重用方法名称。清楚地说,只有当某种东西能区分实际上需要 哪种方法并去调用它时,它才能起作用。在三种打印方法的情况下,可能在参数的数量和类型的基础上对此进行区分。 通过重用方法名称,可用下述方法结束: public void println(int i) public void println (float f) public void println() 当写代码来调用这些方法中的一种方法时,根据提供的参数的类型选择合适的一种方法 有两个规则适用于重载方法 调用语句的参数表必须有足够的不同,以至于允许区分出正确的方法被调用。正常的拓展晋升(如,单精度类型foat 到双精度类型 double)可能被应用,但是这样会导致在某些条件下的混淆 方法的返回类型可以各不相同,但它不足以使返回类型变成唯一的差异。重载方法的参数表必须不同。 第五节构造并初始化对象 构造并初始化对象 调用 new XXXO来为新对象分配空间会产生如下结果 新对象的空间被分配并被初始化为0或空值 进行了显式的初始化 勾造函数被执行 已经看到,为了给新对象分配空间,如何必须执行调用到 new XXXO。有时还会看到参数被放在括号中,如: new bu (“ press me)。使用关键字new会导致下述情况 首先,新对象的空间被分配并初始化到0或空值。在Java编程语言中,该阶段是不可分的,以确保在分配空间的过 程中不会有大小为随机值的对象 其次,进行显式的初始化。 第三,构造函数被执行,它是一种特殊方法。括号中传递给new的参数被传递给构造函数。 本节讨论这最后两个步骤 5.51显式成员初始化 显式成员初始化 public class Initialized i private int x=5; Date created =new Date Methods go here 如果将简单的赋值表达式放在成员声明中,在对象构造过程中会进行显式成员初始化
94 在某些情况下,可能要在同一个类中写几种做同样工作但带有不同参数的方法。考虑一个简单方法,它试图输出参 数的文本表示法。这种方法被称做 println()。 现在假设打印每个 int,float,String 类型需要不同的打印方法。这是合情合理的,因为各种数据类型要求不同的格式, 而且可能要求不同的处理。可以分别创建三种方法,即:printInt(),printfloat()和 printString()。但这是很乏味的。 Java 与其它几种编程语言一样,允许对不止一种方法重用方法名称。清楚地说,只有当某种东西能区分实际上需要 哪种方法并去调用它时,它才能起作用。在三种打印方法的情况下,可能在参数的数量和类型的基础上对此进行区分。 通过重用方法名称,可用下述方法结束: public void println(int i) public void println(float f) public void println() 当写代码来调用这些方法中的一种方法时,根据提供的参数的类型选择合适的一种方法。 有两个规则适用于重载方法: 调用语句的参数表必须有足够的不同,以至于允许区分出正确的方法被调用。正常的拓展晋升(如,单精度类型 float 到双精度类型 double)可能被应用,但是这样会导致在某些条件下的混淆。 方法的返回类型可以各不相同,但它不足以使返回类型变成唯一的差异。重载方法的参数表必须不同。 第五节 构造并初始化对象 构造并初始化对象 调用 new XXX()来为新对象分配空间会产生如下结果: 新对象的空间被分配并被初始化为 0 或空值 进行了显式的初始化 构造函数被执行 已经看到,为了给新对象分配空间,如何必须执行调用到 new XXX()。有时还会看到参数被放在括号中,如:new Button (“press me”)。使用关键字 new 会导致下述情况: 首先,新对象的空间被分配并初始化到 0 或空值。在 Java 编程语言中,该阶段是不可分的,以确保在分配空间的过 程中不会有大小为随机值的对象。 其次,进行显式的初始化。 第三,构造函数被执行,它是一种特殊方法。括号中传递给 new 的参数被传递给构造函数。 本节讨论这最后两个步骤。 5.5.1 显式成员初始化 显式成员初始化 public class Initialized { private int x = 5; private String name = " Fred " ; private Date created = new Date(); // Methods go here ... } 如果将简单的赋值表达式放在成员声明中,在对象构造过程中会进行显式成员初始化