面向对象多态性
一、多态的概念:
多态可以简单理解为事物存在的多种体现形态。
二、多态的扩展性
1.多态的体现。
父类的引用指向的自己的子类对象或者说父类的引用也可以接收自己的子类对象。
2.多态的前提。
类与类之间必须存在继承或者实现的关系。
通常还有一个前提,存在覆盖
3.多态的好处。
多态大大提高了程序的扩展性。
提高了扩展性,但是只能使用父类的引用访问父类中的成员和方法。
4.多态的弊端
虽然提高了代码的复用性,但是只能使用父类的引用访问父类的成员或方法。
具体看下面的代码实现:
package xiaobing.study;
/*需求:定义动物中的猫和狗实现两只动物的吃东西动作
* 以及该动物的特有行为
* */
//定义动物抽象类
abstract class Animal{
abstract void eat();
}
//定义动物中的猫子类
class Cat extends Animal{
//复写eat方法
public void eat(){
System.out.println("吃鱼");
}
//定义猫的特有方法
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("吃骨头");
}
public void kanJia(){
System.out.println("看家");
}
}
public class DuotaiDemo01 {
public static void main(String[] args){
/*常规定义
Cat cat=new Cat();
cat.eat();
Dog dog=new Dog();
dog.eat();
*/
//多态:父类的引用接受子类对象
Animal a=new Cat();
eatThing(a);
eatThing(new Dog());// 这个代码我们可以发现这个引用是自动发生的
}
/*将eat方法提取出来我们发现每次建立新的子类对象需要重写eatThing方法,这是就可以利用多态性定义。
public static void eatThing(Cat c){
c.eat();
}
public static void eatThing(Dog c){
c.eat();
}
*/
public static void eatThing(Animal c){
c.eat();
}
}
三、多态的转型
以上代码例子我们发现多态的弊端无法调用猫或狗的特有方法,这时就需要使用多态的转型。
Animal a=new Cat();这种父类引用指向子类,相当于子类的类型提升为父类,这种称为向上转型.
这时如果要使用子类猫或者都得的特有方法,可以将该父类引用强制转换为子类类型,即向下转型,Cat c=(Cat) a,
这里要注意的是:千万不要将父类对象转换为子类类型,我们能转换的是父类的引用指向了自己的子类对象时,该引用可以被转换,
多态自始至终都是子类在做着变化。
下面看代码实现:
package xiaobing.study;
/*需求:定义动物中的猫和狗实现两只动物的吃东西动作
* 以及该动物的特有行为
* */
//定义动物抽象类
abstract class Animal{
abstract void eat();
}
//定义动物中的猫子类
class Cat extends Animal{
//复写eat方法
public void eat(){
System.out.println("吃鱼");
}
//定义猫的特有方法
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("吃骨头");
}
public void kanJia(){
System.out.println("看家");
}
}
public class DuotaiDemo01 {
public static void main(String[] args){
/*常规定义
Cat cat=new Cat();
cat.eat();
Dog dog=new Dog();
dog.eat();
*/
//多态:父类的引用接受子类对象
Animal a=new Cat();//向上转型
eatThing(a);
eatThing(new Dog());// 这个代码我们可以发现这个引用是自动发生的
Cat c=(Cat) a;//向下转型
c.catchMouse();
/*
* 前面不要出现下面这种操作
* Animal a=new Animal();
* Cat c=(Cat)a;
*/
}
/*将eat方法提取出来我们发现每次建立新的子类对象需要重写eatThing方法,这是就可以利用多态性定义。
public static void eatThing(Cat c){
c.eat();
}
public static void eatThing(Dog c){
c.eat();
}
*/
public static void eatThing(Animal c){
c.eat();
}
}
最后来做一个多态的练习:
需求:现有基础班和高级班的学生,都存在睡觉和学习的动作,用多态来实现这些动作,代码如下:
package xiaobing.study;
abstract class Student{
public abstract void study();
public void sleep(){
System.out.println("躺着睡");
}
}
class BaseStudent extends Student{
public void study(){
System.out.println("base study");
}
public void sleep(){
System.out.println("坐着睡");
}
}
class AdvStudent extends Student{
public void study(){
System.out.println("adv study");
}
}
class DoStudent {
public void doSome(Student s){ //这里就是代码的应用
s.study();
s.sleep();
}
}
public class StudentDemo {
public static void main(String[] args){
DoStudent ds=new DoStudent();
ds.doSome(new BaseStudent());
ds.doSome(new AdvStudent());
/*BaseStudent bs=new BaseStudent();
bs.sleep();
bs.study();
AdvStudent as=new AdvStudent();
as.sleep();
as.study();*/
}
}