子類 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/zh-hk/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

發表回復

登錄後才能評論