3。 @ superbuilder*和繼承
4。結論
lombok庫提供了一種無需編寫任何樣板**即可實現* builder pattern的好方法: [@builder](https:// projectlombok.org/features/builder)*注釋。
在這個簡短的教程中,我們將專門學習涉及繼承時如何處理@ builder注釋。我們將演示兩種技術。一種依賴於標準的lombok功能。另乙個則利用了lombok 1.18中引入的實驗功能。
有關builder注釋的更廣泛概述,請參考使用lombok的@ builder注釋。
project lombok簡介中也提供了有關project lombok庫的詳細資訊。
假設我們的child類擴充套件了parent類:
@getter
@allargsconstructor
public
class
parent
@getter
@builder
public
class
child
extends
parent
在擴充套件了此類的另乙個類上使用@ builder時,我們將在注釋上收到以下編譯錯誤:
隱式超級建構函式parent()未定義。必須顯式呼叫另乙個建構函式
這是由於lombok不考慮超類的字段,而僅考慮了當前類的字段。
對我們來說幸運的是,有乙個簡單的解決方法。我們可以(使用我們的ide甚至手動生成)基於欄位的建構函式。這也包括超類的字段。我們用@ builder而不是類來注釋它:
@getter
@allargsconstructor
public
class
parent
@getter
public
class
child
extends
parent
}
這樣,我們將能夠從child類訪問便捷的構建器,這將使我們也可以指定parent類的字段:
child child = child.
builder()
.parentname
("andrea").
parentage(38
).childname
("emma").
childage(6
).build()
;assertthat
(child.
getparentname()
).isequalto
("andrea");
assertthat
(child.
getparentage()
).isequalto(38
);assertthat
(child.
getchildname()
).isequalto
("emma");
assertthat
(child.
getchildage()
).isequalto(6
);
如果超類本身使用@ builder進行注釋,則在注釋child類的建構函式時會出現以下錯誤:
返回型別與parent.builder()不相容
這是因為child類正試圖公開兩個具有相同名稱的builders。
我們可以通過為至少乙個構建器方法分配唯一的名稱來解決此問題:
@getter
public
class
child
extends
parent
}
然後,我們將能夠通過child.builder()獲得 parentbuilder,並通過child.childbuilder()獲得 childbuilder。
在某些情況下,我們可能需要支援更深的繼承層次結構。我們可以使用與以前相同的模式。讓我們建立child的子類。
@getter
public
class
student
extends
child
}
和以前一樣,我們需要手動新增乙個建構函式。這需要接受所有父類和子類的所有屬性作為引數。然後,像以前一樣新增@ builder批註。通過在注釋中提供另乙個唯一的方法名稱,我們可以獲得parent,child或student的構建器。
student student = student.
studentbuilder()
.parentname
("andrea").
parentage(38
).childname
("emma").
childage(6
).schoolname
("baeldung high school").
build()
;assertthat
(student.
getchildname()
).isequalto
("emma");
assertthat
(student.
getchildage()
).isequalto(6
);assertthat
(student.
getparentname()
).isequalto
("andrea");
assertthat
(student.
getparentage()
).isequalto(38
);assertthat
(student.
getschoolname()
).isequalto
("baeldung high school"
);
然後,我們可以擴充套件此模式以處理任何繼承深度。我們需要建立的建構函式可能會變得很大,但是您的ide可以幫助您。
如我們前面所述,lombok的1.18版引入了* @ superbuilder*批註。我們可以使用它來以更簡單的方式解決問題。
我們可以使建造者能夠看到其祖先的屬性。
為此,我們使用@ superbuilder批註對我們的類及其祖先進行批註。
讓我們在這裡演示我們的三層層次結構。請注意,簡單父級和子級繼承的原理是相同的:
@getter
@superbuilder
public
class
parent
{// same as before...
@getter
@superbuilder
public
class
child
extends
parent
{// same as before...
@getter
@superbuilder
public
class
student
extends
child
{// same as before...
當所有類都以這種方式注釋後,我們將為子類獲得乙個構建器,該構建器也公開了父級的屬性。
注意,我們必須注釋所有類。 @ superbuilder不能在同一類層次結構中與@ builder混合。這樣做會導致編譯錯誤。
這一次,我們不需要定義任何特殊的建構函式。由@ superbuilder生成的生成器類的行為就像我們使用主lombok @ builder生成的生成器類一樣:
student student = student.
builder()
.parentname
("andrea").
parentage(38
).childname
("emma").
childage(6
).schoolname
("baeldung high school").
build()
;assertthat
(student.
getchildname()
).isequalto
("emma");
assertthat
(student.
getchildage()
).isequalto(6
);assertthat
(student.
getparentname()
).isequalto
("andrea");
assertthat
(student.
getparentage()
).isequalto(38
);assertthat
(student.
getschoolname()
).isequalto
("baeldung high school"
);
我們已經看到了如何處理在利用繼承的類中使用@ builder注釋的常見陷阱。
如果使用主要的lombok @ builder批註,我們還有一些額外的步驟可以使它起作用。但是,如果我們願意使用實驗性功能,那麼@ superbuilder可以簡化事情。
和往常一樣,完整的源**可在[github上]獲得(
帶有泛型的類如何繼承
public class genericitytst 具有泛型的classa public class classa 繼承泛型 public class classb extends classa 縮小泛型的範圍,是准許的,但是不允許擴大泛型的範圍 public class classc exten...
帶有虛函式的菱形繼承和帶有虛函式的菱形虛繼承
對於某些函式來說,基類希望它的派生類定義適合自身的版本,此時基類就將這些函式宣告為虛函式。在存在虛函的類,建立物件時會產生虛表指標,虛表指標指向乙個虛表,這時就可以通過虛表訪問自己定義的函式。通過下面兩種繼承進行分析 帶有虛函式的菱形繼承 以下圖的模型為例進行分析 我們觀察c類物件在記憶體中的結構 ...
帶有風的詩詞 帶有風字的詩句
帶有風字的詩句 1 昨夜秋風入漢關,朔雲邊月滿西山。嚴武 軍城早秋 2 夜來風雨聲,花落知多少。孟浩然 春曉 3 相見時難別亦難,東風無力百花殘。李商隱 無題 4 古道西風瘦馬,夕陽西下,斷腸人在天涯。馬致遠 天淨沙 秋思 5 大風起兮雲飛揚。劉邦 大風歌 6 忽如一夜春風來,千樹萬樹梨花開。岑參 ...