设计模式-2.设计模式的七大原则

文章详细阐述了设计模式的七大原则,包括开闭原则、单一职责原则、里氏替换原则、依赖倒转原则、接口隔离原则、迪米特原则和合成复用原则。同时对比分析了接口和抽象类的特性,如接口不能实例化,抽象类不能被直接实例化,以及它们在回调机制中的应用。最后,通过接口回调和抽象类回调的例子展示了回调的概念和实现步骤。
摘要由CSDN通过智能技术生成

1️⃣ 设计模式的七大原则


📝 开闭原则

对扩展开放,对修改关闭。一般使用接口和抽象类来实现,当我们需要扩展的时候派生一个实现类就行了
在这里插入图片描述


📝 单一职责原则

每个类应该实现单一的职责,如若不然,就应该把类拆分


📝 里氏替换原则

任何基类可以出现的地方,子类一定可以出现,子类对父类的方法尽量不要重写和重载,因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它


📝 依赖倒转原则

面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互


📝 接口隔离原则

每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好


📝 迪米特原则

一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类


📝 合成复用原则

尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

在这里插入图片描述


2️⃣ 接口和抽象类

  • 如果抽象类中的所有方法都是抽象方法就可以把这个抽象类转成接口来表示,接口本质不是类。接口是功能的集合;
  • 接口多定义对象的行为;抽象类多定义对象的属性;

在这里插入图片描述


📝 接口的特性

接口的特性
1.接口不能new一个对象,它不是类
2.接口的方法没有方法体body,既不能有{}
3.实现类使用关键字implements实现对应接口。实现类必须重写接口的所有抽象方法,如果不想都重写就要把这个类变成抽象类
4.接口的所有修饰符只能为public
5.接口不能定义构造方法,也不能创建对象,接口对象可以利用子类对象(实现类)的向上造型进行实例化
6.声明的接口类型对象在编译时期可以接收所有类型对象的赋值,但是在运行时期仍然检测接收的对象类型是否是接口的实现类,也就是其他类型的对象转成接口类型时编译时期不检测,运行时期检测是否具有实现关系
7.接口不能有变量但是可以定义常量,常量默认被public static final共同修饰,本质是个全局常量
8.接口可以有多个实现类,实现类也可以引用多个接口,但抽象类的子类只能继承一个父类(java支持多实现,接口与接口之间支持多继承,类与类之间是单继承)
在这里插入图片描述

📝 抽象类的特性

接口的特性
1.不能被实例化:抽象类只能被继承,不能直接创建实例对象。
2.可以包含抽象方法:抽象类可以包含抽象方法,抽象方法没有具体实现,需要在子类中实现。
3.可以包含非抽象方法:抽象类也可以包含非抽象方法,非抽象方法有具体实现,可以在抽象类中直接调用。
4.可以包含静态方法:抽象类可以包含静态方法,静态方法可以在抽象类中直接调用。
5.可以包含静态变量和实例变量:抽象类可以包含静态变量和实例变量。
6.可以实现接口:抽象类可以实现接口,并且在实现接口的同时,可以定义一些共用的方法和属性,且无需实现接口的所有的抽象方法,未实现的抽象方法可以由子类实现。
7.子类必须实现抽象方法:如果一个类继承了抽象类,那么它必须实现所有抽象方法,否则该子类也必须被声明为抽象类。
8.抽象类的子类也可以是抽象类,子类是抽象类时不必实现抽象超类的所有抽象方法。
在这里插入图片描述

📝 抽象类和类的区别

抽象类和类的区别
1. 抽象类不能被实例化,而普通类可以被实例化。
2.抽象类的访问权限限于Public和Protected,因为抽象类的方法是需要继承之后让子类去实现的,如果为Private,则无法被子类继承,子类也无法实现该方法
3. 抽象类中可以包含抽象方法,普通类不可以包含抽象方法。

📝 接口或是抽象类回调


📌 重要的两点

1、接口回调:指的是A通过方法把B赋值给自己的某个属性,然后在A调用某个方法的时候,使B调用B自己的某个方法
2、继承抽象类一样也可以实现回调的,而且可以有更高的扩展性,可以加入更多的属性值


📌 接口回调

package com.study.notes.bean.callback.interfaces;

public interface ICallBack {
    void callback(String homeWork);
}

package com.study.notes.bean.callback.interfaces;

/**
 * @program: study-notes
 * @description:
 * @author: lzq
 * @create: 2023-07-14 15:22
 */
//学生 作为下层身份出现
public class Student {    //相当于老师的办公室
    private ICallBack callBack = null;
    public void setCallBack(ICallBack callBack) {
        this.callBack = callBack;
    }
    public void doHomeWork() {
        System.out.println("写作业...(半个小时后)作业写完了");
        //告诉老师,作业写完了 并且交到了办公室
        callBack.callback("数学卷子一张");
    }
}

package com.study.notes.bean.callback.interfaces;

/**
 * @program: study-notes
 * @description: //老师 作为上层应用身份出现
 * @author: lzq
 * @create: 2023-07-14 15:21
 */

public class Teacher implements ICallBack {
    @Override
    public void callback(String homeWork) {
        System.out.println("老师,这是我的作业..."+homeWork);
    }
}

package com.study.notes.bean.callback.interfaces;

/**
 * @program: study-notes
 * @description:
 * @author: lzq
 * @create: 2023-07-14 15:23
 */
public class Test {

    public static void main(String[] args) {
        Teacher t = new Teacher();
        Student s = new Student();
        //传入回调对象 老师
        s.setCallBack(t);
        s.doHomeWork();
    }

}


📌 抽象类回调

package com.study.notes.bean.callback.abstracts;

public abstract class CallBack {
    protected String name;
    public CallBack(String name) {
        this.name = name;
    }
    public abstract void callback(String homeWork);
}

package com.study.notes.bean.callback.abstracts;

/**
 * @program: study-notes
 * @description: //老师 作为上层应用身份出现
 * @author: lzq
 * @create: 2023-07-14 15:21
 */

public class Teacher extends CallBack {
    public Teacher(String name) {
        super(name);
    }
    @Override
    public void callback(String homeWork) {
        System.out.println(super.name+"老师,这是我的作业..."+homeWork);
    }
}

package com.study.notes.bean.callback.abstracts;

/**
 * @program: study-notes
 * @description:
 * @author: lzq
 * @create: 2023-07-14 15:22
 */
//学生 作为下层身份出现
public class Student {    //相当于老师的办公室
    private CallBack callBack = null;
    public void setCallBack(CallBack callBack) {
        this.callBack = callBack;
    }
    public void doHomeWork() {
        System.out.println("写作业...(半个小时后)作业写完了");
        //告诉老师,作业写完了 并且交到了办公室
        callBack.callback("数学卷子一张");
    }
}

package com.study.notes.bean.callback.abstracts;

/**
 * @program: study-notes
 * @description:
 * @author: lzq
 * @create: 2023-07-14 15:23
 */
public class Test {

    public static void main(String[] args) {
        Teacher t = new Teacher("小明");
        Student s = new Student();
        //传入回调对象 老师
        s.setCallBack(t);
        s.doHomeWork();
    }

}


📌 接口回调 VS 多肽

  • 接口回调是实现接口的类的实例的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法。
  • 不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量就在回调接口方法时可能具有多种形态。

📌 接口回调的步骤

回调是一个非常强大的编程概念,尤其在异步编程和事件驱动的环境中。简而言之,回调就是当一件事情完成后,通知另一件事情开始的机制。在Java等面向对象的编程语言中,这通常通过接口来实现。

📝 步骤概览:

  1. 定义接口: 这是回调方法的声明。
  2. 定义方法: 这个方法的参数是您刚刚定义的接口。
  3. 在方法内调用接口: 这实际上是触发回调的地方。
  4. 调用上述方法: 当您调用这个方法时,传入一个实现了接口的对象。

💡 小贴士: 在Java中,非常常见的做法是直接在接口参数位置传入一个匿名内部类。而在Java 8及以后,由于引入了Lambda表达式,使得这一过程变得更为简洁,特别是对于只有一个方法的接口(函数式接口)。

public interface MyCallInterface {
     public void  printName();
}

public class Client implements MyCallInterface {
     @Override
     public void printName() {
          System.out.println("This is the client printName method");
     }
}

public class Caller {
    //保存一个接口引用
    private MyCallInterface callInterface;
    public Caller() {
    }
    public void setCallFunc(MyCallInterface callInterface) {
         this.callInterface = callInterface;
    }
    public void call() {
         callInterface.printName();
    }
}

public class Test {
    public static void main(String[] args) {
         Caller caller = new Caller();
         caller.setCallFunc(new Client());
         caller.call();
    }
}

public class Test {
    public static void main(String[] args) {
        Caller caller = new Caller();
        //caller.setCallFunc(new Client());使用匿名类代替
        caller.setCallFunc(new MyCallInterface() {
            public void printName() {
                 System.out.println("This is the client printName method");
            }
        });
        caller.call();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yueerba126

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值