对象和类(下)
来源:互联网 发布:北京 db2数据库培训 编辑:程序博客网 时间:2024/06/14 12:21
- 对象和类(下)
- 数组
1. 对象和类(下)
1.1. 方法的重载
1.1.1. 方法的签名
方法的签名包含如下两个方面:方法名和参数列表。
Java语法规定,一个类中不可以有两个方法签名完全相同的方法,即:一个类中不可以有两个方法的方法名和参数列表都完全相同,但是,如果一个类的两个方法只是方法名相同而参数列表不同,是可以的。下面看如下代码:
- public class Cashier {
- public boolean pay(double money) { … }
- public boolean pay(double money) { …}
- }
public class Cashier { public boolean pay(double money) { … } public boolean pay(double money) { …}}
分析如上代码,结论会出现编译错误,因为在同一个类Cashier中的两个方法,签名相同,这在java语法中是不允许出现的。而下面的代码就是正确的:
- public class Cashier {
- public boolean pay(double money) { … }
- public boolean pay(String cardId,
- String cardPwd) { … }
- }
public class Cashier { public boolean pay(double money) { … } public boolean pay(String cardId, String cardPwd) { … }}
可以看到上面的代码,在类Cashier中,虽然pay方法名相同,但是参数列表不同,这样是被允许的,可以正常编译通过。
1.1.2. 方法重载及其意义
假想收款窗口的设计,可以采用两种方式:
- 开设三个窗口,分别用来接收现金,信用卡和支票的交付方式(分别在窗口上标明),用户根据需要选择窗口,并投入指定的物件,如图 – 8所示:
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image001.png)
图- 8
- 开设一个窗口,标为“收款”,可以接收现金,信用卡和支票三种物件。该窗口可以按照输入的不同物件实施不同的操作。例如,如果输入的是现金则按现金支付,如果输入的是信用卡则按信用卡支付,以此类推,如图 – 9所示。
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image002.png)
图- 9
通过对如上两种方式的分析,请问:哪种方式更好一些呢?常规情况下认为,相对于A的方式,B的设计可以降低用户的负担,用户去付款时不需要去找对应的窗口,只需要到收款窗口就可以了, 减少了用户使用时的错误,B的设计更加优雅一些。
按B的设计方式即为方法重载,在Java语言中,允许多个方法的名称相同,但参数列表不同,此种方式称为方法的重载(overload)。
下面的代码即为收款窗口的两种设计方式,可以看出B方式即为方法的重载方式。
- public class PayMoney { //----------A方式
- …payByCash(double money) { }
- …payByCard(String cardId,StringcardPwd) { }
- …payByCheck(String compayName,double money) { }
- }
- public class PayMoney { //-----------B方式
- …pay(double money) { }
- …pay(String cardId,StringcardPwd) { }
- …pay(String compayName,double money) { }
- }
public class PayMoney { //----------A方式 …payByCash(double money) { } …payByCard(String cardId,StringcardPwd) { } …payByCheck(String compayName,double money) { } }public class PayMoney { //-----------B方式 …pay(double money) { } …pay(String cardId,StringcardPwd) { } …pay(String compayName,double money) { } }
通过如上的代码可以看出,按照A的方式若想付款,需在三个方法之中进行选择,不同的方法即为不同的付款方式,而B的方式即为重载方式,若想付款,只需要找到pay方法,只不过,传递不同的参数即可。
1.1.3. 编译时根据签名绑定调用方法
当调用重载的方法时,编译器会在编译时根据签名的不同来绑定调用不同的方法,可以把重载的方法看成是完全不同的方法,只不过,恰好方法名称相同而已。请看下面的两组代码:
重载方法:
- …pay(double money) { }
- …pay(String cardId,StringcardPwd) { }
- …pay(String compayName,double money) { }
…pay(double money) { }…pay(String cardId,StringcardPwd) { }…pay(String compayName,double money) { }
调用方法:(只管调用即可,由编译器来根据签名绑定不同的方法)
- pay(8888.88);
- pay(“12345678”,”666666”);
- pay( “tarena”, 8888.88);
pay(8888.88);pay(“12345678”,”666666”);pay( “tarena”, 8888.88);
1.2. 构造方法
1.2.1. 构造方法语法结构
构造方法是在类中定义的方法, 但不同于其他的方法,构造方法的定义有如下两点规则:
- 构造方法的名称必须与类名相同。
- 构造方法没有返回值,但也不能写void。
如下所示为构造方法的语法:
- 【访问修饰符】类名( ) {
- //构造方法体
- }
【访问修饰符】类名( ) { //构造方法体}
1.2.2. 通过构造方法初始化成员变量
Java语言中的构造方法常常用于实现对对象成员变量的初始化,如下代码展示了构造方法的使用。
- class Cell {
- int row ;
- int col ;
- public Cell (int row1 , int col1){
- row = row1;
- col = col1;
- }
- }
- class TestCell {
- public static void main(String args[ ] ){
- Cell c1 = new Cell( 15 , 6 );
- printCell(c1);
- }
- }
class Cell {int row ;int col ; public Cell (int row1 , int col1){row = row1; col = col1; }}class TestCell {public static void main(String args[ ] ){Cell c1 = new Cell( 15 , 6 ); printCell(c1);}}
可以看出,在创建对象时,构造方法写在new关键字之后,可以理解为:“new”创建了对象,而构造方法对该对象进行了初始化。
1.2.3. this关键字的使用
在上面的代码中,为该构造方法定义了两个参数,分别表示行和列。为了区分于Cell类的成员变量row和col,为两个参数分别取名为row1和col1,这显然不是一种好方法,因为,我们会希望依然使用变量row来表示行,col来表示列,而不是row1和col1。为了解决这个问题,需要使用到this关键字。
this关键字用在方法体中,用于指代调用该方法的当前对象,简单的说:哪个对象调用方法,this指的就是哪个对象。严格来讲,在方法中需要通过this关键字指明当前对象。请看如下代码:
- public void drop ( ) {
- this.row ++;
- }
public void drop ( ) { this.row ++;}
上面的drop()方法可以解释为:将调用该方法对象的成员变量的row加1。很多时候,为了方便起见,在没有歧义的情况下可以省略this,如下所示:
- public void drop ( ) {
- row ++;
- }
public void drop ( ) { row ++;}
在构造方法中,用来初始化成员变量的参数一般和成员变量取相同的名字,这样会有利于代码的可读性,但此处就必须通过this关键字来区分成员变量和参数了,而不能省略this了,如下代码所示:
- public Cell (int row , int col ) {
- this . row = row ;
- this . col = col ;
- }
public Cell (int row , int col ) {this . row = row ;this . col = col ;}
如上的代码中,this.row表示的为Cell类的成员变量,而row为参数变量。
1.2.4. 默认的构造方法
JAVA语法规定,任何一个类都必须含有构造方法,假如源程序中没有定义,则编译器在编译时将为其添加一个无参的空构造方法(此方法称之为“默认的构造方法”)。
例如:先前所定义的Cell类源文件中没有写构造方法,但也可以编译成功,因为在编译时由编译器为其添加了如下的构造方法:
- Cell( ) { }
Cell( ) { }
但是有一个问题需要注意,当类定义了构造方法后,Java编译器将不再添加默认的构造方法,看如下代码:
- class Cell{
- int row;
- int col;
- Cell (int row,int col){
- this.row = row;
- this.col = col;
- }
- }
- public class CellGame {
- public static void main(String[] args) {
- Cell cell = new Cell( ); //编译错误
- }
- }
class Cell{int row; int col;Cell (int row,int col){this.row = row;this.col = col;}}public class CellGame {public static void main(String[] args) { Cell cell = new Cell( ); //编译错误 }}
可以看出,在创建Cell类对象时,发生了一个编译期错误,那是因为,在Cell类中已经定义了Cell(int,int)的构造方法,此时,编译器将不会再提供无参的构造方法了。所以此处发生了编译期错误。
1.2.5. 构造方法的重载
很多时候,为了使用的方便,可以对一个类定义多个构造方法,这些构造方法都有相同的名称(类名),只是方法的参数不同,称之为构造方法的重载。
在创建对象时,Java编译器会根据不同的参数调用来不同构造方法。看如下的几组构造方法的声明及调用。
- 声明:
- Cell ( int row , int col ) {
- }
- 调用:
- Cell c1 = new Cell ( 5 , 6 );
- 声明:
- Cell ( ) {
- }
- 调用:
- Cell c1 = new Cell ( ) ;
- 声明:
- Cell (int row) {
- this(row , row );
- }
- 调用:
- Cell c1 = new Cell ( 5 ) ;
声明:Cell ( int row , int col ) {}调用:Cell c1 = new Cell ( 5 , 6 );声明:Cell ( ) { } 调用:Cell c1 = new Cell ( ) ;声明:Cell (int row) {this(row , row );}调用:Cell c1 = new Cell ( 5 ) ;
可以注意到,在第三段声明的构造方法中,使用了this关键字,在构造方法中可以通过this关键字来调用另外的一个重载的构造方法。this(row,row)调用了第一段声明Cell(int row, int col)构造方法。
2. 数组
2.1. 引用类型数组
2.1.1. 数组是对象
在java中,数组属于引用数据类型,数组对象存放在堆中存储,数组变量属于引用类型,存储数组对象的地址信息,指向数组对象。而数组的元素可以看成数组对象的成员变量(只不过类型全部相同)。看如下代码:
- int[ ] arr = new int [ 3 ]
int[ ] arr = new int [ 3 ]
内存的分配如下图– 4所示:
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image003.png)
图- 4
说明: 在堆内存中分配了数组对象,分配三个int型空间,并将每个元素赋初始值为0,栈中存储对堆中数据的引用,即堆中int数组的首地址。
2.1.2. 引用类型数组的声明
刚刚声明的数组为基本类型数组,除了基本类型数组以外,也可以声明引用类型数组。所谓引用类型数组,即数组元素的类型不是基本类型(int,char,float。。) , 而是引用类型,看如下代码:
- Cell [ ] cells = new Cell [ 4 ] ;
Cell [ ] cells = new Cell [ 4 ] ;
其内存分配如下图– 5所示:
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image004.png)
图- 5
从上图示可以看出,new Cell[4]实际是分配了4个空间用于存放4个Cell类型的引用,并赋初始值为null,而并非是分配了4个Cell类型的对象。
2.1.3. 引用类型数组的初始化
前面所介绍的基本类型数组的默认值同成员变量默认的初始值(如int类型的数组初始值为0),而引用类型数组的默认初始值都是null。
如果希望每一个元素都指向具体的对象,则需要针对每一个数组元素进行“new”运算。与基本类型数组一样,也可以采用静态初始化的方式进行初始化操作。如下代码所示:
- Cell[ ] cells = new Cell[4];
- cells[0] = new Cell(0,4);
- cells[1] = new Cell(1,3);
- cells[2] = new Cell(1,4);
- cells[3] = new Cell(1,5);
Cell[ ] cells = new Cell[4];cells[0] = new Cell(0,4);cells[1] = new Cell(1,3);cells[2] = new Cell(1,4);cells[3] = new Cell(1,5);
等价于:
- Cell[ ] cells = new Cell[ ] {
- new Cell(0,4) ,
- new Cell(1,3) ,
- new Cell(1,4) ,
- new Cell(1,5)
- } ;
Cell[ ] cells = new Cell[ ] {new Cell(0,4) ,new Cell(1,3) ,new Cell(1,4) , new Cell(1,5) } ;
如上数组内存分配图如下图– 6 所示:
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image005.png)
图- 6
2.1.4. 数组的类型是基本类型数组
前面所介绍的数组的元素或为基本类型int,或为引用类型Cell,而数组本身也是一种数据类型,当然也可以作为数组的元素。看下面的代码:
- int [ ][ ] arr = new int[3][ ];
- arr[0] = new int[2];
- arr[1] = new int[3];
- arr[2] = new int[2];
- arr[1][1] = 100;
int [ ][ ] arr = new int[3][ ];arr[0] = new int[2];arr[1] = new int[3];arr[2] = new int[2];arr[1][1] = 100;
分析如上代码可以看出,变量arr指向一个数组,该数组有三个元素,每个元素都是int类型数组,长度分别为2,3,2,arr[1][1]=100表示将arr数组中的第2个元素(数组)的第2个元素赋值为100, 其内存分配如图– 7所示:
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image006.png)
图- 7
对于元素为数组的数组,如果每个数组元素的长度相同,也可以采用如下的方式声明:
- int row = 3, col = 4;
- int[][] arr = new int[row][col];
- for (int i = 0; i < row; i++) {
- for (int j = 0; j < col; j++) {
- arr[i][j] = i * j;
- }
- }
int row = 3, col = 4;int[][] arr = new int[row][col];for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {arr[i][j] = i * j; }}
如上形式的数组可以用来表示类似“矩阵”这样的数据结构(3行4列),如下图-8所示,arr[i][j] 可以认为访问行号为i,列号为j的那个元素。在其他的一些语言中有专门表示这样结构的所谓二维数组;但严格的讲,Java语言中没有真正的二维数组。
![](http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/OOP/DAY02/SUPERDOC/01/index.files/image007.png)
图- 8
- 类和对象(下)
- 对象和类(下)
- 【Java】类和对象(下)
- 【Java】 面向对象 对象和类 下
- 20150609类和对象(下)
- JAVA学习笔记(5)对象和类(下)
- OOP Unit02 对象和类(下) 、 数组
- java对象和json对象之间互相转换(下)
- 【IOS 开发学习总结-OC-8.2】★★ objective-c面向对象之——类和对象(下)
- JAVA 面向对象( 类和对象)
- 面向对象(类和对象)
- 面向对象(对象和类)
- c++学习笔记(四)——类和对象(下)
- OOP Unit06 抽象类、接口和内部类(下) 、 面向对象汇总
- 15-11-30 java 类和对象的理解(下)
- 黑马程序员-面向对象(下)--内部类和异常
- 对象的四大特征(下)--抽象和多态
- JavaScript学习笔记——对象和数组(下)
- Elasticsearch java api 常用查询方法QueryBuilder构造举例
- 喜欢的现代诗 -。-
- 网络常用端口号大全
- 微信小程序 LeanCloud(二)命令行工具使用
- 可重入函数
- 对象和类(下)
- HDU 1548 A strange lift
- ios苹果推送-APNS
- 新手如何在 HBuilder 中创建 web项目
- beanshell的使用
- Javascript常用的简写技术有哪些?
- 解决svn清理失败且路径显示乱码问题
- Nginx 经验小结
- 对象内存管理