面向对象(多态表现二和三、方法重载、23种设计模式之工厂模式)

在上一章面向对象(多态、方法重写)中我说明了多态在面向对象时的体现有三个方面我已经对第一个方面<父类引用>指向<子类对象>:好处:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化,那么在这一章我将会将多态的另外两个方面进行说明.首先我们先引入方法重载的概念:

方法重载

⚠️注意:

实现前提:

在同一个类中

1.方法名必须相同

2.参数列表必须不同:个数不同,类型不同,顺序不同(满足一种都可以)

3.返回类型可以相同也可以不同

作用: 简化代码设计,方便调用

使用场景:

在同一个类当中,如果多个功能是相似的,可以考虑将它们的方法名定义的一致,使用方法重载机制


详细介绍(区分方法的重载和重写)

通过对方法重载的了解后,我们在代码里面来具体的了解一下时如何实现的方法的重载,如下:

public class VehicleService {
    /**
     * 以下三个方法构成了方法重载
     * 在同一个类中,方法名相同,参数列表不同的机制,它可以通过一个相同名字的统一方法来执行不同参数的功能,
     * 从而简化设计
     *
     * 构成重载的条件
     * 前提条件--必须发生在同一个类中
     *
     * 要求:方法名必须相同,参数列表必须不同(参数的个数,类型,顺序...),返回类型没有限制
     */
    public void goWork(Car car) {
        System.out.println("开" + car.getBrand() + car.getType() + "车上班...");
    }

    public void goWork(Bike bike) {
        System.out.println("骑" + bike.getBrand() + bike.getType() + "自行车上班...");
    }

    public void goWork(Plane plane) {
        System.out.println("坐" + plane.getBrand() + plane.getType() + "飞机上班...");
    }

测试类:

public class TestVehicle {
    public static void main(String[] args) {
        //创建业务类对象
        VehicleService service = new VehicleService();
       //创建交通工具对象
        Car car = new Car("奇瑞","QQ");
       //调用业务方法
        service.goWork(car);

通过这个业务类我们将不同交通工具的的作用通过方法的重载进行了实现,在测试类中我们只需要创建业务类对象,再将我们创建的交通工具对象传入到业务类对象方法中,然后业务方法会通过传入的对象类型(参数)选择对应的方法,这就是方法的重载.

注意⚠️!

看完方法的重载以后,再回过头来看方法重写的存在条件如下:

存在条件:有继承关系

​ 那么我们会想如果利用多态还有方法的重写,在创建对象的时候我用父类引用指向子类,并且在业务类中用instanceof判断是什么类型,然后再选择执行对应的方法,同样也可以实现这些功能如下:

/**
 * 多态应用之方法参数列表写成父类
 * 优点: 可以在设计时合并多个子类参数的方法,并且后期具有拓展性
 */
public void goWork(Vehicle vehicle) {
    if (vehicle instanceof Car) {
        System.out.println("开" + vehicle.getBrand() + vehicle.getType() + "车上班...");
    } else if (vehicle instanceof Bike) {
        System.out.println("骑" + vehicle.getBrand() + vehicle.getType() + "自行车上班...");
    } else if (vehicle instanceof Plane) {
        System.out.println("坐" + vehicle.getBrand() + vehicle.getType() + "飞机上班...");
    } else if (vehicle instanceof MotoBike) {
        System.out.println("骑" + vehicle.getBrand() + vehicle.getType() + "摩托车上班...");
    }
注意⚠️:在这里我们可以发现这样的写法虽然没有什么毛病,但是后期如果增加了一个新的交通工具,那就需要对业务类进行改动了,这在实际的开发当中是非常繁琐的并且不利于后期的扩展,
所以我们这里要多思考一个如何写才能方便以后的扩展,那怕新增一个类型也不需要对业务类进行改动
解答:vehice.move( );没错这样就写完了,是不是非常奇妙,如果还是不能理解为什么只用写这一句话就解决问题的话,我来详细解释一下,注意这里我们方法参数列表写成的是父类,然后我可以
先在父类中定义一个move的空方法,那么子类继承以后只需要重写这个方法就可以了,那么回到业务类中来,只需要写一句话了,一切的一切都交给方法的重写子类方法会覆盖父类的方法来解决!这个
思想非常的重要!理解之后真的能感受到他的妙用,以及业务类和实体类分离的妙用!!!!!!!!我在下面会具体写出来!!!!

测试类:

public class TestVehicle {
    public static void main(String[] args) {
        //创建业务类对象
        VehicleService service1 = new Car();
       //调用业务方法
        service.goWork(service1);

​ 那么就有疑惑了方法的重载有啥用呢,通过上面的代码我们可以看到,多态和方法的重写同样可以实现同样的效果,那么我们仔细思考一下,方法重写和多态的前提是需要有继承的关系,但是方法的重载不需要!

注意⚠️:

在同一个类当中,如果多个功能是相似的,可以考虑将它们的方法名定义的一致,使用方法重载机制,这样便于程序员的调用,以及代码美观,但相反,如果两个方法所完成的功能完全不同,那么方法名也一定要不一样,这样才是合理的。


小结:

在同一个类当中,如果多个功能是相似的

此类无继承关系,利用方法的重载

在不同类类当中,如果多个功能是相似的

我们可以创建一个父类,利用继承关系,子类对父类方法的重写


方法的参数列表使用父类(多态表现二)

参数使用父类来代替各种不同的传入子类对象的方法,多合一,简化设计,还可以带来拓展性

方法的返回类型使用父类(多态的表现三)

经典应用: 简单工厂

工厂模式

将上面多态表现二、多态表现三通过实际的例子来理解:

如下代码:

交通工具类:

package com.JavaSE.day09.v2;
/**
 * @Description 交通工具父类
 * @createTime 2022/3/18 9:31
 * @author Administrator
 */
public class Vehicle {
    private String brand;
    private String type;

    public Vehicle() {
    }

    public Vehicle(String brand, String type) {
        this.brand = brand;
        this.type = type;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void move(){
        重点⚠️//作用是用来被子类重写覆盖的方法
    }
}

业务类

/**
 * @Description 业务类
 * @createTime 2022/3/18 9:32
 * @author Administrator
 */
public class VehicleService {
    /**
     1.
     * 方法的参数列表使用父类(多态表现二)
     * 优点: 可以在设计时合并多个子类参数的方法,并且后期具有拓展性
     *2.
     *注意这里我们方法参数列表写成的是父类,然后我可以先在父类中定义一个move的空方法,那么子类继承以后只需要重写这个方法就可以了,那么回到业务类中来,只需要写一句话了,并且最大的优势
     *以后哪怕我对某一个功能进行改动我只需要在对应的子类中进行改动,不需要对业务类进行改动!!!!!! 一定要理解!!!
     */
    public void goWork(Vehicle vehicle){
        重点⚠️ vehicle.move()
}

工厂类

**
 * @Description 工厂类, 负责生产指定父类类型下的所有子类对象
 * 问题: 有父类,有若干子类,子类需要创建对象,则可以考虑使用工厂模式
 *
 * Java23种设计模式之一,设计模式就是程序员在大量的开发中总结出来的一套"公式",利用这套公式可以解决
 * 某一类具体的问题.
 *
 * 注意: Java中的23个设计模式是大的分类,每个设计模式还有它的分支,比如:工厂模式就分为简单工厂,抽象工厂...
 *
 * @createTime 2022/3/18 10:51
 * @author Administrator
 */
public class VehicleFactory {
    /**
     *  常量定义,public static final
     *
     *  注意:
     *  常量一般都是公开的
     *  final表示这个常量无法被改变
     *  常量的命名全部采用大写字母,多个单词的话中间用_隔开
     *
     *  作用: 安全(不能改) + 提高代码的可读性
     */
    public static final int BIKE = 1;
    public static final int CAR = 2;
    public static final int PLANE = 3;
    public static final int MOTOBIKE = 4;
    public static final int BOAT = 5;

    /**多态应用: 方法的返回类型写成父类*/
    public static Vehicle getVehicle(int type) {
        Vehicle vehicle = null;
        if (type == BIKE) {
            vehicle = new Bike();
        } else if (type == CAR) {
            vehicle = new Car();
        } else if (type == PLANE) {
            vehicle = new Plane();
        } else if (type == MOTOBIKE) {
            vehicle = new MotoBike();
        } else if (type == BOAT) {
            vehicle = new Boat();
        } else {
            System.out.println("参数有误!");
        }
        return vehicle;
    }
}

测试类:

/**
 * @Description
 * @createTime 2022/3/18 9:34
 * @author Administrator
 */
public class TestVehicle {
    public static void main(String[] args) {
        //创建业务类对象
        VehicleService service = new VehicleService();
        /**
         * 使用工厂来创建对象,没有出现具体的子类对象,都是面向父类的,
         * 可以隐藏子类,提高代码的维护性和后期的拓展性
         */
        //使用常量提高代码的可读性
        Vehicle vehicle=VehicleFactory.getVehicle(VehicleFactory.CAR);
        vehicle.setBrand("奇瑞");
        vehicle.setType("QQ");
        //调用业务方法
        service.goWork(vehicle);
    }
}
结果:开奇瑞QQ车上班...

个人理解:工厂类相当于把创建的子类对象给隐藏起来了,不像前面写的代码一样的是直接暴露在外面的例如: VehicleService service1 = new Car();,工程类的好处呢就可以隐藏子类,提高代码的维护性和后期的拓展性,并且可读性增加了

注意⚠️:

工厂模式创建出来的对象是通用对象,即属性都是默认值,需要设置属性值,1.公共属性直接set设置,2.特有属性,需要先强制类型转换,然后再set设置,注意转换之前最好先进行类型判断,避免出现类型转换异常

总结:

这一篇博客,主要就掌握最重要的三点!!!!,
第一点也就是方法的参数列表使用父类
第二点在第一点的基础上在业务类中体会直接用父类.方法的好处和妙用(方法的重写)
第三点也就是方法的返回类型使用父类从工厂模式可以体现他的妙用.
第四点:方法的重载

posted @ 2022-03-18 14:16  JanoCode  阅读(53)  评论(0)    收藏  举报