Kotlin嵌套成员的可见性

时间:2016-12-24 04:02:31

标签: kotlin

我有一个带有嵌套私有类的类。我有一个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 }}

我看到的唯一选择是:

  1. 不是在我的构建器中有Example,而是保存构造一个所需的所有信息,然后在SneakyType中构建它。工作但增加了很多复杂性。
  2. 放弃Example不可变,并允许构建者调用它来设置Example
  3. 公开Sneaky
  4. 有没有办法模仿Java版本?

1 个答案:

答案 0 :(得分:2)

我看到两个可行的选择:

  1. 使用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编译模块中可见。

  2. 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>