Читая ваш сценарий использования, вы, вероятно, ищете внутренний класс тогда.Вот решение, полученное из вашей первой попытки с использованием внутреннего класса Bar
:
class Foo {
private var data = 0 // private as you do not want to make it publicly available
fun add(x: Int) {
data += x
}
inner class Bar {
private var data = 2 * this@Foo.data // access the outer foo directly... no need to hold it in the constructor
fun show() = println(data + 10)
}
}
fun main() {
val myFoo = Foo()
myFoo.add(3)
myFoo.add(4)
// val myBar = Foo.Bar() // this does not compile... you need a foo to build a bar...
val myBar = myFoo.Bar() // this works...
myBar.show()
// myBar.data // this wouldn't compile as it's not accessible
}
Как вы сказали, вы предпочитаете класс верхнего уровня.В зависимости от того, насколько вы хотите, чтобы Foo.data
был защищен, вас также могут заинтересовать следующие настройки:
class Foo {
private var data = 0
fun add(x: Int) {
data += x
}
fun Bar.getFooData() = data
}
class Bar(foo: Foo) {
private var data = 2 * with(foo) { getFooData() }
fun show() = println(data + 10)
}
Таким образом, вы можете получить доступ к данным Foo, только если у вас есть оба, a Bar
и a Foo
доступно, последний как приемник.Это, однако, также означает, что вы можете получить доступ к Foo.data
извне, если вам доступны оба объекта, например, следующее будет также в main
:
with (myFoo) {
myBar.getFooData()
}
То есть: data
недоступенснаружи (игнорируя размышления) вложенный или внутренний класс - ваш друг.Сложнее получить к нему доступ (или: заставить некоторые условия быть верными перед его использованием), подход с использованием функции расширения с соответствующим получателем может быть вашим другом.