Java基础_学习笔记_13_类的多态性(一)

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_example\lesson6>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_example\lesson6>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_example\lesson6>java Student
38 They are not the same!
39 */

 

posted @ 2015-11-10 16:17  巅峰之旅  阅读(190)  评论(0编辑  收藏  举报