> 技术文档 > Java 面向对象实战:用披萨制作项目理解继承、多态与工厂模式

Java 面向对象实战:用披萨制作项目理解继承、多态与工厂模式

       刚学完 Java 基础语法?想通过实战项目理解面向对象(OOP)核心思想?这篇博客带你用「披萨制作小项目」吃透继承、方法重写、多态、工厂模式!全程保姆级解析,代码 + 思路一步到位,适合前端转 Java / 纯新手入门~

目录

一、项目背景:为什么选 “披萨制作”?

二、需求分析:用户要做什么?

三、核心知识点:用 OOP 解决问题

四、代码分步解析:从父类到工厂

1. 父类Pizza:封装公共属性

2. 子类BaconPizza:继承 + 扩展 + 重写

3. 子类FruitsPizza:和培根披萨逻辑一致

4. 工厂类PizzaStore:解耦对象创建

5. 测试类Test:用户交互入口

五、运行效果:控制台交互示例

场景 1:选培根披萨

场景 2:选水果披萨

六、总结:学到了哪些 OOP 核心?

七、扩展思考:让项目更完善


一、项目背景:为什么选 “披萨制作”?

      学编程最头疼的是 **“语法懂了,一写项目就懵”。这个小项目模拟真实场景:用户选披萨类型→输入定制参数→程序输出订单详情。通过 “做披萨” 的流程,把继承、多态、工厂模式 ** 这些抽象概念落地,看完就能实操!

二、需求分析:用户要做什么?

  • 选择披萨类型:培根披萨(需填 “培根克数”)、水果披萨(需填 “水果配料”)
  • 输入公共参数:披萨大小(寸)、价格(元)
  • 输出结果:披萨名称、大小、价格 + 各自的定制信息(培根克数 / 水果配料)

三、核心知识点:用 OOP 解决问题

先记住这张面向对象核心逻辑图(新手建议截图保存):

关键概念拆解:

  1. 继承(Inheritance):子类(培根 / 水果披萨)复用父类(Pizza)的属性(名称、大小、价格)和方法,减少重复代码。
  2. 方法重写(Override):子类重写父类的showPizza方法,添加自己的 “定制信息”(培根克数 / 水果配料)。
  3. 多态(Polymorphism):父类类型的变量(Pizza pizza)可以指向子类对象(BaconPizza/FruitsPizza),调用方法时自动执行子类的重写逻辑。
  4. 工厂模式(Factory Pattern):用PizzaStore工厂类封装对象创建逻辑,用户只需选类型,不用关心 “怎么 new 对象”,降低代码耦合。

四、代码分步解析:从父类到工厂

1. 父类Pizza:封装公共属性

public class Pizza { // 封装属性:用private隐藏细节,通过getter/setter访问 private String name; // 披萨名称 private int size; // 披萨大小(寸) private int price; // 披萨价格(元) // 核心方法:展示披萨信息(子类会重写它!) public String showPizza() { return \"匹萨的名字是:\" + name + \"\\n匹萨的大小是:\" + size + \"寸\\n匹萨的价格:\" + price + \"元\"; } // 构造器(无参+全参):方便创建对象 public Pizza() {} public Pizza(String name, int size, int price) { this.name = name; this.size = size; this.price = price; } // getter/setter:访问private属性 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; }}

       关键理解:父类像 “模板”,定义所有披萨的公共属性和基础行为(如showPizza),子类继承后可以 “复用 + 扩展”。

2. 子类BaconPizza:继承 + 扩展 + 重写

public class BaconPizza extends Pizza { // 子类特有属性:培根克数 private int weight; // 构造器:调用父类构造器(super)初始化公共属性 public BaconPizza(String name, int size, int price, int weight) { super(name, size, price); // 必须先调用父类构造器 this.weight = weight; } // 重写父类方法:添加“培根克数”信息 @Override public String showPizza() { // super.showPizza() 调用父类的基础信息 return super.showPizza() + \"\\n培根的克数是:\" + weight + \"克\"; } // getter/setter public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; }}

关键理解

  • extends Pizza:子类继承父类,拿到name/size/priceshowPizza方法。
  • super(...):必须在子类构造器第一行调用父类构造器,初始化继承的属性。
  • @Override:重写父类方法,让 “展示信息” 更具体(加上培根克数)。

3. 子类FruitsPizza:和培根披萨逻辑一致

public class FruitsPizza extends Pizza { // 子类特有属性:水果配料 private String burdening; public FruitsPizza(String name, int size, int price, String burdening) { super(name, size, price); this.burdening = burdening; } // 重写父类方法:添加“水果配料”信息 @Override public String showPizza() { return super.showPizza() + \"\\n你要加入的水果:\" + burdening; } // getter/setter public String getBurdening() { return burdening; } public void setBurdening(String burdening) { this.burdening = burdening; }}

       对比学习:和BaconPizza的区别仅在于特有属性(克数→配料)重写内容(培根信息→水果信息),这就是继承的威力—— 复用框架,只改细节!

4. 工厂类PizzaStore:解耦对象创建

import java.util.Scanner;public class PizzaStore { public static Pizza getPizza(int choice) { Scanner sc = new Scanner(System.in); Pizza p = null; // 父类类型变量,准备指向子类对象(多态!) switch (choice) { case 1: // 培根披萨 System.out.println(\"请录入培根的克数:\"); int weight = sc.nextInt(); System.out.println(\"请录入匹萨的大小:\"); int size = sc.nextInt(); System.out.println(\"请录入匹萨的价格:\"); int price = sc.nextInt(); // 创建子类对象,赋值给父类变量(多态) p = new BaconPizza(\"培根匹萨\", size, price, weight); break; case 2: // 水果披萨 System.out.println(\"请录入你想要加入的水果:\"); String burdening = sc.next(); System.out.println(\"请录入匹萨的大小:\"); int sizeFruit = sc.nextInt(); System.out.println(\"请录入匹萨的价格:\"); int priceFruit = sc.nextInt(); // 创建子类对象,赋值给父类变量(多态) p = new FruitsPizza(\"水果匹萨\", sizeFruit, priceFruit, burdening); break; } return p; // 返回父类类型,调用者无需关心具体子类 }}

关键理解

  • 工厂的作用:把 “创建披萨对象” 的逻辑集中在这里,测试类只需调用getPizza(choice),不用写复杂的new逻辑,符合单一职责原则
  • 多态体现Pizza p可以是BaconPizzaFruitsPizza,返回给调用者时,调用p.showPizza()会自动执行子类的重写方法!

5. 测试类Test:用户交互入口

import java.util.Scanner;// 注意:需补充包路径public class Test { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println(\"请选择你想要购买的匹萨(1.培根匹萨 2.水果匹萨):\"); int choice = sc.nextInt(); // 调用工厂创建披萨(父类类型接收子类对象) Pizza pizza = PizzaStore.getPizza(choice); // 多态:实际执行子类的showPizza方法! System.out.println(pizza.showPizza()); }}

执行流程
用户选类型→工厂创建对应披萨对象→测试类调用showPizza→输出子类重写后的详细信息。

五、运行效果:控制台交互示例

场景 1:选培根披萨

请选择你想要购买的匹萨(1.培根匹萨 2.水果匹萨):1 请录入培根的克数:23 请录入匹萨的大小:12 请录入匹萨的价格:103 匹萨的名字是:培根匹萨 匹萨的大小是:12寸 匹萨的价格:103元 培根的克数是:23克 

场景 2:选水果披萨

请选择你想要购买的匹萨(1.培根匹萨 2.水果匹萨):2 请录入你想要加入的水果:榴莲,芒果,草莓 请录入匹萨的大小:10 请录入匹萨的价格:76 匹萨的名字是:水果匹萨 匹萨的大小是:10寸 匹萨的价格:76元 你要加入的水果:榴莲,芒果,草莓 

六、总结:学到了哪些 OOP 核心?

  1. 继承:子类复用父类属性和方法,减少重复代码(父类写一次,子类直接用)。
  2. 方法重写:子类根据需求 “定制” 父类方法,让行为更具体(比如培根披萨加克数、水果披萨加配料)。
  3. 多态:父类类型变量可以指向子类对象,调用方法时自动执行子类逻辑(Pizza pizza能调用BaconPizzashowPizza)。
  4. 工厂模式:把对象创建逻辑封装到工厂类,降低代码耦合(测试类不用关心 “怎么 new 披萨”,只管选类型)。

七、扩展思考:让项目更完善

  • 添加更多披萨类型:比如海鲜披萨(需填 “海鲜种类”),继承Pizza类,重写showPizza即可。
  • 优化输入验证:比如披萨大小不能为负数、价格不能小于成本,在工厂类里加if判断。
  • 界面化改造:用 Java Swing 或 JavaFX 做图形界面,把控制台交互改成按钮选择(进阶方向)。

写在最后:面向对象的核心是 **“抽象共性,封装变化”**—— 父类抽象公共逻辑,子类封装各自的 “变化点”(培根 / 水果的不同)。这个小项目把复杂概念拆成了 “继承→重写→多态→工厂” 的链条,跟着敲一遍,OOP 思想就吃透一半啦!

       如果对你有帮助,点赞 + 收藏鼓励一下呀~ 后续会更 Java Swing 做图形界面的扩展版,关注不迷路!

(代码可直接复制运行,注意包路径和 Scanner 导入~ 有问题评论区见!)