类的多态性

一、子类重定义父类成员

当子类从父类继承来的成员不能满足子类需要时,子类不能删除它们,但可以重定义它们,修改或扩充父类成员方法的功能,使父类成员能够适应子类新的需求。

重定义包括:

1、重定义父类的成员变量,则隐藏父类的成员变量

2、重定义父类的成员方法,如果参数列表和返回值类型均相同,则覆盖父类的成员方法;如果参数列表不同,则重载父类的成员方法。如果参数列表相同而返回值类型不同,编译器会指出存在二义性的语法错误。

子类重定义父类成员表现出多态性,父类对象引用父类成员,子类对象引用子类成员。重定义的同名成员之间不会产生冲突和混乱。在子类的实例方法中,可使用super引用访问被子类隐藏的父类同名成员变量,调用被子类覆盖的父类同名成员方法,语法格式如下:

super.成员变量

super.成员方法([参数列表])

super将当前对象作为其父类的一个实例引用。注意:静态方法中不能使用super引用

覆盖父类方法时,子类的访问权限不能小于父类方法的访问权限

二、类型的多态(Student类是Person类的子类)

1、子类对象即是父类对象,反之不然

对象运算符instanceof判断一个实例是否属于指定类

例如:new Person() instanceof Person      //结果是true

2、父类对象引用子类实例,反之不行

Person p = new Student();       //赋值相容,子类对象即是父类对象

Student s = new Person();       //语法错,赋值不相容,父类对象不是子类对象

三、编译时多态和运行时多态

根据合适确定执行多态方法中的哪一个,多态分为两种情况:编译时多态和运行时多态。

1、编译时多态

方法重载都是编译时多态。

方法覆盖表现出两种多态性,当对象引用本类实例时,为编译时多态,否则为运行时多态。

2、运行时多态

当以下父类对象p引用子类实例时,p.toString()究竟执行的是谁的toString()方法?

Person p = new Student();

p.toString();

Java支持运行时多态,意为p.toString()实际执行p所引用实例的toString()方法,究竟执行Person类还是Student类的方法,运行时再确定。如果Student类声明toString()方法,则执行之,否则执行Person类的toString()方法

程序运行时,java从实例所属的类开始寻找匹配的方法执行,如果当前类中没有匹配方法,则沿着继承关系逐层向上,一次在父类或各祖先类中寻找匹配方法,直到object类。

因此,父类对象只能执行那些在父类中声明、被子类覆盖了的子类方法,如toString(),不能执行子类增加的成员方法。

 

多态的弊端:父类无法访问子类特有的属性和行为。因此在重写父类的方法时,形参仍然要是父类型的,但在方法体中可以向下转型。

例如:

Person类继承Object类,当重写equals方法时

public boolean equals(Object object)  //注意,这里参数必须是Object,而不能是Student,因为如果是Student,那么就不是重写,而是重载

{

     Person p = (Person) object ;

     return this.name.equals(p.name);

}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值