我有一个带有嵌套私有类的类。我有一个Builder
标准Java构建器模式,它构造了这个类的实例。我不希望班上的任何人能够看到我隐藏的课程。
在Java中,我可以这样做:
public class Example {
private SneakyType doNotExposeThis;
private Example(Builder builder) {
// OK 'cause in Java you can access the private
// members of a nested class
doNotExposeThis = builder.doNotExposeThis;
}
private static class SneakyType {
SneakyType(String x) {
// stuff
}
}
public static class Builder {
private SneakyType doNotExposeThis;
public void addFoo(String something) {
doNotExposeThis = new SneakyType(something);
}
public Example build() { return new Example(this); }
}
}
但是我无法弄清楚如何在Kotlin中做同样的事情:
class Example(builder: Builder) {
private lateinit var doNotExposeThis: SneakyType
init {
doNotExposeThis = builder.doNotExposeThis
}
class Builder {
// If private or internal I can't access it in Example.init
// and if public it gets exposed.
val doNotExposeThis: SneakyType
fun addFoo(something: String) {
// actual construction is quite a bit more complex
doNotExposeThis = SneakyType(something)
}
}
}
请注意,为了Java互操作,我想保留我的构建器。我也想要它,因为我的对象构造起来很复杂,我希望它是不可变的,所以我有一个包含很多setter,adders,vals等的构建器,然后在init
中我构造了一个不可变的{{1 }}
我看到的唯一选择是:
Example
,而是保存构造一个所需的所有信息,然后在SneakyType
中构建它。工作但增加了很多复杂性。Example
不可变,并允许构建者调用它来设置Example
Sneaky
有没有办法模仿Java版本?
答案 0 :(得分:2)
我看到两个可行的选择:
使用class Example private constructor(builder: Builder) {
private val doNotExposeThis: SneakyType
init {
doNotExposeThis = builder.doNotExposeThis
}
internal class SneakyType(x: String)
class Builder {
internal lateinit var doNotExposeThis: SneakyType
fun addFoo(something: String) {
doNotExposeThis = SneakyType(something)
}
fun build(): Example {
return Example(this)
}
}
}
visibility modifier:
SneakyType
这将使Example
仅在您的Kotlin编译模块中可见。
让class Example private constructor(private val doNotExposeThis: SneakyType) {
private class SneakyType(x: String)
class Builder {
private lateinit var doNotExposeThis: SneakyType
fun addFoo(something: String) {
doNotExposeThis = SneakyType(something)
}
fun build(): Example {
return Example(doNotExposeThis)
}
}
}
独立于其构建器(这是我推荐的):
<my-tag color="green"></my-tag>
<my-tag color="red"></my-tag>
<my-tag>
<h1 class="{opts.color}">{ message }</h1>
<script>
this.message = 'hello there'
</script>
<style>
.red {
color: red;
}
.green {
color: green;
}
</style>
</my-tag>