【问题标题】:Does Kotlin break the rule of encapsulation?Kotlin 是否打破了封装规则?
【发布时间】:2018-07-05 13:32:30
【问题描述】:

变量在使用默认可见性修饰符的类中使用public。为每个成员变量创建了一个 setter 和一个 getter,但在 Kotlin 中你可以这样做:

class Person {
    var name: String = "unknown"
}

fun main(args: Array<String>) {
    val person = Person()
    person.name = "kevvex"
    println("${person.name}")
}

由于使用时应用了getter和setter,这是否仍然没有违反封装规则:

person.name = "kevvex"

如果是这样,那怎么可能是封装?该变量仍然是公开的。由于私有可见性修饰符,将其声明为私有将迫使我创建一个 setter 和 getter 来获取变量。

我比较的是 Java,它通常将成员变量设为私有,而每个成员变量都有一个公共的 setter 和 getter

【问题讨论】:

  • 您可以根据需要更改 getter 和 setter 的行为。它们仍然是保护变量的方法。它们只是以更方便的方式调用。
  • 暴露一个类的内部字段,不管它是如何实现的 - 是否使用 getter - 总是会破坏封装

标签: java kotlin encapsulation


【解决方案1】:

我正在与 Java 进行比较,Java 通常将成员变量设为私有,而每个成员变量都有一个公共的 setter 和 getter。

这实际上是这个 Kotlin 代码中发生的事情。 name 不是一个字段(你称之为成员变量),它是一个带有私有支持字段的属性。如果你修改它的 getter 和 setter:

var name: String
    get() = ...
    set(value: String) { ... }

调用者继续使用

person.name = "kevvex"

并且不需要重新编译。

var name: String = "unknown" 完全等同于 Java 的

private String _name = "unknown";
public String getName() { return _name; }
public void setName(String name) { this._name = name; }

甚至会像这样从 Java 中看到。所以它打破了与 Java 相同程度的封装。

【讨论】:

  • 我更改变量值的方式是否正确?所以我应该怎么做?
  • 是的,person.name = ... 是 Kotlin 调用 setter 方法的方式。
【解决方案2】:

您可以创建公共变量,但只能使用私有设置器

var name: String = "unknown"
private set

此外,您还可以编辑 get 或 set 的行为方式,就像在 Java 中一样。封装没有问题,Kotlin 通过将“默认 setter / getter”创建为公共的,让“POJO”的创建变得更加容易

【讨论】:

    猜你喜欢
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    相关资源
    最近更新 更多