子类 builder() 没有父类的属性

本文将从以下几个方面对子类 builder() 缺少父类属性进行详细阐述:

一、Subclassing with the Builder Pattern

在实现 builder 模式时,我们通常使用一个基础的 builder 类来构建对象。然而,有时候我们需要在继承中使用 builder 模式,此时存在一个问题:子类的 builder 没有继承父类的属性。

例如,假设我们有一个基础的汽车类 Car,它有三个属性:make、model、year。我们想要实现一个 Tesla 类,它是 Car 的子类,然而它有一个额外的属性:battery。


class Car {
    private final String make;
    private final String model;
    private final int year;

    // Constructor
    private Car(Builder builder) {
        this.make = builder.make;
        this.model = builder.model;
        this.year = builder.year;
    }

    // Builder class
    public static class Builder {
        private final String make;
        private final String model;
        private final int year;

        public Builder(String make, String model, int year) {
            this.make = make;
            this.model = model;
            this.year = year;
        }

        public Car build() {
            return new Car(this);
        }
    }
}

class Tesla extends Car {
    private final int battery;

    private Tesla(TeslaBuilder builder) {
        super(builder);
        this.battery = builder.battery;
    }

    public static class TeslaBuilder extends Builder {
        private int battery;

        public TeslaBuilder(String make, String model, int year) {
            super(make, model, year);
        }

        public TeslaBuilder battery(int battery) {
            this.battery = battery;
            return this;
        }

        public Tesla build() {
            return new Tesla(this);
        }
    }
}

可以看到,在子类 Tesla 中,我们需要创建一个 TeslaBuilder 去构建 Tesla 对象。然而,在子类中,TeslaBuilder 并没有继承 Car.Builder 的属性。

二、解决方法

1. 使用父类的静态工厂方法

父类可以提供一个静态的工厂方法,用于从子类的 builder 中构建父类实例。这种方法可以将父类的属性添加到子类 builder 中,并在子类的 build() 方法中调用父类的 build() 方法。


class TeslaBuilder extends Builder {
    private int battery;

    public static TeslaBuilder newBuilder() {
        return new TeslaBuilder();
    }

    private TeslaBuilder() {
        super("Tesla", "Model S", 2019);
    }

    public TeslaBuilder battery(int battery) {
        this.battery = battery;
        return this;
    }

    @Override
    public Car build() {
        return new Tesla(this);
    }
}

class Tesla extends Car {
    private final int battery;

    private Tesla(TeslaBuilder builder) {
        super(builder);
        this.battery = builder.battery;
    }

    // Static factory method
    public static TeslaBuilder newBuilder() {
        return TeslaBuilder.newBuilder();
    }
}

在上面的代码中,TeslaBuilder 继承自 Car.Builder。我们使用父类 Car 的静态工厂方法来创建一个名为 “Tesla” 的实例,同时,我们也可以在子类 TeslaBuilder 中添加子类的属性 “battery”。

此外,在 TeslaBuilder 的 build() 方法中,我们调用了父类 Car 的 build() 方法来创建 Tesla 对象。

2. 通过抽象方法继承

另一种解决方法是,使用抽象方法来实现属性的继承。


abstract class Car {
    protected final String make;
    protected final String model;
    protected final int year;

    protected Car(CarBuilder builder) {
        this.make = builder.make;
        this.model = builder.model;
        this.year = builder.year;
    }

    public static abstract class CarBuilder<e b="" car,="" carbuilder> {
        protected String make;
        protected String model;
        protected int year;

        public B make(String make) {
            this.make = make;
            return self();
        }

        public B model(String model) {
            this.model = model;
            return self();
        }

        public B year(int year) {
            this.year = year;
            return self();
        }

        public abstract E build();

        protected abstract B self();
    }
}

class Tesla extends Car {
    private final int battery;

    private Tesla(TeslaBuilder builder) {
        super(builder);
        this.battery = builder.battery;
    }

    public static class TeslaBuilder extends CarBuilder {
        private int battery;

        public TeslaBuilder battery(int battery) {
            this.battery = battery;
            return self();
        }

        @Override
        public Tesla build() {
            return new Tesla(this);
        }

        @Override
        protected TeslaBuilder self() {
            return this;
        }
    }
}

在上面的代码中,我们使用了一个抽象方法 self() 来返回 builder 对象。通过让子类的 builder 实现该方法,我们可以保证属性的继承问题。在 TeslaBuilder 的 build() 方法中,我们返回了 Tesla 对象。

三、小结

子类 builder() 缺少父类属性是 builder 模式中的一种常见问题。本文介绍了两种方法来解决这个问题:静态工厂方法和抽象方法继承。在实现 builder 模式时,选择哪种方法需要根据实际情况来决定。

原创文章,作者:NNSGS,如若转载,请注明出处:https://www.506064.com/n/373931.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
NNSGS的头像NNSGS
上一篇 2025-04-27 15:26
下一篇 2025-04-27 15:26

相关推荐

  • 全面解读数据属性r/w

    数据属性r/w是指数据属性的可读/可写性,它在程序设计中扮演着非常重要的角色。下面我们从多个方面对数据属性r/w进行详细的阐述。 一、r/w的概念 数据属性r/w即指数据属性的可读…

    编程 2025-04-29
  • Vant ContactList 增加属性的实现方法

    在使用前端UI框架Vant中的ContactList组件时,我们有时需要为此组件增加一些个性化的属性,来满足我们特定的需求。那么,如何实现ContactList组件的增加属性功能呢…

    编程 2025-04-29
  • 使用PHP foreach遍历有相同属性的值

    本篇文章将介绍如何使用PHP foreach遍历具有相同属性的值,并给出相应的代码示例。 一、基础概念 在讲解如何使用PHP foreach遍历有相同属性的值之前,我们需要先了解几…

    编程 2025-04-28
  • PowerDesigner批量修改属性

    本文将教您如何使用PowerDesigner批量修改实体、关系等对象属性。 一、选择要修改的对象 首先需要打开PowerDesigner,并选择要修改属性的对象。可以通过以下两种方…

    编程 2025-04-27
  • Python中的delattr:一个多功能的属性删除方法

    在Python编程中,delattr()是一个十分强大常用的函数,可以方便的删除一个对象的属性,并且使用起来非常灵活。接下来将从多个方面详细阐述Python中的delattr()方…

    编程 2025-04-27
  • JavaScript中修改style属性的方法和技巧

    一、基本概念和方法 style属性是JavaScript中一个非常重要的属性,它可以用来控制HTML元素的样式,包括颜色、大小、字体等等。这里介绍一些常用的方法: 1、通过Java…

    编程 2025-04-25
  • HTMLButton属性及其详细阐述

    一、button属性介绍 button属性是HTML5新增的属性,表示指定文本框拥有可供点击的按钮。该属性包括以下几个取值: 按钮文本 提交 重置 其中,type属性表示按钮类型,…

    编程 2025-04-25
  • display属性的多方位应用

    一、display属性概述 display属性是CSS中常用的一个属性,它定义了一个元素的盒模型类型,以及其在页面上的布局形式。在HTML文档中,每个HTML标签都有一个默认的di…

    编程 2025-04-23
  • 微信小程序image属性详解

    微信小程序开发以其轻量、高效、便利为特点,深受开发者喜爱。image属性作为基础组件之一,在开发过程中也扮演着重要的角色。本文将从微信小程序image显示不出来、微信小程序imag…

    编程 2025-04-23
  • 深入学习input 属性

    一、基础属性 input元素是用于不同目的的HTML标记。可以用于创建文本框、邮件地址、密码、电话号码、日期和时间等输入框。基础属性指input元素最常用的属性,例如type、na…

    编程 2025-04-23

发表回复

登录后才能评论