【Java】接口使用原则及代理模式

本文深入探讨了接口的开发原则、使用原则及其在软件工程中的应用,详细讲解了模板设计模式、工厂设计模式和代理设计模式,以及它们在解决特定问题时的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接口:

开发原则:接口优先原则,在一个场景既可以使用抽象类也可以使用接口的时候,优先考虑使用接口.

定义:接口中只有全局常量和抽象方法(JDK8之前),接口使用interface定义接口.

2.使用原则:
a.接口无法直接创建实例化对象,需要通过具体子类向上转型为其实例化。
b.接口命名一般以I 开头,子类实现一般以implements关键字实现接口,一般以impl结尾,表示此类是一个接口的子类。(接口名+impl)
c.接口允许多实现(多继承),一个子类可以同时使用implements实现若干接口
在这里插入图片描述

注:真正new的子类才有意义,不要被前边的类名称或接口名称搞晕。
通过共同子类建立的关系。

例子:

interface IMessage{
    //全局常量,final为常量,static为全局变量
    public static final String MSG = "BIT";
    //抽象方法
    public abstract void getMsg();
}
interface INews{
    public abstract void getNews();
}
//此时MessageImpl同时是INews与IMessage的子类
class MessageImpl implements IMessage,INews{
    public void getMsg(){
        System.out.println(MSG);
    }
    public void getNews(){
        System.out.println(MSG);
    }
}
public class Test{
    public static void main(String[] args) {
        IMessage msg = new MessageImpl() ;
        msg.getMsg();
        //INews news = new MessageImpl();
        //父接口间的相互转换。
        INews news = (INews) msg;
        news.getNews();
    }
}

运行结果:
在这里插入图片描述

d.接口中只允许public权限,即便不写也是public.接口中abstract,final,static均可省略不写.(强制要求不写)
阿里编码规约:接口中的方法和属性不要加任何修饰符号,public也不要加,保持代码的简洁性.
e.当子类既需要继承抽象类又需要实现接口时,先extends一个抽象类而后使用implements实现多个接口.(继承单继承,未知写后边)
例子:

interface IMessage{
    //全局常量,final为常量,static为全局变量
    public static final String MSG = "BIT";
    //抽象方法
    public abstract void getMsg();
}
abstract class News{
    public abstract void getNews();
}
class MessageImpl extends News implements IMessage{
     public void getMsg(){
        System.out.println(MSG);
    }
    public void getNews(){
        System.out.println(MSG);
    }
}
public class Test{
     public static void main(String[] args) {
        IMessage msg = new MessageImpl() ;
        msg.getMsg();
        //News news = new MessageImpl();
         //IMessage与News有共同的子类
        News news = (News) msg;
        news.getNews();
    }
}

运行结果:
在这里插入图片描述
f.接口和抽象类的关系
抽象类可以使用implements实现多个接口,接口不能继承抽象类(抽象类是普通类的超集),接口可以使用extends继承多个父接口.
例子:

interface A{
    //抽象方法,有返回值声明
    void A();
}
interface B{
    //抽象方法
    void B();
}
interface  C extends A,B{
    void C();
}
class D implements C{
    public void A(){ }
    public void B(){ }
    public void C(){ }
}
public class Test{
     public static void main(String[] args) {
       C c = new D();
       c.C();
    }
}

3.接口应用场景: 混合

  • 定义操作标准(USB接口、Type-c接口 、5G标准)
  • 表示一种能力、行为
    例子:
//定义标准
interface  USB{
    //安装驱动
    void setUp();
    //正常工作
    void work();
}
class Mouse implements USB{
    public void setUp(){
        System.out.println("安装鼠标驱动。。");
    }
    public void work(){
        System.out.println("鼠标正常工作");
    }
}
class Keyboard implements USB{
    public void setUp(){
        System.out.println("安装键盘驱动。。");
    }
    public void work(){
        System.out.println("键盘正常工作");
    }
}
class Computer{
    public void plugin(USB usb){
        usb.setUp();
        usb.work();
    }
}
public class Test{
     public static void main(String[] args) {
         Computer computer = new Computer();
         computer.plugin(new Mouse());
         computer.plugin(new Keyboard());
     }
}

结果:
在这里插入图片描述

23种设计模式–软件工程

代码重构:扩展功能(在基础代码之上增加功能)
《HeadFirst设计模式》
五大设计原则:

OCP原则(开闭原则)

定义:一个软件实体如类,接口等应该对扩展开放,修改关闭.

所有设计模式先找第三方(找到此设计模式,共同的父类)。
第三方:模板类,将核心算法与具体子类相分离,子类只需要覆写具体的某几步流程即可.

模板设计模式(模板方法):

  • 基于抽象类的设计模式
定义:在一个方法中定义一个算法的骨架(如冲泡饮料流程),而将一些步骤延迟到子类中实现
  • 优点:模板模式可以使得子类在不改变核心算法的基础上,具体实现算法中的某些步骤

举例:星巴克冲咖啡,泡茶
重复代码一次都不准出现
1.(核心):为了不让子类修改,将核心配置封装在父类中 -->将方法使用final封装。

  • 代码:冲咖啡,泡茶
  • 问题:咖啡与茶在制作过程中,烧水与倒入杯中的两个过程重复操作,
  • 想法:将这两个方法提取出放在父类(基类)中,让咖啡与茶都继承此父类.
 class CaffeineBeverage{
     public void boilWater(){}
     public void pourInCup(){}
 }

例子:

abstract class CaffeineBeverage {
    //核心算法,子类只能使用。
    public final void prepareRecipe() {
        boilWater();
        //抽象方法,在父类中不知道子类要什么饮料
        brewBeverage();
        //抽象方法,同上
        pourInCup();
        addCondiments();
    }
    public void boilWater() {
        System.out.println("将水烧开");
    }
    public void pourInCup() {
        System.out.println("将饮料倒入杯中");
    }
    public abstract void brewBeverage();
    public abstract void addCondiments();
}
class Coffee extends CaffeineBeverage{
    public void brewBeverage(){
        System.out.println("冲泡咖啡");
    }
    public void addCondiments(){
        System.out.println("加糖和牛奶");
    }
}
class Tea extends CaffeineBeverage{
    public void brewBeverage(){
        System.out.println("浸泡茶包");
    }
    public void addCondiments(){
        System.out.println("加柠檬");
    }
}
public class Test{
    public static void main(String[] args) {
        CaffeineBeverage coffee = new Coffee();
        System.out.println("给大佬泡咖啡");
        coffee.prepareRecipe();
        System.out.println("---------");
        CaffeineBeverage tea = new Tea();
        System.out.println("给大佬递茶");
        tea.prepareRecipe();
    }
}
  • 我们来看此时的类图;
    在这里插入图片描述

模板类的组成:

类比于实验模板,简历模板

  • final修饰的核心算法
  • Abstract修饰的抽象方法,延迟子类实现
  • 普通具体方法,所有子类都一样,子类直接使用即可
  • 钩子方法 hook()
    –默认不做事的方法,子类可以视情况而定,是否需要覆写.
    钩子方法的使用:
import java.util.Scanner;

abstract class CaffeineBeverage {
    //核心算法,子类只能使用。
    public final void prepareRecipe() {
        boilWater();
        //抽象方法,在父类中不知道子类要什么饮料
        brewBeverage();
        //抽象方法,同上
        pourInCup();
        if(isCustomerWantsCondiments()){
            addCondiments();
        }
    }
    public void boilWater() {
        System.out.println("将水烧开");
    }
    public void pourInCup() {
        System.out.println("将饮料倒入杯中");
    }
    public abstract void brewBeverage();
    public abstract void addCondiments();
    //钩子方法,默认所有饮料均需要加调料
    public boolean isCustomerWantsCondiments(){
        return true;
    }
}
class Coffee extends CaffeineBeverage{
    public void brewBeverage(){
        System.out.println("冲泡咖啡");
    }
    public void addCondiments(){
        System.out.println("加糖和牛奶");
    }
}

class Tea extends CaffeineBeverage{
    public void brewBeverage(){
        System.out.println("浸泡茶包");
    }
    public void addCondiments(){
        System.out.println("加柠檬");
    }
    public boolean isCustomerWantsCoundiments(){
        System.out.println("您需要加柠檬吗?y表示需要");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        if(str.equals("y")){
            System.out.println("客户想要柠檬");
            return true;
        }else{
            System.out.println("客户喜欢原味");
            return false;
        }
    }
}
public class Test{
    public static void main(String[] args) {
        CaffeineBeverage coffee = new Coffee();
        System.out.println("给大佬泡咖啡");
        coffee.prepareRecipe();
        System.out.println("---------");
        CaffeineBeverage tea = new Tea();
        System.out.println("给大佬递茶");
        tea.prepareRecipe();
    }
}

运行结果:
在这里插入图片描述

工厂设计模式(重点)

Java基础要求掌握三种实际模式:

  • 工厂
  • 代理
  • 单例

第三方:工厂类,将客户端的产生对象与具体子类分离,提取(解耦)到专门的工厂类中产生对象.

a.简单工厂模式

1.没有工厂类时,用户无法便捷灵活的得到想要的产品.

  • 问题本质:主方法(客户端)直接与具体产品交互.
  • 解决方法:将客户端产生商品的行为(new 对象)提取到一个新的类中–>工厂类
    **

特点:

  • 一个抽象产品类(接口,如:computer)
  • 多个具体的产品类(如:Macbookpro)
  • 一个工厂(负责生产所有具体商品,客户端与工厂交互,不与具体产品交互)
当多个具体产品呈现出家族式特征时(如微软系,苹果系),
为了保证不同产品系之间的隐私性,不同产品系有自己的工厂。

b.工厂方法模式

  • 当产品出现家族式特征时

特点:

  • 一个抽象产品类(接口,如Computer)
  • 多个具体的产品类(如MacbookPro)
  • 一个抽象工厂
  • 多个具体工厂(如微软工厂,苹果工厂)

代理设计模式

—类比代练或代购

  • 真实业务类
  • 辅助类

代理模式:
第三方:代理类,将真实业务与辅助操作解耦(买电脑与出国排队,发快递解耦).

特点:一个接口,两个子类,其中一个子类负责完成真实业务,
另一个子类辅助之

代理类中:
1.需要传入真实业务对象,代理类需要知道真实客户是谁,完成真实业务是由真实对象来完成,代理只需要辅助之,通过构造方法传入。
2.传入的是接口对象:只要是接口中定义的业务,代理都可以进行代理.(只要是买电脑,代购都可以处理,若传入真实类,则只能代购具体品牌电脑)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值