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

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

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()方法得到了统一,所以即使出现了再多的子类,方法也不需要进行修改了.注意:在子类的操作中,尽量向父类靠拢,即如果此时子类自己扩充了父类的方法,那么这些方法也无法直接使用了(可以使用向下转型实现).

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值