java面向对象(十四) 多态性

来源:互联网 发布:廊坊市北商网络 编辑:程序博客网 时间:2024/05/18 01:20

多态性是面向对象的最后一个主要特征,主要有两个方面:方法的多态性,对象的多态性.

1.方法的多态性:

    ①重载:同一个方法名称,根据不同的参数类型及个数完成不同的功能.

    ②覆写:同一个方法,根据操作的子类不同,所完成的功能也不同.

2.对象的多态性:

    ①向上转型:子类对象变为父类对象,格式如下:

父类 父类对象 = 子类实例

    ②向下转型:父类对象变为子类对象,格式如下:

子类 子类对象 = (子类) 父类实例   //强制转换

范例1,向上转型:

class A{public void print(){System.out.println("A.public void print(){}") ;}}class B extends A{public void print(){System.out.println("B.public void print(){}") ;}}public class Demo{public static void main(String args[]){A a = new B() ;a.print() ;}}
运行结果:


以上程序实现了一个对象的向上转型操作,虽然最后调用print()方法的是A类对象,但是由于此时实例化的是子类对象"new B()",而且print()方法被子类覆写了,所以最终调用的就是被B类覆写过的print()方法.

范例2,向下转型:

class A{public void print(){System.out.println("A.public void print(){}") ;}}class B extends A{public void print(){System.out.println("B.public void print(){}") ;}}public class Demo{public static void main(String args[]){A a = new B() ;  //向上转型B b = (B) a ;  //向下转型b.print() ;}}
运行结果:


本程序强制将父类对象变为子类对象,由于本程序在开始实例化的依然是子类对象(new B()),所以最终调用的print()方法依然是被子类覆写过的方法.

范例3:

class A{public void print(){System.out.println("A.public void print(){}") ;}}class B extends A{public void print(){System.out.println("B.public void print(){}") ;}}public class Demo{public static void main(String args[]){A a = new A() ;  //没有转型B b = (B) a ;  //向下转型b.print() ;}}
运行结果:


以上程序在编译时没有任何错误信息,但在实行时出现了"ClassCastException"错误提示,表示的是类转换异常,即两个没有关系的类相互发生了对象的强制转型.(当我们只看A类时,并不知道谁是其子类,但是如果看B类时可以得出它的父类的,在范例2中,通过A a = new B()使A知道了它的子类是B,)由此可得:当对象发生向下转型关系前,一定要首先发生对象的向上转型关系.

既然在发生向下转型的操作中会存在一些问题,我们可以先判断一下再转型.使用instanceof关键字即可(返回boolean值).

范例4:

class A{public void print(){System.out.println("A.public void print(){}") ;}}class B extends A{public void print(){System.out.println("B.public void print(){}") ;}public void getB(){System.out.println("b.getB()") ;}}public class Demo{public static void main(String args[]){A a = new B() ;System.out.println(a instanceof A) ;System.out.println(a instanceof B) ;if(a instanceof B){B b = (B) a ;b.getB() ;}}}
运行结果:


为了日后的操作方便,在写代码时,尽量不要去执行向下转型操作.即子类尽量不要扩充新的方法名称(父类没有的方法名称),应该依据父类定义的操作完善方法.

范例5:

class Person{private String name ;private int age ;public Person(String name , int age){this.name = name ;this.age = age ;}public String getInfo(){return "姓名:" + this.name + ",年龄: " +this.age ;}}class Student extends Person{private String school ;public Student(String name ,int age, String school){super(name,age) ;this.school = school ;}public String getInfo(){return super.getInfo() + ",学校:" +this.school ;   //仅仅是完善!}}public class Demo{public static void main(String args[]){Person per = new Student("张三",20,"清华大学") ;System.out.println(per.getInfo()) ;}}
运行结果:


一切的操作都要以父类为主!!!

范例6:要求定义一个方法,这个方法可以接受A类的任意子类对象.

实现方式1,不使用对象转型,采用方法重载完成:

class A{public void print(){System.out.println("A.public void print(){}") ;}}class B extends A{public void print(){System.out.println("B.public void print(){}") ;}}class C extends A{public void print(){System.out.println("C.public void print(){}") ;}}public class Demo{public static void main(String args[]){fun(new B()) ;fun(new C()) ;}public static void fun(B b){b.print() ;}public static void fun(C c){c.print() ;}}
运行结果:


以上的程序实现了要求,但是!如果A类有5000万个子类,方法重载5000万次.所以,使用对象的向上转型可解决此问题:

实现方式二:

class A{public void print(){System.out.println("A.public void print(){}") ;}}class B extends A{public void print(){System.out.println("B.public void print(){}") ;}}class C extends A{public void print(){System.out.println("C.public void print(){}") ;}}public class Demo{public static void main(String args[]){fun(new B()) ;fun(new C()) ;}public static void fun(A a){a.print() ;} }
运行结果:


本程序在定义fun()方法时直接使用A类作为接收的参数,这样它的所有子类都可以利用对象的向上转型调用fun()方法,此时由于fun()方法得到了统一,所以即使出现了再多的子类,方法也不需要进行修改了.注意:在子类的操作中,尽量向父类靠拢,即如果此时子类自己扩充了父类的方法,那么这些方法也无法直接使用了(可以使用向下转型实现).

最后一句:向上转型居多.

0 0
原创粉丝点击