tonglin0325的个人主页

Java对象的多态性(转型)

多态性在面向对象中主要有两种体现:

<1>方法的重载与覆写#

<2>对象的多态性#

向上转型:子类对象–>父类对象,向上转型会自动完成

向下转型:父类对象–>子类对象,向下转型时,必须明确地指明转型的子类类型

 

对象的向上转型#

虽然使用的父类对象调用fun1方法,但是实际上调用的方法是被子类覆写过的方法,也就是说,如果对象发生了向上转型关系后,所调用的方法一定是被子类覆写过的方法。

但是父类的a无法调用b类中的fun3方法,因为这个方法只在子类中定义,而没有在父类中定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class C_1{												// 定义接口C_1
public void fun1(){ //定义fun1()方法
System.out.println("C_1--->public void fun1");
}

public void fun2(){ //定义fun2()方法
this.fun1();
}
}

class D_1 extends C_1{ //子类D_1继承父类C_1
public void fun1(){
System.out.println("D_1--->public void fun1"); //覆写父类中的fun1()方法
}

public void fun3(){
System.out.println("D_1--->public void fun3"); //子类自己定义方法
}
}

// 对象的多态性,对象向上转型
public class ploy_up_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
D_1 b = new D_1(); //定义子类的实例化对象
C_1 a = b; //声明一个父类,发生向上转型的关系,子类赋值给父类
a.fun1(); //此方法被子类覆写过,虽然a是父类,但是调用的是子类的fun1()方法
}

}

 

对象的向下转型#

在子类中调用了父类中的fun2方法,fun2方法要调用fun1方法,但是此时fun1方法已经被子类覆写过了,所以调用fun2方法的时候还是调用被子类覆写过的方法

在进行对象的向下转型之前,必须首先发生对象的向上转型,否则将出现对象转换异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class C_1{												// 定义接口C_1
public void fun1(){ //定义fun1()方法
System.out.println("C_1--->public void fun1");
}

public void fun2(){ //定义fun2()方法
this.fun1();
}
}

class D_1 extends C_1{ //子类D_1继承父类C_1
public void fun1(){
System.out.println("D_1--->public void fun1"); //覆写父类中的fun1()方法
}

public void fun3(){
System.out.println("D_1--->public void fun3"); //子类自己定义方法
}
}

// 对象的多态性,对象向上转型
public class ploy_up_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
// D_1 b = new D_1(); //定义子类的实例化对象
// C_1 a = b; //声明一个父类,发生向上转型的关系,子类赋值给父类
// a.fun1(); //此方法被子类覆写过,虽然a是父类,但是调用的是子类的fun1()方法

C_1 c = new D_1(); //声明一个父类,发生了向上转型,子类赋值给父类
D_1 d = (D_1)c; //声明的父类强制转换成子类,发生了向下转型关系
d.fun1();
d.fun2();
d.fun3();
}

}

 

多态的应用

设计一个方法,要求此方法可以接受A类的任意子类对象,并调用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class C_1{												// 定义接口C_1
public void fun1(){ //定义fun1()方法
System.out.println("C_1--->public void fun1");
}

public void fun2(){ //定义fun2()方法
this.fun1();
}
}

class D_1 extends C_1{ //子类D_1继承父类C_1
public void fun1(){
System.out.println("D_1--->public void fun1"); //覆写父类中的fun1()方法
}

public void fun3(){
System.out.println("D_1--->public void fun3"); //子类自己定义方法
}
}

class E_1 extends C_1{ //子类E_1继承父类C_1
public void fun1(){
System.out.println("E_1--->public void fun1"); //覆写父类中的fun1()方法
}

public void fun5(){
System.out.println("E_1--->public void fun3"); //子类自己定义方法
}
}

// 对象的多态性,对象向上转型
public class ploy_up_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
// D_1 b = new D_1(); //定义子类的实例化对象
// C_1 a = b; //声明一个父类,发生向上转型的关系,子类赋值给父类
// a.fun1(); //此方法被子类覆写过,虽然a是父类,但是调用的是子类的fun1()方法

// C_1 c = new D_1(); //声明一个父类,发生了向上转型,子类赋值给父类
// D_1 d = (D_1)c; //声明的父类强制转换成子类,发生了向下转型关系
// d.fun1();
// d.fun2();
// d.fun3();

fun(new C_1()); //传递C_1类的实例,产生向上转型
fun(new D_1()); //传递D_1类的实例,产生向上转型
}

public static void fun(C_1 c){ //接收父类对象,不用写多次分别接收子类对象
c.fun1();
}
}