一、使用 instanceof 操作符判断对象类型
当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生 ClassCastException 异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使用 instanceof 操作符来完成。 可以使用 instanceof 操作符判断是否一个类实现了某个接口,也可以用它来判断一个对象是否属于一个类。
instanceof 的语法格式 :
myobject instanceof ExampleClass
myobject :某类的对象引用
ExampleClass : 某个类
使用 instanceof 操作符的表达式返回值为布尔值。如果返回值为 true ,说明 myobject 对象为 ExampleClass 的实例对象;如果返回值为 false ,说明 myobject 对象不是 ExampleClass 的实例对象。
instanceof 是 Java 语言的关键字,在 Java 语言中的关键字都是小写。
eg :创建类,和 3 个内部类 Quadrangle 、 Square 、Anything 。其中 Parallelogram 类和 Square 类继承 Quadrangle 类,在 Parallelogram 类的主方法中分别创建这些类的对象,然后使用 instanceof 操作符判断它们的类型并输出结果。
class Quadrangle{
public static void draw(Quadrangle q){
//SomeSentence
}
class Square extends Quadrangle{
//SomeSentence
}
class Anything{
//SomeSentence
}
public class Parallelogram extends Quadrangle{
public static void main(String[] args){
Quadrangle q = new Quadrangle(); //实例化父类对象
//判断父类对象是否为 Parallelogram 子类的一个实例
if(q instanceof Parallelogram){
Parallelogram p = (Parallelogram) q ; //向下转型操作
}
//判断父类对象是否为 Paralelogram 子类的一个实例
if(q instanceof Square){
Square s = (Square) q ; //进行向下转型操作
}
//由于 q 对象不为 Anything 类的对象,所以这条语句是错误的
//System.out.println(q instanceof Anything);
}
}
将 instanceof 操作与向下转型操作结合使用,在程序中定义了两个子类,即平行四边形类和正方形类,这两个类分别继承四边形类。在主方法中首先创建四边形类对象,然后使用 instanceof 操作符判断四边形类对象是否为平行四边形类的一个实例,是否为正方形类的一个实例,如果判断结果为 true ,将进行向下转型操作。
二、方法的重载
构造方法的名称已经有类名决定,所以构造方法只有一个名称,但如果希望以不同的方式来实例化对象,就需要使用多个构造方法来完成。由于这些构造方法都需要根据类名进行命名,为了让方法名相同而形参不同的构造方法同时存在,必须用到“方法重载”。虽然方法重载起源于构造方法,但是它也可以应用到其他方法中。
方法的重载就是在同一个类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。
eg :创建类,在类中编写 add() 方法的多个重载形式,然后再主方法中分别输出这些方法的返回值。
public class OverLoadTest {
public static int add(int a,int b) { //定义一个方法
return a + b ;
}
public static double add(double a,double b) { //定义与第一个方法名称相同,类型不同的方法
return a + b ;
}
public static int add(int a) { //定义与第一个方法参数不同的方法
return a ;
}
public static int add(int a,double b) { //定义成员方法
return 1 ;
}
public static int add(double a,int b) { //定义一个参数顺序不同的方法
return 1;
}
public static void main(String[] args) {
System.out.println("调用 add(int,int)方法:" + add(1, 2));
System.out.println("调用 add(double,double)方法:" + add(2.1, 3.3));
System.out.println("调用 add(int)方法:" + add(1));
}
}
运行结果为 :
调用 add(int,int)方法:3
调用 add(double,double)方法:5.4
调用 add(int)方法:1
在例子中定义了 5 个方法,在这 5 个方法中,前两个方法的参数类型不同,并且方法的返回值类型也不同,所以这两个方法构成重载关系;前两个方法与第 3 个方法相比,第 3 个方法的参数个数少于前两个方法,所以这 3 个方法也构成了重载关系;最后两个方法相比,发现除了参数的出现顺序不同之外,其他都相同,这样同样可以根据这个区别将两个方法构成重载关系。
虽然在方法重载中可以使用两个方法的返回值不同,但只有返回值不同并不足以区分两个方法的重载,还需要通过参数的个数以及参数的类型来设置。
编辑器是利用方法名、方法各参数类型和参数的个数以及参数的顺序来确定类中的方法是否唯一。方法的重载使得方法以统一的名称被管理,是程序代码有条理。
eg :参数的个数可以确定两个方法是否具有重载关系时,定义不定长参数方法,也是一个 add() 重载方法。
public static int add(int ... a){ //定义不定长参数方法
int s=0;
for(int i=0;i<s.length;i++){
s+=a[i]; //做参数累计操作
return s; //将结果返回
}
}
不定长方法的语法 :
返回值 方法名(参数数据类型 ··· 参数名称)
在参数列表中使用 “ ··· ”形式定义不定长参数,其实这个不定长参数 a 就是一个数组,编译器会将 (int ... a )这种形式看做是 (int[] a),所以在 add() 方法体做累加操作时使用到了 for 循环语句,在循环中是根据数值 a 的长度作为循环条件的,最后将累加结果返回。
eg : 创建类,在类中编写 add() 方法的多种重载形式,并编写该方法的不定长参数形式。然后再主方法中太哦用这些重载方法,并输出返回值。
public class OverLoadTest2 {
public static int add(int a,int b) { //定义一个方法
return a + b ;
}
public static double add(double a,double b) { //定义与第一个方法名称相同,类型不同的方法
return a + b ;
}
public static int add(int a) { //定义与第一个方法参数不同的方法
return a ;
}
public static int add(int a,double b) { //定义成员方法
return 1 ;
}
public static int add(double a,int b) { //定义一个参数顺序不同的方法
return 1;
}
public static int add(int ... a ) { //定义不定长参数方法
int s=0;
for (int i=0;i<a.length;i++)
//根据参数个数做循环操作
s+=a[i]; //将每个参数累加
return s; //将计算结果返回
}
public static void main(String[] args) {
System.out.println("调用 add(int,int)方法:" + add(1, 2));
System.out.println("调用 add(double,double)方法:" + add(2.1, 3.3));
System.out.println("调用 add(int)方法:" + add(1));
System.out.println("调用 不定长参数方法1:" + add(1,2,3,4,5,6,7,8,9));
System.out.println("调用 不定长参数方法2:" + add(1));
}
}
运行结果为 :
调用 add(int,int)方法:3
调用 add(double,double)方法:5.4
调用 add(int)方法:1
调用 不定长参数方法1:45
调用 不定长参数方法2:1