Java中无需重载即可适配多模型类的方法?最佳实践咨询
解决方案:面向抽象编程(抽象类+开闭原则)
针对你的需求,最贴合Java最佳实践的方案是通过抽象类统一食物模型的行为,消除重复代码,同时让consumeFood方法接收抽象类型参数,无需重载即可支持所有食物类,后续扩展新菜单类也无需修改现有核心代码。
步骤1:定义抽象基类Food
将Bread和Meat的公共属性、方法抽象到父类中,复用配菜拼接逻辑,仅让子类实现食物类型的获取:
import java.util.StringJoiner; public abstract class Food { private String[] sideDishes; // 子类必须实现,返回具体食物类型 public abstract String getFoodType(); public void setConsumeWith(String[] sideDishes) { this.sideDishes = sideDishes; } public String[] getConsumeWith() { return sideDishes; } // 统一实现配菜拼接逻辑,避免重复代码 public String enjoyWith() { StringJoiner joiner = new StringJoiner(", ", "", ""); for (String side : getConsumeWith()) { joiner.add(side.trim()); } String sides = joiner.toString(); // 处理最后一个配菜替换为"or" if (sides.contains(",")) { int lastCommaIndex = sides.lastIndexOf(","); sides = sides.substring(0, lastCommaIndex) + " 或" + sides.substring(lastCommaIndex + 1); } return "享用 " + getFoodType() + ",搭配 " + sides + "。"; } }
注:用StringJoiner替代原有的字符串拼接逻辑,更简洁高效,符合Java 8+编码规范
步骤2:重构Bread和Meat类
让它们继承Food抽象类,只需实现getFoodType方法,无需重复编写enjoyWith和配菜相关逻辑:
public class Bread extends Food { private String breadType; public void setBreadType(String breadType) { this.breadType = breadType; } @Override public String getFoodType() { return breadType; } }
public class Meat extends Food { private String meatType; public void setMeatType(String meatType) { this.meatType = meatType; } @Override public String getFoodType() { return meatType; } }
步骤3:简化Consume类
无需再写重载的consumeWith方法,直接接收Food类型参数即可:
public class Consume { public String consumeWith(Food food) { return food.enjoyWith(); } }
步骤4:修改MainStarter的consumeFood方法
将参数从Object改为Food,类型更安全,无需重载就能支持所有食物子类:
public class MainStarter { public static void main(String[] args) { Bread bread = new Bread(); String breadType = "黑麦面包"; String[] consumeBreadWith = {"黄油", "肉类", "花生酱"}; bread.setBreadType(breadType); bread.setConsumeWith(consumeBreadWith); consumeFood(bread); Meat meat = new Meat(); String meatType = "烤牛肉"; String[] consumeMeatWith = {"胡椒粉", "土豆", "青豆"}; meat.setMeatType(meatType); meat.setConsumeWith(consumeMeatWith); consumeFood(meat); } // 无需重载,自动支持所有Food子类 public static void consumeFood(Food food) { Consume consume = new Consume(); String result = consume.consumeWith(food); System.out.println(result); } }
后续扩展
新增菜单类(比如Vegetable)时,只需继承Food抽象类、实现getFoodType方法,无需修改consumeFood、Consume等现有代码,完全符合开闭原则(对扩展开放,对修改关闭)。
内容的提问来源于stack exchange,提问作者Joseph McTigue
相关产品推荐
相关产品推荐

