1、对象的类型转换
- 子类对象转换成父类对象
1 class A 2 { 3 public void func1() 4 { 5 System.out.println("A func1 is calling"); 6 } 7 public void func2() 8 { 9 func1(); 10 System.out.println("****"); 11 } 12 } 13 class B extends A 14 { 15 public void func1() 16 { 17 System.out.println("B func1 is calling"); 18 } 19 public void func3() 20 { 21 System.out.println("B func3 is calling"); 22 } 23 } 24 class C 25 { 26 public static void main(String [] args) 27 { 28 B b=new B(); 29 callA(b); 30 A a=b; 31 callA(a); 32 callA(new B()); 33 } 34 public static void callA(A a) 35 { 36 a.func1(); 37 a.func2(); 38 } 39 } 40 /* 41 F:java_examplelesson6>java C 42 B func1 is calling 43 B func1 is calling 44 **** 45 B func1 is calling 46 B func1 is calling 47 **** 48 B func1 is calling 49 B func1 is calling 50 **** 51 */
根据上述代码,可以很明显的看到,系统直接将子类对象b作为形参赋值给了父类A的引用类型变量,这是一个隐式自动类型转换过程。用类比的方式来解释,我们可以将A类看作是人类,B类看作是男性,男性肯定是属于人类的,那么将男性看作为人类,是很自然的事情。但是,自然界中,人类可以直接认为是男性么,答案肯定是否定的~既然如此,那么父类对象隐式转换成子类对象么?
- 父类对象转换成子类对象
通过上面打印出来的结果,我们可以看到,调用的是B类中的方法,那现在在callA()中加一个a.func3();public static void callA(A a)
......
public static void callA(A a)
{
a.func1();
a.func2();
a.func3();
}
......
编译之后就报错了,找不到a.func3().这也就说明,虽然我们知道这个函数中的a实际传进来的是b,但是程序编译过程中,它只知道A中没有func3(),所以编译未通过。
那我们再改动一下,
1 class C 2 { 3 public static void main(String [] args) 4 { 5 B b=new B(); 6 callA(b); 7 A a=b; 8 callA(new A()); 9 } 10 public static void callA(A a) 11 { 12 B b=(B)a; 13 b.func1(); 14 b.func2(); 15 b.func3(); 16 } 17 } 18 /* 19 F:java_examplelesson6>java C 20 B func1 is calling 21 B func1 is calling 22 **** 23 B func3 is calling 24 Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B 25 at C.callA(lesson6.java:12) 26 at C.main(lesson6.java:8) 27 28 */
加了强制类型转换之后代码编译通过,但运行不成功。
为了解决这个问题,我们需要引入instanceof操作符
1 class C 2 { 3 public static void main(String [] args) 4 { 5 B b=new B(); 6 callA(b); 7 A a=b; 8 callA(new A()); 9 } 10 public static void callA(A a) 11 { 12 if(a instanceof B) 13 { 14 B b=(B)a; 15 b.func1(); 16 b.func2(); 17 b.func3(); 18 } 19 a.func1(); 20 a.func2(); 21 22 } 23 }
引入instanceof操作符来判断是否一个类实现了某个接口,也可以判断一个实例对象是否属于一个类,语法为
对象 instanceof 类(接口) 其返回值是布尔型。
2、Object类
Object类是所有类的父类,如果一个类没有使用extends关键字明确的标识继承另一个类,那么这个类就默认继承Object类。因此,Object类是Java中最高层的类,是所有类的超类。也就是说,所有类都是有Object衍生出来的,所以Object的方法适用于所有类
public class Student
{
...
}
等价于:
public class Student extends Object
{
...
}
1 class Student 2 //public class Student 3 //一个Java文件中只能有一个public的类,而且这个类必须和这个java文件同名 4 { 5 private String name; 6 private int age; 7 public Student(String name,int age) 8 { 9 this.name=name; 10 this.age=age; 11 } 12 public boolean equals(Object obj) 13 { 14 Student st=null; 15 if(obj instanceof Student) 16 { 17 st = (Student)obj; 18 if((st.name==name) && (st.age==age)) 19 return true; 20 else 21 return false; 22 } 23 else 24 return false; 25 } 26 public static void main(String [] args) 27 { 28 Student st1=new Student("Jane",23); 29 Student st2=new Student("Mike",23); 30 if(st1.equals(st2)) 31 System.out.println("They are the same!"); 32 else 33 System.out.println("They are not the same!"); 34 } 35 } 36 /* 37 F:java_examplelesson6>java Student 38 They are not the same! 39 */