(32)java基础语法 --多态polymorphic

目录

1、多态的概述

2、java中多态的形式有两种

3、多态代码体现(定义格式)

4、多态调用注意事项

5、多态的好处和弊端

6、向上向下类型转换

7、多态的应用

案例一:

案例二:


1、多态的概述

多态是继封装、继承之后,面向对象的第三大特性。

现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。

Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。

多态:

父类类型的引用指向子类的对象

多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态

在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法

2、java中多态的形式有两种

1.在继承的情况下

      子类继承父类,并且子类重写父类中的方法;

2.在实现的情况下

      实现类实现接口,实现接口中的抽象方法;

3、多态代码体现(定义格式)

父类引用指向子类对象就是多态的定义格式。同一个父类的方法会被不同的子类重写为各自的具体实现。在调用方法时,调用的为各个子类重写后的方法。

此时,虽然该变量指向的是子类对象,但表现为一个父类的形态,可以调用一切父类的方法,子类特有的方法将不能调用

1.在继承的情况下

      1.子类继承父类

      2.子类重写父类中的方法;

      3.定义一个父类类型的变量 指向 子类的对象:

格式

      父类名 对象名 = new 子类名(实参列表);

特点:

      通过父类类型的引用访问被重写的方法,访问的是子类中的方法,访问被重写的属性时访问的是父类中的属性.

 

2.在实现的情况下

      1.实现类实现接口

      2.实现接口中的抽象方法;

      3.定义一个接口类型的对象, 指向 实现类的对象:

格式

      接口名 对象名 = new 实现类名(实参列表);

4、多态调用注意事项

在继承的情况的多态的特点:

      1.如果在子类中重写了父类中的属性,当通过父类类型的引用访问这个属性时,访问的是父类中定义的属性

      2.不能通过父类类型的引用访问子类中特有的属性

      3.通过父类类型的引用访问被重写的方法时,访问子类中重写后的方法

      4.不能通过父类类型的引用访问子类中特有的方法

有接口有实现类的情况下的多态的特点:

      1.只要实现类 重写了接口中的方法,当通过接口类型的引用访问这些方法时,访问的是子类中重写后的方法

      2.如果在实现类中重写了接口中的常量,通过接口类型的引用访问这个常量时,访问的是接口中定义的常量

5、多态的好处和弊端

当变量名指向不同的子类对象时,由于每个子类重写父类方法的内容不同,所以会调用不同的方法。

如:在Boss类中,有叫员工去工作的方法,当该方法的参数定义为接口时,可以传入任意的实现类对象。相比定义多个实现类类参数,定义多个方法,这样大大提高了代码复用性与扩展性。

/*
    Boss类中,goToWork是叫员工工作的方法
*/
class Boss{    //Boss类
	public void goToWork(Empolyee e){    //Empolyee是员工接口类型的引用
		e.work();    // 调用接口被各个实现类重写的方法
	}
}

多态的好处:

      配合继承与方法重写提高了代码的复用性与扩展性,如果没有方法重写,则多态同样没有意义。

多态的弊端: 不能调用子类的特有方法

      当通过父类类型的引用访问属性和方法时 不能访问子类中 特有的 属性和方法, 只能访问 父类中有的属性和方法.

6、向上向下类型转换

多态的转型分为向上转型与向下转型两种:

向上转型:

      当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程

       父类类型  变量名 = new 子类类型();

Animal a = new Cat();

向下转型:

      一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的!

      子类类型 变量名 = (子类类型) 父类类型的变量;

Animal a = new Cat();    // 向上转型

// 向下转型
Cat c = (Cat)a;    // 变量a实际上指向Cat对象

instanceof关键字

使用格式:

      boolean b = 引用变量 instanceof 类;

if(a instanceof Dog){
   Dog d = (Dog)a;
}

7、多态的应用

案例一:

      多态做为形参(接受范围更广的对象,避免方法重载过度使用)

      需求:完成喂动物操作。定义一个动物园类,类中有一个喂动物的方法。动物包括:老虎,猴子,狗,猫。每个动物类中都有一个eat的方法。(喂动物即是调用动物的eat方法)

/*
    Animal父类
*/
public class Animal {

    public void eat(){
        System.out.println("吃");
    }
}
/*
    Tiger子类
*/
public class Tiger extends Animal {
    @Override
    public void eat() {
        System.out.println("老虎吃兔子~~~");
    }
}
/*
    Monkey子类
*/
public class Monkey extends Animal {

    @Override
    public void eat() {
        System.out.println("猴子吃香蕉~~~");
    }
}
/*
    动物园Zoo类
*/
public class Zoo {

    public void feed(Animal animal){    // 喂动物
        animal.eat();
    }
}
/*
    测试方法
*/
public class PolymorphicDemo {

    public static void main(String[] args) {

        Zoo z = new Zoo();

        Tiger t = new Tiger();
        z.feed(t);

        Monkey m = new Monkey();
        z.feed(m);
    }
}


// 打印结果
/*
老虎吃兔子~~~
猴子吃香蕉~~~
*/

案例二:

      多态做为返回值类型(简单工厂模式)

      需求:有一个生产汽车的工厂,有一个生产汽车的方法,根据客户不同的需求,可以生产出不同的汽车。汽车包括:奔驰(benz)、宝马(BMW)、法拉利(ferrari)

/*
    Car父类
*/
public class Car {

    public void run(){
        System.out.println("run");
    }
}
public class BMW extends Car {

    @Override
    public void run() {
        System.out.println("宝马在路上run~~~");
    }
}
public class Benz extends Car {

    @Override
    public void run() {
        System.out.println("奔驰在路上run~~~");
    }
}
public class Ferrari extends Car {

    @Override
    public void run() {
        System.out.println("法拉利在路上run~~~");
    }
}
/*
    汽车工厂类
*/
public class CarFactory {

    public Car makeCar(String name){
        if ("bmw".equals(name)){
            return new BMW();
        }
        if ("benz".equals(name)){
            return new Benz();
        }
        if ("ferrari".equals(name)){
            return new Ferrari();
        }

        return null;
    }
}

上一篇:(31)Java基础语法 --接口

下一篇:(33)java基础语法 --工具类和常用类 --Arrays类

你可能感兴趣的:(Java基础,java)