java中的抽象类到底如何用

一、设计模式中的使用

1. 模板方法模式

1.定义:当你需要为一组相关类提供一个操作的框架,其中一些步骤是固定的,而其他步骤(由抽象方法表示)则在子类中实现。例如,制定一个学习计划,其中学习计划的基本流程是固定的(比如先预习、再上课、最后复习),但是每一步的具体实现可能因学生类型而异。

2.结构

  • 抽象类:定义并实现一个模板方法,该方法定义了算法的骨架,并调用一些抽象方法,这些抽象方法由子类实现。
  • 具体子类:实现抽象类中声明的抽象方法,完成具体的步骤。

3.代码

定义一个抽象类


/**
 * 抽象类:学习计划模板
 */
public abstract class StudyPlan {
    // 模板方法,定义学习流程的骨架
    public final void studyProcess(String name) {
        preview(name);
        attendClass(name);
        review(name);
    }
    
    // 预习
    protected abstract void preview(String name);
    // 上课
    protected abstract void attendClass(String name);
    // 复习
    protected abstract void review(String name);
}

中学生学习计划子类的实现

/**
 * 中学生学习计划
 */
public class MiddleStudentStudyPlan extends StudyPlan {
    @Override
    protected void preview(String name) {
        System.out.println(name + ":预习");
    }

    @Override
    protected void attendClass(String name) {
        System.out.println(name + ":上课");
    }

    @Override
    protected void review(String name) {
        System.out.println(name + ":复习");
    }
}

小学生学习计划子类的实现

/**
 * 小学生学习计划
 */
public class PrimaryStudentStudyPlan extends StudyPlan {
    @Override
    protected void preview(String name) {
        System.out.println(name + ":预习");
    }

    @Override
    protected void attendClass(String name) {
        System.out.println(name + ":上课");
    }

    @Override
    protected void review(String name) {
        System.out.println(name + ":复习");
    }
    
}

测试

public class TestMoBan {
    public static void main(String[] args) {
        // 小学生的学习计划
        new PrimaryStudentStudyPlan().studyProcess("小学生");
        // 中学生的学习计划
        new MiddleStudentStudyPlan().studyProcess("中学生");
    }
}

2. 抽象工厂模式

1.什么是抽象工厂模式 : 它提供了一种方式来创建一系列相关的或相互依赖的对象,而无需指定它们具体的类。这种模式允许客户端使用抽象接口来操作对象,而不需要了解具体类的实现细节,从而使得系统在不修改具体类的情况下引入新产品族变得容易。

2.结构

  • 抽象工厂:声明一个创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类。
  • 具体工厂:实现抽象工厂接口,负责创建一个产品系列的具体对象。
  • 抽象产品:定义一组产品的接口,使得在各个具体产品之间可以互换。
  • 具体产品:实现抽象产品接口的具体类,每个具体工厂都创建一个具体产品的实例。

3.优点

  • 将产品的创建和使用分离开来,使得客户端代码更加简洁,并且向客户端隐藏产品的创建细节。
  • 将一系列相关的产品对象的创建工作统一到一个抽象工厂中,客户端只需要访问抽象工厂即可,具 体的产品工厂可以灵活替换。
  • 当一个族中的多个对象被设计成一起工作时, 它能够保证客户端始终只使用同一个族中的对象。

4.缺点

  • 一个产品族下增加新的产品等级非常困难,甚至需要修改抽象层代码和其下所有的实现, 严重违背了“开闭原则”。
  • 增加了代码的复杂性,增加了系统的抽象性,增加了理解难度

5.实现方式太麻烦了,这里就不演示代码了,有兴趣的博主可以自行百度。

二、扩展性和灵活性

1.设定接口规范:抽象类可以定义一组抽象方法,这些方法没有具体实现,要求所有子类必须实现这些方法。这实际上是在设定一个接口规范,确保所有子类都遵循相同的操作接口,即使它们的具体实现可能不同。这提高了系统的规范性和一致性。

2.提供默认实现:除了抽象方法外,抽象类还可以包含具体方法,为子类提供默认行为的实现。这意味着子类可以重用这些实现,或者覆盖它们以提供定制化的功能。这种机制既减少了代码重复,又增加了灵活性,因为子类可以选择性地覆盖或扩展父类的行为。

3.支持多态性:通过抽象类,可以利用多态性原则,编写与具体实现分离的代码。这意味着你可以针对抽象基类编程,而不用担心具体子类的细节。这样,当需要引入新的子类或修改现有子类的实现时,只需保持对外接口不变,即可轻松替换或扩展功能,而不影响到调用这些抽象类的地方。

4.代码组织和模块化 :抽象类有助于将相关的功能组织在一起,形成逻辑上的模块。每个抽象类可以代表一个概念或功能领域,它的子类则代表这个领域内的具体变体。这种组织方式使得代码结构清晰,易于理解和维护,同时也便于团队协作开发。

5.易于扩展:随着项目的发展,需求可能会变化,需要添加新的功能。抽象类作为基础框架,允许你在不破坏原有代码结构的基础上,通过添加新的子类来扩展功能。这种设计模式使得系统更加灵活,能够更好地适应未来的变化。

6.演示

  1. 创建一个抽象工厂
public abstract class DbConnectionFactory {
    // 打开链接
    public abstract void openConnection(String name);
	// 关闭链接
    public abstract void closeConnection(String name);
    
}
  1. 创建MySQL连接
public class MySQLConnection extends DbConnectionFactory {

    @Override
    public void openConnection(String name) {
        System.out.println(name + ": 打开了MySQL连接");
    }

    @Override
    public void closeConnection(String name) {
        System.out.println(name + ": 关闭了MySQL连接");
    }
}
  1. 创建PgSQL连接
public class PgSQLConnection extends DbConnectionFactory {

    @Override
    public void openConnection(String name) {
        System.out.println(name + ":打开了PgSQL连接");
    }

    @Override
    public void closeConnection(String name) {
        System.out.println(name + ":关闭了PgSQL连接");
    }
}
  1. 测试
public class TestMain {
    public static void main(String[] args) {
        DbConnectionFactory mySQLConnection = new MySQLConnection();
        mySQLConnection.openConnection("用户A");
        mySQLConnection.closeConnection("用户A");

        PgSQLConnection pgSQLConnection = new PgSQLConnection();
        pgSQLConnection.openConnection("用户B");
        pgSQLConnection.closeConnection("用户B");
    }
}

三、为什么开发时抽象类用的很少,反而用接口的很多

1.多重继承限制:Java中类只允许单一继承,这意味着一个类只能继承一个抽象类。然而,一个类却可以实现多个接口,这为多继承提供了替代方案,增加了设计的灵活性。因此,当需要实现多个行为规范时,接口成为更自然的选择。

2.多重继承限制:Java中类只允许单一继承,这意味着一个类只能继承一个抽象类。然而,一个类却可以实现多个接口,这为多继承提供了替代方案,增加了设计的灵活性。因此,当需要实现多个行为规范时,接口成为更自然的选择。

3.接口的进化:自从Java 8引入默认方法和静态方法以来,接口变得更加灵活。默认方法允许在接口中提供实现,这样就能够在不破坏现有实现的情况下向接口添加新功能,这在一定程度上弥补了接口与抽象类之间功能上的差距。

4.设计原则:面向接口编程鼓励针对接口而非实现编程,这有利于降低耦合度,提高代码的可测试性和可维护性。接口更纯粹地体现了这一原则,因为它不包含任何状态或具体实现,强调的是行为的约定而非实现细节。

5.框架和库的偏好:现代框架和库,如Spring框架,倾向于使用接口来进行依赖注入,以利用其提供的灵活性和可配置性。这种设计模式鼓励使用接口来定义组件之间的合同。

6.清晰的职责划分:接口通常用于定义类型或行为的契约,而抽象类可能包含更多关于实现细节的逻辑。使用接口可以帮助开发者更清晰地分离关注点,使得代码更容易理解和维护。:自从Java 8引入默认方法和静态方法以来,接口变得更加灵活。默认方法允许在接口中提供实现,这样就能够在不破坏现有实现的情况下向接口添加新功能,这在一定程度上弥补了接口与抽象类之间功能上的差距。

7.设计原则:面向接口编程鼓励针对接口而非实现编程,这有利于降低耦合度,提高代码的可测试性和可维护性。接口更纯粹地体现了这一原则,因为它不包含任何状态或具体实现,强调的是行为的约定而非实现细节。

8.框架和库的偏好:现代框架和库,如Spring框架,倾向于使用接口来进行依赖注入,以利用其提供的灵活性和可配置性。这种设计模式鼓励使用接口来定义组件之间的合同。

9.清晰的职责划分:接口通常用于定义类型或行为的契约,而抽象类可能包含更多关于实现细节的逻辑。使用接口可以帮助开发者更清晰地分离关注点,使得代码更容易理解和维护。

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值