今天学习了抽象类、抽象方法及重写、多态输出

ScreenShot_2026-10-03_233143_889.png

ScreenShot_2026-10-03_233204_724.png

ScreenShot_2026-10-03_233221_992.png

main()

▼
text
复制代码
package cn.com.d99714.smart.service; import cn.com.d99714.smart.common.Config; import cn.com.d99714.smart.entity.*; public class SmartHomeTest { public static void main(String[] args) { // 厂家 Company vendor = new Company("张经理", "13829871635", "视声智能", "广州市黄埔区", "KNX全屋智能/灯光/安防"); // 业主 Person client1 = new Customer("赵今麦", "15138473848", "上海市静安区", 533); // 商家 Person client2 = new Company("李经理", "13150432864", "杜亚窗帘", "杭州市拱墅区", "智能窗帘/智能门锁"); // 师傅 Person worker = new Worker("王师傅","13022531893","电工",2,4.2); // 报价单:厂家给业主 SmartHomeQuotation quote1 = new SmartHomeQuotation( Config.QUOTATION_PREFIX + "20260001-000001", "2026-10-02 16:35:11", "赵女士静安府全屋智能", client1, vendor, 35800.0, 5800.0, 6500.0, 4200.0, 2000.0 ); // 报价单:厂家给商家 SmartHomeQuotation quote2 = new SmartHomeQuotation( Config.QUOTATION_PREFIX + "20260001-000002", "2026-10-02 16:37:20", "杜亚展厅智能改造", client2, vendor, 28000.0, 3500.0, 4000.0, 2500.0, 1500.0 ); // 打印报价单 System.out.println(quote1); System.out.println(); System.out.println(quote2); // 打印完整信息 System.out.println(); System.out.println("完整客户信息(点击查看)"); System.out.println(quote1.getClientFullInfo()); System.out.println(quote2.getClientFullInfo()); // 折扣测试 System.out.println(); System.out.println("折扣测试"); // 设置折扣 quote1.setTotalDiscount(0.85); quote2.setTotalDiscount(0.80); // 测试 calcTotal() + getDiscountedTotal() System.out.printf("%s 原始金额:%,.2f 元,%s后金额:%,.2f 元,优惠金额:%.2f 元%n", quote1.getQuotationNo(), quote1.calcOriginalTotalAmount(), quote1.getDiscountDesc(), // "85折" quote1.calcDiscountedTotalAmount(), quote1.calcOriginalTotalAmount() - quote1.calcDiscountedTotalAmount()); System.out.printf("%s 原始金额:%,.2f 元,%s后金额:%,.2f 元,优惠金额:%.2f 元%n", quote2.getQuotationNo(), quote2.calcOriginalTotalAmount(), quote2.getDiscountDesc(), // "8折" quote2.calcDiscountedTotalAmount(), quote2.calcOriginalTotalAmount() - quote2.calcDiscountedTotalAmount()); // 越界折扣测试 System.out.println(); System.out.println("越界折扣测试"); double invalidResult = quote1.getDiscountedTotal(1.5); System.out.printf("传入1.5(越界),返回:%,.2f 元%n", invalidResult); // Day40 批量汇总(数组遍历) System.out.println(); System.out.println("批量汇总"); SmartHomeQuotation[] quotes = {quote1, quote2}; double allTotal = 0; double allFinal = 0; for (SmartHomeQuotation q : quotes) { System.out.printf("%s 原价:%,.2f 元,%s后:%,.2f 元%n", q.getQuotationNo(), q.calcOriginalTotalAmount(), q.getDiscountDesc(), q.calcDiscountedTotalAmount()); allTotal += q.calcOriginalTotalAmount(); allFinal += q.calcDiscountedTotalAmount(); } System.out.printf("总优惠:%,.2f 元%n", allTotal - allFinal); // 一行摘要 System.out.println(); System.out.println("报价单摘要"); System.out.println(quote1.getSummaryLine()); System.out.println(quote2.getSummaryLine()); // Day41:多态遍历测试 System.out.println(); System.out.println("多态遍历测试"); Person[] people = {client1, client2, worker, vendor}; for (Person p : people) { System.out.println(p.showRole() + " " + p.getName()); System.out.println("自我介绍:" + p.introduce()); System.out.println(); } } }

Config配置类

▼
text
复制代码
package cn.com.d99714.smart.common; import java.time.format.DateTimeFormatter; public final class Config { // final类,禁止继承 private Config() { } // private构造方法,禁止实例化 // 校验规则组 public static final String PHONE_REGEX = "^1[3-9]\\d{9}$"; public static final String ERROR_PHONE_FORMAT = "手机号码格式不正确,已置空!"; public static final int MIN_WORK_YEAR = 0; public static final int MAX_WORK_YEAR = 70; public static final String ERROR_WORK_YEAR = "工龄0-70,其他无效!已置0"; public static final double MIN_SCORE = 0.0; public static final double MAX_SCORE = 5.0; public static final String ERROR_SCORE = "评分只能0-5,整数或一位小数!已置0"; public static final double MIN_HOUSE_AREA = 0.0; public static final double MAX_HOUSE_AREA = 5000.0; public static final String ERROR_HOUSE_AREA = "面积大于0小于5000,整数或一位小数!"; public static final double MIN_DISCOUNT_RATE = 0.0; // 0 = 免费 public static final double MAX_DISCOUNT_RATE = 1.0; // 1 = 原价 public static final double DEFAULT_DISCOUNT_RATE = 1.0; // 格式规则组 public static final DateTimeFormatter DATE_TIME_INPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static final DateTimeFormatter DATE_TIME_DISPLAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); public static final String AMOUNT_FORMAT = "%,.2f"; // 报价单标识组 public static final String QUOTATION_PREFIX = "Q-SM-"; public static final String LINE_CHAR = "-"; public static final int LINE_TITLE_REPEAT_COUNT = 50; public static final int LINE_REPEAT_COUNT = 56; public static final String VERSION = "V1.0"; // 显示标签组(预埋多语言,V1.1 进 i18n 表) public static final String QUOTATION_TITLE = "智能家居报价单"; public static final String LABEL_QUOTATION_NO = "报价编号:"; public static final String LABEL_QUOTATION_DATE = "报价日期:"; public static final String LABEL_VENDOR = "报价单位:"; public static final String LABEL_PROJECT_NAME = "项目名称:"; public static final String LABEL_CLIENT_INFO = "用户信息:"; public static final String LABEL_TOTAL_AMOUNT = "项目金额:"; public static final String LABEL_DETAIL_PREFIX = "其中:"; public static final String LABEL_DEVICE_COST = "设备金额:"; public static final String LABEL_MATERIAL_COST = "材料金额:"; public static final String LABEL_INSTALL_COST = "安装金额:"; public static final String LABEL_DEBUG_COST = "调试金额:"; public static final String LABEL_OTHER_COST = "其他金额:"; public static final String TAG_CUSTOMER = "【业主】"; public static final String TAG_COMPANY = "【公司】"; public static final String LABEL_DISCOUNT_RATE = "折扣率:"; public static final String LABEL_DISCOUNTED_AMOUNT = "折后金额:"; public static final String LABEL_DISCOUNT_AMOUNT = "优惠金额:"; // 消息提示组(预埋多语言) public static final String MSG_WARN_PREFIX = "【警告】 "; public static final String MSG_DISCOUNT_RATE_INVALID = "折扣率超出有效范围(0.0=免费|1.0=原价),已重置为原价."; public static final String MSG_DISCOUNT_RATE_MIN = "折扣率 0,为不收费!"; public static final String MSG_DISCOUNT_RATE_MAX = "折扣率 1,为没有折扣!"; }

SmartHomeQuotation业务实体类

▼
text
复制代码
package cn.com.d99714.smart.entity; import cn.com.d99714.smart.common.Config; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class SmartHomeQuotation { private String quotationNo = ""; private String quotationDate = ""; private String projectName = ""; private Person client; private Company vendor; private double deviceCost = 0.0; private double materialCost = 0.0; private double installCost = 0.0; private double debugCost = 0.0; private double otherCost = 0.0; // 分类折扣 private double deviceDiscount = 1.0; private double materialDiscount = 1.0; private double installDiscount = 1.0; private double debugDiscount = 1.0; private double otherDiscount = 1.0; // 整单折扣 private double totalDiscount = 1.0; public SmartHomeQuotation() { } public SmartHomeQuotation(String quotationNo, String quotationDate, String projectName, Person client, Company vendor, double deviceCost, double materialCost, double installCost, double debugCost, double otherCost) { this.setQuotationNo(quotationNo); this.setQuotationDate(quotationDate); this.setProjectName(projectName); this.setClient(client); this.setVendor(vendor); this.setDeviceCost(deviceCost); this.setMaterialCost(materialCost); this.setInstallCost(installCost); this.setDebugCost(debugCost); this.setOtherCost(otherCost); } public void setQuotationNo(String quotationNo) { this.quotationNo = quotationNo; } public void setQuotationDate(String quotationDate) { this.quotationDate = quotationDate; } public void setProjectName(String projectName) { this.projectName = projectName; } public void setClient(Person client) { this.client = client; } public void setVendor(Company vendor) { this.vendor = vendor; } public void setDeviceCost(double deviceCost) { this.deviceCost = deviceCost; } public void setMaterialCost(double materialCost) { this.materialCost = materialCost; } public void setInstallCost(double installCost) { this.installCost = installCost; } public void setDebugCost(double debugCost) { this.debugCost = debugCost; } public void setOtherCost(double otherCost) { this.otherCost = otherCost; } public void setDeviceDiscount(double deviceDiscount) { if (deviceDiscount < Config.MIN_DISCOUNT_RATE || deviceDiscount > Config.MAX_DISCOUNT_RATE) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return; } this.deviceDiscount = deviceDiscount; } public void setMaterialDiscount(double materialDiscount) { if (materialDiscount < Config.MIN_DISCOUNT_RATE || materialDiscount > Config.MAX_DISCOUNT_RATE) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return; } this.materialDiscount = materialDiscount; } public void setInstallDiscount(double installDiscount) { if (installDiscount < Config.MIN_DISCOUNT_RATE || installDiscount > Config.MAX_DISCOUNT_RATE) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return; } this.installDiscount = installDiscount; } public void setDebugDiscount(double debugDiscount) { if (debugDiscount < Config.MIN_DISCOUNT_RATE || debugDiscount > Config.MAX_DISCOUNT_RATE) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return; } this.debugDiscount = debugDiscount; } public void setOtherDiscount(double otherDiscount) { if (otherDiscount < Config.MIN_DISCOUNT_RATE || otherDiscount > Config.MAX_DISCOUNT_RATE) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return; } this.otherDiscount = otherDiscount; } public void setTotalDiscount(double totalDiscount) { if (totalDiscount < Config.MIN_DISCOUNT_RATE || totalDiscount > Config.MAX_DISCOUNT_RATE) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return; } this.totalDiscount = totalDiscount; } public String getQuotationNo() { return this.quotationNo; } public String getQuotationDate() { LocalDateTime dateTime = LocalDateTime.parse(this.quotationDate, Config.DATE_TIME_INPUT_FORMATTER); return dateTime.format(Config.DATE_TIME_DISPLAY_FORMATTER); } public String getProjectName() { return this.projectName; } public Person getClient() { return this.client; } public Company getVendor() { return this.vendor; } public double getDeviceCost() { return this.deviceCost; } public double getMaterialCost() { return this.materialCost; } public double getInstallCost() { return this.installCost; } public double getDebugCost() { return this.debugCost; } public double getOtherCost() { return this.otherCost; } public double getDeviceDiscount() { return this.deviceDiscount; } public double getMaterialDiscount() { return this.materialDiscount; } public double getInstallDiscount() { return this.installDiscount; } public double getDebugDiscount() { return this.debugDiscount; } public double getOtherDiscount() { return this.otherDiscount; } public double getTotalDiscount() { return this.totalDiscount; } /** * 计算原价的总金额 * @return 原价的总金额 */ public double calcOriginalTotalAmount() { return (deviceCost + materialCost + installCost + debugCost + otherCost); } /** * 计算优惠后的总金额 (总金额 = 设备费用 * 折扣 + 材料费用 * 折扣 + 安装费用 * 折扣 + 调试费用 * 折扣 + 其他费用 * 折扣) * 折扣 * * @return 折扣后的总金额 */ public double calcDiscountedTotalAmount() { double dc = deviceCost * deviceDiscount; double mc = materialCost * materialDiscount; double ic = installCost * installDiscount; double bc = debugCost * debugDiscount; double oc = otherCost * otherDiscount; return (dc + mc + ic + bc + oc) * totalDiscount; } /** * 计算优惠的金额(优惠的金额 = 原始的总金额 - 优惠后的总金额) * * @return 优惠的金额 */ public double caclDiscountAmount() { return calcOriginalTotalAmount() - calcDiscountedTotalAmount(); } // TODO:测试,要删除 /** * 试算:不修改字段,只返回给定折扣率的计算结果 * @param discountRate 试算折扣率 * @return 试算金额 */ public double getDiscountedTotal(double discountRate) { if (discountRate < 0.0 || discountRate > 1.0) { System.out.println(Config.MSG_WARN_PREFIX + Config.MSG_DISCOUNT_RATE_INVALID); return calcOriginalTotalAmount(); } return calcOriginalTotalAmount() * discountRate; } public String getClientDisplay() { if (client instanceof Customer) { Customer cu = (Customer) client; return cu.getName() + Config.TAG_CUSTOMER; } else if (client instanceof Company) { Company co = (Company) client; return co.getCompanyName() + Config.TAG_COMPANY; } return ""; } public String getClientFullInfo() { if (client instanceof Customer) { Customer cu = (Customer) client; return Config.TAG_CUSTOMER + "电话:" + cu.getPhone() + ",地址:" + cu.getHouseAddress() + ",房屋面积:" + cu.getHouseArea() + "m²"; } else if (client instanceof Company) { Company co = (Company) client; return Config.TAG_COMPANY + "联系人:" + co.getName() + ",电话:" + co.getPhone() + ",地址:" + co.getAddress(); } return ""; } /** * 折扣率转中文描述 * 1.0 → 原价, 0.85 → 85折, 0.8 → 8折, 0.0 → 免费 * @return 中文描述 */ public String getDiscountDesc() { if (totalDiscount == Config.MAX_DISCOUNT_RATE) return "原价"; if (totalDiscount == Config.MIN_DISCOUNT_RATE) return "免费"; long percent = Math.round(totalDiscount * 100); // 0.85→85, 0.8→80 if (percent % 10 == 0) { return (percent / 10) + "折"; // 80→8折, 50→5折 } else { return percent + "折"; // 85→85折, 88→88折 } } // 报价单摘要展示 public String getSummaryLine() { return String.format("%s | %s | %s | 原始金额:%s 元 | 折扣:%.0f%% | 折后金额:%s 元", quotationNo, projectName, getClientDisplay(), String.format(Config.AMOUNT_FORMAT, calcOriginalTotalAmount()), totalDiscount * 100, String.format(Config.AMOUNT_FORMAT, calcDiscountedTotalAmount()) ); } @Override public String toString() { double totalAmount = calcDiscountedTotalAmount(); // 调用calcTotalAmount(),计算报价单总金额 StringBuilder sb = new StringBuilder(); // 静态拼接报价单的头 sb.append(Config.LINE_CHAR.repeat(Config.LINE_TITLE_REPEAT_COUNT)).append(Config.QUOTATION_TITLE).append(Config.LINE_CHAR.repeat(Config.LINE_TITLE_REPEAT_COUNT)).append("\n"); sb.append(String.format(Config.LABEL_QUOTATION_NO + "%s%n", getQuotationNo())); sb.append(String.format(Config.LABEL_QUOTATION_DATE + "%s%n", getQuotationDate())); sb.append(String.format(Config.LABEL_VENDOR + "%s%n", vendor.getCompanyName())); sb.append(String.format(Config.LABEL_PROJECT_NAME + "%s%n", getProjectName())); sb.append(String.format(Config.LABEL_CLIENT_INFO + "%s%n", getClientDisplay())); sb.append(Config.LINE_CHAR.repeat(Config.LINE_REPEAT_COUNT * 2)).append("\n"); // 动态拼接报价单金额(按照总金额格式化后的长度右对齐) String totalStr = String.format(Config.AMOUNT_FORMAT, totalAmount); int width = totalStr.length(); // 折后金额 sb.append(String.format(Config.LABEL_DISCOUNTED_AMOUNT + "%," + width + ".2f" + " 元%n", calcDiscountedTotalAmount())); // 优惠金额 sb.append(String.format(Config.LABEL_DISCOUNT_AMOUNT + "%," + width + ".2f" + " 元%n", caclDiscountAmount())); // 原始金额 sb.append(String.format(Config.LABEL_TOTAL_AMOUNT + "%," + width + ".2f" + " 元(" + Config.LABEL_DISCOUNT_RATE + "%.0f %% )%n", calcOriginalTotalAmount() * totalDiscount, totalDiscount * 100)); sb.append(Config.LINE_CHAR.repeat(Config.LINE_REPEAT_COUNT * 2)).append("\n"); sb.append(Config.LABEL_DETAIL_PREFIX + "\n"); sb.append(String.format(Config.LABEL_DEVICE_COST + "%," + width + ".2f" + " 元(" + Config.LABEL_DISCOUNT_RATE + "%.0f %% )%n", deviceCost * deviceDiscount, deviceDiscount * 100)); sb.append(String.format(Config.LABEL_MATERIAL_COST + "%," + width + ".2f" + " 元(" + Config.LABEL_DISCOUNT_RATE + "%.0f %%) %n", materialCost * materialDiscount, materialDiscount * 100)); sb.append(String.format(Config.LABEL_INSTALL_COST + "%," + width + ".2f" + " 元(" + Config.LABEL_DISCOUNT_RATE + "%.0f %% )%n", installCost * installDiscount, installDiscount * 100)); sb.append(String.format(Config.LABEL_DEBUG_COST + "%," + width + ".2f" + " 元(" + Config.LABEL_DISCOUNT_RATE + "%.0f %% )%n", debugCost * debugDiscount, debugDiscount * 100)); sb.append(String.format(Config.LABEL_OTHER_COST + "%," + width + ".2f" + " 元(" + Config.LABEL_DISCOUNT_RATE + "%.0f %% )%n", otherCost * otherDiscount, otherDiscount * 100)); sb.append(Config.LINE_CHAR.repeat(Config.LINE_REPEAT_COUNT * 2)).append("\n"); return sb.toString(); } }

Person抽象父类 抽象方法introduce ()和showRole ()

▼
text
复制代码
package cn.com.d99714.smart.entity; import cn.com.d99714.smart.common.Config; public abstract class Person { private String name = ""; private String phone = ""; public Person() { } public Person(String name, String phone) { setName(name); setPhone(phone); } public void setName (String name){ this.name = name; } public void setPhone (String phone){ if (phone != null && phone.matches(Config.PHONE_REGEX)) { this.phone = phone; } else { System.out.println(Config.ERROR_PHONE_FORMAT); this.phone = ""; } } public String getName () { return this.name; } public String getPhone () { return this.phone; } public abstract String introduce (); public abstract String showRole (); }

Company子类,继承Person父类,重写抽象方法introduce ()和showRole ()

▼
text
复制代码
package cn.com.d99714.smart.entity; public class Company extends Person { private String companyName = ""; private String address = ""; private String serviceScope = ""; public Company() { } public Company(String name, String phone, String companyName, String address, String serviceScope) { super(name, phone); setCompanyName(companyName); setAddress(address); setServiceScope(serviceScope); } public void setCompanyName(String companyName) { this.companyName = companyName; } public void setAddress(String address) { this.address = address; } public void setServiceScope(String serviceScope) { this.serviceScope = serviceScope; } public String getCompanyName() { return this.companyName; } public String getAddress() { return this.address; } public String getServiceScope() { return this.serviceScope; } @Override public String toString() { return "【公司】联系人:" + this.getName() + ",电话:" + this.getPhone() + ",品牌:" + this.getCompanyName() + ",地址:" + this.getAddress() + ",服务范围:" + this.getServiceScope(); } @Override public String introduce() { StringBuilder sb = new StringBuilder(); sb.append("您好,我们是").append(this.getCompanyName()).append("的").append(this.getName()).append(",联系电话:").append(this.getPhone()).append(",服务范围:").append(this.getServiceScope()); return sb.toString(); } @Override public String showRole(){ return "【公司客户】"; } }

Customer子类,继承Person父类,重写抽象方法introduce ()和showRole ()

▼
text
复制代码
package cn.com.d99714.smart.entity; import cn.com.d99714.smart.common.Config; public class Customer extends Person { private String houseAddress = ""; private double houseArea = 0.0; public Customer() { } public Customer(String name, String phone, String houseAddress, double houseArea) { super(name, phone); setHouseAddress(houseAddress); setHouseArea(houseArea); } public void setHouseAddress(String houseAddress) { this.houseAddress = houseAddress; } public void setHouseArea(double houseArea) { if (houseArea > Config.MIN_HOUSE_AREA && houseArea < Config.MAX_HOUSE_AREA) { this.houseArea = houseArea; } else { System.out.println(Config.ERROR_HOUSE_AREA); this.houseArea = 0.0; } } public String getHouseAddress() { return this.houseAddress; } public double getHouseArea() { return this.houseArea; } @Override public String toString() { return "【业主】:" + this.getName() + "," + this.getPhone() + "," + this.getHouseAddress() + "," + this.getHouseArea() + "m²"; } @Override public String introduce() { StringBuilder sb = new StringBuilder(); sb.append("我是业主").append(this.getName()).append(",房屋面积").append(this.getHouseArea()).append("m²,位于").append(this.getHouseAddress()).append(",需要智能家居报价。"); return sb.toString(); } @Override public String showRole() { return "【业主】"; } }

Worker子类,继承Person父类,重写抽象方法introduce ()和showRole ()

▼
text
复制代码
package cn.com.d99714.smart.entity; import cn.com.d99714.smart.common.Config; public class Worker extends Person { private String jobType = ""; private int workYear = 0; private double score = 0.0; public Worker() { } public Worker(String name, String phone, String jobType, int workYear, double score) { super(name, phone); setJobType(jobType); setWorkYear(workYear); setScore(score); } public void setJobType(String jobType) { this.jobType = jobType; } public void setWorkYear(int workYear) { if (workYear >= Config.MIN_WORK_YEAR && workYear <= Config.MAX_WORK_YEAR) { this.workYear = workYear; } else { System.out.println(Config.ERROR_WORK_YEAR); this.workYear = 0; } } public void setScore(double score) { if (score >= Config.MIN_SCORE && score <= Config.MAX_SCORE) { this.score = score; } else { System.out.println(Config.ERROR_SCORE); this.score = 0.0; } } public String getJobType() { return this.jobType; } public int getWorkYear() { return this.workYear; } public double getScore() { return this.score; } @Override public String toString() { return "【师傅】:" + this.getName() + "," + this.getPhone() + "," + this.getJobType() + "," + this.getWorkYear() + "," + this.getScore(); } @Override public String introduce() { StringBuilder sb = new StringBuilder(); sb.append("我是").append(this.getName()).append(",从事").append(this.getJobType()).append(" ").append(this.getWorkYear()).append("年,评分").append(this.getScore()); return sb.toString(); } @Override public String showRole(){ return "【师傅】"; } }
0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP