Java基础(多态的理解与应用)


在最初学习java的时候,人们都知道,java这种面向对象的语言,一共有三大特征,分别是:封装、继承,多态

这些词经常被人们提及,那么,到底什么是多态呢?


多态概念

java里,多态是同一个行为具有不同表现形式或形态的能力,即对象多种表现形式的体现,就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

理解如下:

  • 多态是同一个行为具有多个不同表现形式或形态的能力。我们也可以说多态就是同一种引用类型,不同的实例执行不同的的操作。
  • 多态就是同一个接口,使用不同的实例而执行不同操作。

多态现实意义理解

  • 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是,即出现两种形态
  • 使用手机扫描二维码支付时,二维码并不知道客户是通过何种方式进行支付,只有通过二维码后才能判断是走哪种支付方式执行对应流程。

Java类的多态和递归方法 java多态的定义和应用_多态

多态的前提

  • 要有继承或实现关系

如Student类继承了Person类,一个Student的对象便既是Student,又是Person。

  • 要有方法的重写
  • 要有父类引用指向子类对象

注意:

  • 在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。**
  • 声明方法时,形参列表为父类,调用方法时,实参列表为子类
  • 声明时为父类类型,赋值时为子类类型
  • 创建数组时,元素类型为父类 ,数组元素为子类
  • 多态的定义与使用格式

定义格式:父类类型 变量名=new 子类类型();

多态的好处和弊端

使用多态,我们可以很好的完成代码的解耦和工作,加强代码的可扩展性,是代码更加灵活,在不改变原有接口方法的情况下简化流程等,总结一下就是:

  • 减耦合
  • 增强可以替换性
  • 可扩展性
  • 灵活性
  • 接口性
  • 灵活性
  • 简化性

使用多态必须满足三个必要条件。

  • 继承
  • 重写
  • 父类引用指向子类Parent p = new Child();

在编写代码期间使用多态调用方法时,IDE首先会检查父类中是否有该方法,如果没有,则会编译报错。如果有父类中调用子类的同名方法。

总结:

  • 好处
    提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
  • 弊端
    不能使用子类的特有成员

多态中成员的特点

  • 多态成员变量:编译运行看左边,及编译看父类,运行看父类
Fu f=new Zi();
System.out.println(f.num);//f是Fu中的值,只能取到父中的值
  • 多态成员方法:编译看左边,运行看右边,及编译看父类,运行看子类
Fu f1=new Zi();
System.out.println(f1.show());//f1的门面类型是Fu,但实际类型是Zi,所以调用的是重写后的方法。
  • instanceof关键字

作用:用来判断某个对象是否属于某种数据类型。

注意: 返回类型为布尔类型

多态的实现方式

  • 重写

我们会在下面做一个详解

  • 接口

生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。

java中的接口类似于生活中的接口,就是一些方法特征的集合。 

  • 抽象类和抽象方法

[文档地址]((3条消息) JAVA学习(十)之接口和抽象类 

多态案例

例1:(理解多态,可以重点看这个案例

package day0524;
 
public class demo04 {
    public static void main(String[] args) {
        People p=new Stu();
        p.eat();
        //调用特有的方法
        Stu s=(Stu)p;
        s.study();
        //((Stu) p).study();
    }
}
class People{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Stu extends People{
    @Override
    public void eat(){
        System.out.println("吃水煮肉片");
    }
    public void study(){
        System.out.println("好好学习");
    }
}
class Teachers extends People{
    @Override
    public void eat(){
        System.out.println("吃樱桃");
    }
    public void teach(){
        System.out.println("认真授课");
    }
}

例2:

请问题目运行结果是什么?

package day0524;
public class demo1 {
    public static void main(String[] args) {
        A a=new A();
        a.show();
        B b=new B();
        b.show();
    }
}
class A{
    public void show(){
        show2();
    }
    public void show2(){
        System.out.println("A");
    }
}
class B extends A{
    public void show2(){
        System.out.println("B");
    }
}
class C extends B{
    public void show(){
        super.show();
    }
    public void show2(){
        System.out.println("C");
    }
}

例3:

我们文档开始位置所说的支付的实现(使用多态)

/**
 * 支付抽象类或者接口
 */
public abstract class Pay {
    abstract public String pay();
}
/**
 * 支付宝支付
 */
public class AliPay extends Pay {
    @Override
    public String pay() {
        System.out.println("支付宝pay");
        return "success";
    }
}
/**
 * 微信支付
 */
public class WeixinPay extends Pay {
    @Override
    public String pay() {
        System.out.println("微信Pay");
        return "success";
    }
}
/**
 * 银联支付
 */
public class YinlianPay extends Pay {
    @Override
    public String pay() {
        System.out.println("银联支付");
        return "success";
    }
}

测试支付
public static void main(String[] args) {
 /**
      * 测试支付宝支付多态应用
      */
    Pay pay = new AliPay();
    pay.pay();
 /**
      * 测试微信支付多态应用
      */
    pay = new WeixinPay();
    pay.pay();
 /**
      * 测试银联支付多态应用
      */
    pay = new YinlianPay();
    pay.pay();
}

------>输出结果如下:

支付宝pay
微信Pay
银联支付

例4:

请采用多态的思想实现猫和狗的案例,并在测试类中进行测试

  • Animal .java
public class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println("动物吃东西");
    }
}
  • Cat.java
public class Cat extends Animal {

    public Cat() {
    }

    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
  • Dog .java
public class Dog extends Animal {

    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}
  • text.java
public class AnimalDemo {
    public static void main(String[] args) {
        //创建猫类对象进行测试
        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();

        a = new Cat("加菲", 5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();
    }
}
//测试方法如下
    public static void main(String[] args) {
        //创建猫类对象进行测试
        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();

        a = new Cat("加菲", 5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();
    }
}

我们再文章的最后来看一个例子
功能:
使用多态实现汽车租赁系统
代码如下

public class AnimalDemo {
    public static void main(String[] args) {
        //创建猫类对象进行测试
        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();

        a = new Cat("加菲", 5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();
    }
}

package car.model;

import car.base.errors.StaticValue;
import car.base.model.BaseModel;

/**
 * The type Bus.
 *
 * @author user
 */
public class Bus extends BaseModel {
    @Override
    public void setType(int type) throws Exception {
        switch (type){
            case 1:
                this.type = StaticValue.BUS_CHANGE_FIRST;
                break;
            case 2:
                this.type= StaticValue.BUS_CHANGE_SECOND;
                break;
            default:
                throw new Exception(StaticValue.ERROR_MESSAGE);
        }
    }

    @Override
    public void setPrice(Float price) {
        if (price<= StaticValue.BUS_MAX_VALUE) {
            this.price=StaticValue.BUS_CHANGE_FIRST_PRICE;
        }else{
            this.price=StaticValue.BUS_CHANGE_SECONDS_PRICE;
        }
    }

    /**
     * Create type.
     *
     * @param value     the value
     * @param valueType the value type
     * @param carWords  the car words
     * @throws Exception the exception
     */
    public void createType(Bus value, int valueType, float carWords) throws Exception {
        try {
            value.setType(valueType);
            value.setPrice(carWords);
        } catch (Exception e) {
            throw new Exception("Choice.CreateType Error");
        }
    }
}
package car.model;

import car.base.errors.StaticValue;
import car.base.model.BaseModel;

/**
 * The type Car.
 *
 * @author user
 */
public class Car extends BaseModel {
    @Override
    public void setType(int type) throws Exception {
        switch (type){
            case 1:{
                this.type = StaticValue.CAR_CHANGE_FIRST;
                setPrice(StaticValue.CAR_CHANGE_FIRST_PRICE);
                break;
            }
            case 2:{
                this.type= StaticValue.CAR_CHANGE_SECOND;
                setPrice(StaticValue.CAR_CHANGE_SECONDS_PRICE);
                break;
            }
            case 3:{
                this.type= StaticValue.CAR_CHANGE_THIRD;
                setPrice(StaticValue.CAR_CHANGE_THREAD_PRICE);
                break;
            }
            default:{
                throw new Exception(StaticValue.ERROR_MESSAGE);
            }
        }
    }


    /**
     * Create type.
     *
     * @param value     the value
     * @param valueType the value type
     * @throws Exception the exception
     */
    public void createType(Car value, int valueType) throws Exception {
        try {
            value.setType(valueType);
        } catch (Exception e) {
            throw new Exception(StaticValue.ERROR_MESSAGE);
        }
    }
}

package car.model;

import car.base.errors.StaticValue;
import car.base.model.BaseModel;

/**
 * The type Truck.
 *
 * @author user
 */
public class Truck extends BaseModel {
    private Float weight;

    private Float getWeight() {
        return weight;
    }

    /**
     * Sets weight.
     *
     * @param weight the weight
     */
    public void setWeight(Float weight) {
        this.weight = weight;
    }

    @Override
    public double calcRent(short intValue) {
        return (double) (getPrice() * intValue * getWeight());
    }

    @Override
    public void setType(int type) throws Exception {
        switch (type){
            case 1:
                this.type = StaticValue.TRUCK_FREEST;
                this.setPrice(StaticValue.TRUCK_FREEST_PRICE);
                break;
            case 2:
                this.type= StaticValue.TRUCK_SECONDS;
                this.setPrice(StaticValue.TRUCK_SECONDS_PRICE);
                break;
            default:
                throw new Exception(StaticValue.ERROR_MESSAGE);
        }
    }

    /**
     * Create type.
     *
     * @param value     the value
     * @param valueType the value type
     * @throws Exception the exception
     */
    public void createType(Truck value, int valueType) throws Exception {
        try {
            value.setType(valueType);
        } catch (Exception e) {
            throw new Exception(StaticValue.ERROR_MESSAGE);
        }
    }
}
package car.controllers;


import car.base.errors.StaticValue;
import car.model.Bus;
import car.model.Car;
import car.model.Truck;

/**
 * The type Base person.controller.
 *
 * @author user
 */
public class BaseController {
    /**
     * Create object object.
     *
     * @param value the value
     * @return the object
     */
    public static Object createObject(int value){
        if (value == 0) {
            return new Car();
        }else if (value == StaticValue.FIRST_VALUE_PRICE) {
            return new Truck();
        }else if (value ==StaticValue.SECOND_VALUE_PRICE){
            return new Bus();
        }else{
            System.out.println(StaticValue.ERROR_MESSAGE);
                return null;
            }
        }
}
package car.base.carinterface;

/**
 * The interface Base model inter face.
 *
 * @author user
 */
public interface BaseModelInterFace {
    /**
     * Calc rent double.
     *
     * @param intValue the int value
     * @return the double
     */
    double calcRent(short intValue);
}
package car.base.errors;

/**
 * The type Static value.
 *
 * @author user
 */
public  class StaticValue {
    /**
     * The constant BUS_CHANGE_FIRST.
     */
    public static final String BUS_CHANGE_FIRST = "金杯";
    /**
     * The constant BUS_CHANGE_SECOND.
     */
    public static final String BUS_CHANGE_SECOND = "金龙";
    /**
     * The constant BUS_MAX_VALUE.
     */
    public static final Float BUS_MAX_VALUE = 16F;
    /**
     * The constant CAR_CHANGE_FIRST.
     */
    public static final String CAR_CHANGE_FIRST = "别克商务舱GL8";
    /**
     * The constant CAR_CHANGE_SECOND.
     */
    public static final String CAR_CHANGE_SECOND = "宝马550i";
    /**
     * The constant CAR_CHANGE_THIRD.
     */
    public static final String CAR_CHANGE_THIRD = "别克林荫大道";
    /**
     * The constant ERROR_MESSAGE.
     */
    public static final String ERROR_MESSAGE ="Choice.CreateType Error";

    /**
     * The constant TRUCK_FREEST.
     */
    public static final String TRUCK_FREEST = "东风";

    /**
     * The constant TRUCK_SECONDS.
     */
    public static final String TRUCK_SECONDS = "二仙桥专线";

    /**
     * The constant TRUCK_FREEST_PRICE.
     */
    public static final float TRUCK_FREEST_PRICE =200F;

    /**
     * The constant TRUCK_SECONDS_PRICE.
     */
    public static final float TRUCK_SECONDS_PRICE = 20F;

    /**
     * The constant BUS_CHANGE_FIRST_PRICE.
     */
    public static final float BUS_CHANGE_FIRST_PRICE = 800.00F;

    /**
     * The constant BUS_CHANGE_SECONDS_PRICE.
     */
    public static final float BUS_CHANGE_SECONDS_PRICE = 1500.00F;

    /**
     * The constant CAR_CHANGE_FIRST_PRICE.
     */
    public static final float CAR_CHANGE_FIRST_PRICE = 600.00F;

    /**
     * The constant CAR_CHANGE_SECONDS_PRICE.
     */
    public static final float CAR_CHANGE_SECONDS_PRICE = 500.00F;

    /**
     * The constant CAR_CHANGE_THREAD_PRICE.
     */
    public static final float CAR_CHANGE_THREAD_PRICE = 300.00F;

    /**
     * The constant FIRST_VALUE_PRICE.
     */
    public static final int FIRST_VALUE_PRICE = 1;

    /**
     * The constant SECOND_VALUE_PRICE.
     */
    public static final int SECOND_VALUE_PRICE = 2;

    /**
     * The constant THIRD_VALUE_PRICE.
     */
    public static final int THIRD_VALUE_PRICE = 3;
}
package car.base.model;

import car.base.carinterface.BaseModelInterFace;

/**
 * The type Base model.
 *
 * @author user
 */
public abstract class BaseModel implements BaseModelInterFace {
    /**
     * The Type.
     */
    protected String type;
    /**
     * The Price.
     */
    protected Float price;
    private String no;
    private String brand;
    private String color;
    private Double mileages;
    private Short carWords;

    /**
     * Gets type.
     *
     * @return the type
     */
    public String getType() {
        return type;
    }

    /**
     * Sets type.
     *
     * @param type the type
     * @throws Exception the exception
     */
    public void setType(int type) throws Exception {
    }

    /**
     * Gets price.
     *
     * @return the price
     */
    public Float getPrice() {
        return price;
    }

    /**
     * Sets price.
     *
     * @param price the price
     */
    public void setPrice(Float price) {
        this.price = price;
    }

    /**
     * Gets no.
     *
     * @return the no
     */
    public String getNo() {
        return no;
    }

    /**
     * Sets no.
     *
     * @param no the no
     */
    public void setNo(String no) {
        this.no = no;
    }

    /**
     * Gets brand.
     *
     * @return the brand
     */
    public String getBrand() {
        return brand;
    }

    /**
     * Sets brand.
     *
     * @param brand the brand
     */
    public void setBrand(String brand) {
        this.brand = brand;
    }

    /**
     * Gets color.
     *
     * @return the color
     */
    public String getColor() {
        return color;
    }

    /**
     * Sets color.
     *
     * @param color the color
     */
    public void setColor(String color) {
        this.color = color;
    }

    /**
     * Gets mileages.
     *
     * @return the mileages
     */
    public Double getMileages() {
        return mileages;
    }

    /**
     * Sets mileages.
     *
     * @param mileages the mileages
     */
    public void setMileages(Double mileages) {
        this.mileages = mileages;
    }

    /**
     * Gets car words.
     *
     * @return the car words
     */
    public Short getCarWords() {
        return carWords;
    }

    /**
     * Sets car words.
     *
     * @param carWords the car words
     */
    public void setCarWords(Short carWords) {
        this.carWords = carWords;
    }

    @Override
    public double calcRent(short intValue) {
        return (double) (getPrice() * intValue);
    }
}