【问题标题】:Not using set and get methods in Java when there are many attributes当有很多属性时,不使用 Java 中的 set 和 get 方法
【发布时间】:2017-10-28 10:22:53
【问题描述】:

所以我一直在学习 OOP。我目前正在尝试创建简单的“英雄配置文件”,包括生命值、法力、智力、力量、敏捷、护甲等。如您所见,我想为英雄对象添加很多属性。但是这些属性是在私有而不是公共中声明的(因为有人告诉我最好将这些声明为私有),当我在私有中声明它们时,我必须为每个属性设置 set 和 get 方法。而且很费时间,感觉不太实用。

有没有更实用的方法?即使有十几个,编码人员真的会键入这些 get 和 set 方法吗?我要做的就是创建两个具有这些属性的英雄资料,然后模拟两者之间的 1v1 战斗。

【问题讨论】:

  • Eclipse > 右键 > Source > Generate getter and setter > Check all > Done
  • 哦,我使用的是 IntelliJ。是否也有这样的功能? @马文

标签: java oop object methods


【解决方案1】:

谁告诉你,对象的各个属性应该是私有的,这绝对是正确

OOP 的基本原则之一是Encapsulation。简单地说,这意味着应该隐藏对象的内部结构(“字段”)。这是OOP最重要的一个方面,OOP的大部分优势都来自于此。

现在,访问器方法(setter 和getter)违反封装,就像将它们公开一样,因为您不再隐藏内部结构。这不仅仅是保护内部字段,而是隐藏它们。

不幸的是,访问器方法在 Java(和 C# 中也是如此)中很常见,但如果您认真学习 OOP,则应该不惜一切代价避免使用它们!以后,当你有更多的经验时,你可能会在少数情况下例外,但我建议你暂时避免它们。避免使用 Project Lombok 并避免使用 IDE 功能自动生成内容。

Here 是 Allen Holub 关于该主题的精彩文章。

回到您的实际问题:是的,您将字段声明为私有,但您根本没有为它们定义 setter/getter。相反,我们要做的是考虑对象应该具有哪些职责/特性/功能/逻辑。

因此,与其考虑统计数据,不如想想您将这些统计数据用于什么。一个面向对象的 Hero 可能看起来像这样:

public final class Hero {
    private int hp;
    private int strength;
    private int agility;
    private int armor;
    ...

    public void dealDamageTo(Hero other) {
        other.takeDamage(stength);
    }

    public void takeDamage(int damage) {
        hp = hp - Math.max(0, damage-armor);
    }
    ...
}

当然,这只是一个示例,但您可能明白这一点。如果您的设计正确,则根本不需要发布内部字段。

【讨论】:

  • 我明白了。很有见地。非常感谢!
【解决方案2】:

在你的属性周围有 getter 和 setter 真的很重要。否则,你会破坏封装。

不幸的是,Java 没有为程序员提供合适的快捷方式来声明 getter 和 setter。但是,许多 IDE 确实为您提供了生成访问器方法的工具。

【讨论】:

【解决方案3】:

是的,您应该编写或生成 getter 和 setter,这要归功于您的 IDE 来封装您的字段,除了一个好的做法之外,您在更改代码时不必更改代码中的 get() 和 set() 调用变量的名称或类型(例如从 Collection 到 List),在 java8 中更适合使用 lambda 方法调用

另外,你的类正在管理它的属性,没有人可以以一种不方便的方式改变它们的状态

【讨论】:

  • “是的,你应该写 getter 和 setter”,你的意思是实际手写它们还是让编辑器为我们生成它们?
  • 我的意思是让编辑自己写,需要的时候改,当然生成会更快
  • 那么请使用edit 选项并澄清它,因为基于“而且它消耗这么多时间”,它看起来像是 OP 的主要关注点之一。
【解决方案4】:

如果您讨厌创建 getter 和 setter,或者您认为它们会造成混乱/不必要,您可以使用 Lombok。使用外部框架可能不是初学者,但很有趣。

https://projectlombok.org/

检查一下:

https://projectlombok.org/features/GetterSetter.html

https://projectlombok.org/features/Data.html

【讨论】:

    【解决方案5】:

    @huzo,欢迎使用 OOP,感谢您尝试 Java。回答您的问题,对于 IntelliJ,请使用 https://www.jetbrains.com/help/idea/2017.1/generating-getters-and-setters.html,一旦熟悉,请按照 @Rjiuk 的建议尝试 https://projectlombok.org/,以避免使用 setter 和 getter。

    【讨论】:

      【解决方案6】:

      我目前正在尝试使用 HP、Mana、 智力、力量、敏捷、护甲等。如你所见,有 我想为 Hero 对象添加很多属性。

      看着这些行,我可以说,这里有继承树。您可以为这些获取父类并在其中保留公共成员(变量和方法)。父类可以是interfaceabstract class 或具体类。那么你就可以通过构造函数来传递成员变量的值了。

      实际上,假设您有strength 类,并且您有名为armStrength 的成员变量(例如)。当您创建此类的新实例时,您可以通过构造函数传递值。但后来手臂变得虚弱/折断。在这种情况下,您需要更新armStrength

      要实现这一点,您还需要一个 setter 方法。在 OOP 中拥有 getter 和 setter 是一件更好的事情。因为封装是OOP中的重点之一。

      为了避免在拥有大量 getter 和 setter 时出现混淆,您可以将它们放在单独的类中。

      幸运的是,您可以使用 IDE 快捷方式为您生成它们,而不是输入所有的 getter 和 setter。

      • 在 Eclipse 中:Alt+Shift+S, R
      • 在 Netbeans 中:Alt+Insert
      • 在 IntelliJ 中:ALT+Insert

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-27
        • 1970-01-01
        • 1970-01-01
        • 2015-08-19
        • 1970-01-01
        相关资源
        最近更新 更多