天天看点

想要写出优秀的Java代码?学会抽象类和策略设计模式是关键

作者:你的老师父

在Java开发中,我们经常会遇到需要“抽象”的情况。比如,我们可能有多个类需要实现相同的方法,但具体实现方式又不同;或者我们需要定义一些规范,但具体细节由子类实现。这时候,我们就可以使用Java中的抽象类和抽象方法来解决问题。

另外,在软件开发中,我们也经常会遇到需要根据不同的情况采取不同的策略的情况。此时,我们可以运用策略设计模式来处理。本文将结合代码示例,详细介绍Java中的抽象类、抽象方法和策略设计模式,并带着大家一起实现一个简单的策略模式示例。

Java抽象类和抽象方法

一、什么是抽象类?

在Java中,抽象类是一种特殊的类,它不能被实例化,只能作为其他类的父类来使用。抽象类通常用来定义一些基础的方法和属性,供子类继承和实现。

二、如何定义抽象类?

在Java中,可以使用abstract关键字来定义一个抽象类。抽象类中可以包含非抽象方法和属性,也可以包含抽象方法。抽象方法是没有具体实现的方法,其在抽象类中只有声明,而不需要具体的实现。

下面是一个抽象类的示例:

public abstract class Shape {
    protected int x, y;
    
    public void move(int newX, int newY) {
        x = newX;
        y = newY;
    }
    
    public abstract double area();
}
           

上述代码中,Shape是一个抽象类,它包含两个非抽象属性x和y,以及两个方法move()和area()。其中,move()方法是具体实现的,而area()方法则是抽象的,需要子类来实现。

三、如何实现抽象方法?

当一个类继承了一个抽象类时,它必须实现该抽象类中所有的抽象方法,否则该类仍然是一个抽象类。如果不想实现某个抽象方法,也可以将该类定义为抽象类。

下面是一个继承了抽象类的示例:

public class Circle extends Shape {
    private int radius;
    
    public Circle(int x, int y, int r) {
        this.x = x;
        this.y = y;
        radius = r;
    }
    
    public double area() {
        return Math.PI * radius * radius;
    }
}
           

上述代码中,Circle类继承了Shape抽象类,并实现了area()方法。注意到,在Circle类中需要使用protected关键字来访问Shape类中的属性x和y。

四、抽象类和接口的区别

虽然抽象类和接口都能够定义抽象方法,但它们之间还是有一些差异的。下面是它们主要的区别:

  1. 抽象类可以包含非抽象方法和属性,而接口只能包含抽象方法和常量。
  2. 一个类只能继承一个抽象类,但可以实现多个接口。
  3. 抽象类中的抽象方法可以有具体的实现,但接口中的所有方法都没有实现。
  4. 接口中的方法默认是公开的,而抽象类中的方法可以有不同的访问权限。

综上所述,抽象类和接口都是用来实现多态性的工具,但它们的使用场景略有不同。当需要定义一些基础的属性和方法,并希望子类继承时,可以使用抽象类;当需要定义规范或者行为,以供类实现时,可以使用接口。

策略设计模式

一、什么是策略设计模式?

策略设计模式是一种软件设计模式,它可以在运行时根据不同的情况选择不同的算法或策略,来达到相同的目标。策略模式通常包含一个策略接口和多个实现该接口的类,以及一个包含策略对象的环境类。

二、如何实现策略设计模式?

下面我们将通过一个简单的示例,来介绍如何使用策略设计模式。

假设我们正在编写一个商场结算系统,它需要根据不同的产品类型和数量,计算出不同的总价。为了实现这个功能,我们可以定义一个PricingStrategy接口,以及多个实现该接口的类,比如:

public interface PricingStrategy {
    double calculatePrice(double price, int quantity);
}

public class NormalStrategy implements PricingStrategy {
    public double calculatePrice(double price, int quantity) {
        return price * quantity;
    }
}

public class DiscountStrategy implements PricingStrategy {
    public double calculatePrice(double price, int quantity) {
        return price * quantity * 0.8;
    }
}

public class RebateStrategy implements PricingStrategy {
    public double calculatePrice(double price, int quantity) {
        return price * quantity - 10;
    }
}
           

上述代码中,PricingStrategy是策略接口,它定义了一个calculatePrice()方法。NormalStrategy、DiscountStrategy和RebateStrategy分别是实现了PricingStrategy接口的类,它们分别采用不同的算法来计算总价。

接下来,我们可以定义一个包含策略对象的环境类ShoppingCart,用来根据不同的情况选择不同的算法:

public class ShoppingCart {
    private PricingStrategy strategy;
    
    public void setStrategy(PricingStrategy strategy) {
        this.strategy = strategy;
    }
    
    public double checkout(double price, int quantity) {
        return strategy.calculatePrice(price, quantity);
    }
}
           

在ShoppingCart类中,我们可以通过setStrategy()方法来设置策略对象,并在checkout()方法中调用该对象的calculatePrice()方法,以获得最终的总价。

三、如何使用策略设计模式?

现在,我们已经实现了一个简单的策略模式示例。下面是一个使用该示例的代码:

public static void main(String[] args) {
    ShoppingCart cart = new ShoppingCart();
    PricingStrategy strategy = new DiscountStrategy(); // 选择打折策略
    cart.setStrategy(strategy);
    
    double price = 100;
    int quantity = 5;
    double totalPrice = cart.checkout(price, quantity);
    
    System.out.println("Total price: " + totalPrice);
}
           

上述代码中,我们首先创建了一个ShoppingCart对象,并设置了一个打折策略。然后,我们传入了商品的单价和数量,调用了checkout()方法,获得了最终的总价。

总结

本文介绍了Java中的抽象类、抽象方法和策略设计模式,并通过代码示例详细讲解了如何定义抽象类和实现抽象方法,以及如何使用策略设计模式来根据不同的情况选择不同的算法或策略。

在编写Java程序时,抽象类和抽象方法可以帮助我们定义基础的属性和方法,并实现多态性;而策略设计模式则可以让我们根据不同的情况选择不同的算法,从而达到相同的目标。这些工具在Java程序开发中都扮演着重要的角色,掌握它们的使用方法对于提高代码的可读性、可维护性和可扩展性都有很大的帮助。

虽然本文涉及的知识点比较基础,但是掌握好了这些知识点,可以为您的Java编程之路打下坚实的基础。同时,在学习过程中也不要忘记将知识点与实际项目相结合,通过实践来加深理解和掌握。最后,希望本文能够为你的学习和工作带来一些启发和帮助!

最后再留几个问题

  1. 抽象类和接口各有什么优缺点?你更倾向于使用哪一个?
  2. 你认为在实际开发中,什么情况下适合使用策略设计模式?
  3. 策略设计模式与工厂设计模式有什么不同?它们可以一起使用吗?
  4. Java中除了抽象类和接口之外,还有哪些机制可以实现多态性?
  5. 抽象类和普通类相比,有哪些需要注意的地方?

这些问题可以帮助读者深入探讨本文介绍的知识点,并在实际应用中取得更好的效果。

继续阅读