You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中IS关系实现咨询:披萨店菜品(披萨/意面)建模疑问

实现Dish与Pizza、Pasta的IS-A关系的Java方案

在Java中,Dish与Pizza、Pasta的IS-A关系(即“是一个”的继承关系)可以通过抽象父类+子类继承的方式实现,同时结合业务场景做扩展。以下是具体实现建议:

1. 基础类结构设计

将Dish定义为抽象类,封装所有菜品的通用属性与方法;Pizza和Pasta作为子类继承Dish,实现各自特有的属性与行为。

抽象父类Dish

包含所有菜品共有的属性(如ID、名称、价格等),以及通用方法,同时定义抽象方法让子类实现差异化逻辑:

import java.math.BigDecimal;

public abstract class Dish {
    private Long id;
    private String name;
    private BigDecimal price;
    private String description;
    private boolean available;

    // 构造方法、Getter/Setter省略

    // 通用方法:计算指定数量的菜品总价
    public BigDecimal calculateTotal(int quantity) {
        return price.multiply(new BigDecimal(quantity));
    }

    // 抽象方法:子类需实现各自的制作流程
    public abstract void prepare();
}

子类Pizza与Pasta

继承Dish并添加特有属性,同时实现父类的抽象方法:

import java.util.List;

public class Pizza extends Dish {
    private String size; // 如"SMALL"、"MEDIUM"、"LARGE"
    private List<String> toppings; // 配料列表

    // 构造方法、Getter/Setter省略

    @Override
    public void prepare() {
        System.out.println("制作披萨:擀面皮 → 涂抹酱料 → 添加配料 → 烘烤");
    }
}

public class Pasta extends Dish {
    private String noodleType; // 如"SPAGHETTI"、"LASAGNA"
    private String sauceType; // 如"MARINARA"、"ALFREDO"

    // 构造方法、Getter/Setter省略

    @Override
    public void prepare() {
        System.out.println("制作意面:煮面条 → 翻炒酱汁 → 混合面条与酱汁");
    }
}

2. 业务层多态使用

利用Java多态特性,在订单等业务逻辑中统一用Dish类型处理子类实例,简化代码:

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Order {
    private Long orderId;
    private List<Dish> dishes = new ArrayList<>();
    private LocalDateTime orderTime;

    public void addDish(Dish dish) {
        if (dish.isAvailable()) {
            dishes.add(dish);
        }
    }

    // 计算订单总金额
    public BigDecimal calculateOrderTotal() {
        return dishes.stream()
                .map(dish -> dish.calculateTotal(1))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

3. 持久层实现(基于JPA/Hibernate)

如果需要将菜品数据持久化到数据库,可通过JPA的继承策略实现,常用三种方式:

单表继承(Single Table)

所有菜品数据存于同一张表,用dish_type字段区分类型,适合查询性能优先的场景:

import jakarta.persistence.*;
import java.math.BigDecimal;

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dish_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Dish {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private BigDecimal price;
    private String description;
    private boolean available;
    // Getter/Setter省略
}

@Entity
@DiscriminatorValue("PIZZA")
public class Pizza extends Dish {
    private String size;
    @ElementCollection
    private List<String> toppings;
    // Getter/Setter省略
}

@Entity
@DiscriminatorValue("PASTA")
public class Pasta extends Dish {
    private String noodleType;
    private String sauceType;
    // Getter/Setter省略
}

联合表继承(Joined Table)

父类与子类各对应一张表,子类表仅存储特有属性与父类外键,适合数据结构清晰、无冗余的场景:
只需将Dish类的@Inheritance注解改为:

@Inheritance(strategy = InheritanceType.JOINED)

4. 扩展优化建议

  • 工厂模式解耦:新增DishFactory类统一创建菜品实例,避免业务代码直接依赖子类:
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

public class DishFactory {
    public static Dish createDish(String type, Map<String, Object> params) {
        return switch (type.toUpperCase()) {
            case "PIZZA" -> {
                Pizza pizza = new Pizza();
                pizza.setName((String) params.get("name"));
                pizza.setPrice((BigDecimal) params.get("price"));
                pizza.setSize((String) params.get("size"));
                pizza.setToppings((List<String>) params.get("toppings"));
                yield pizza;
            }
            case "PASTA" -> {
                Pasta pasta = new Pasta();
                pasta.setName((String) params.get("name"));
                pasta.setPrice((BigDecimal) params.get("price"));
                pasta.setNoodleType((String) params.get("noodleType"));
                pasta.setSauceType((String) params.get("sauceType"));
                yield pasta;
            }
            default -> throw new IllegalArgumentException("未知菜品类型:" + type);
        };
    }
}
  • 接口增强灵活性:若后续需扩展非菜品的可订购项,可定义Orderable接口,让Dish实现该接口,进一步解耦逻辑。

内容的提问来源于stack exchange,提问作者ZenBa2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:00:14