【问题标题】:Should I call the getter method for methods in the same class?我应该为同一个类中的方法调用 getter 方法吗?
【发布时间】:2020-09-17 20:10:40
【问题描述】:

我开始学习面向对象编程,导师说“getter”和“setter”函数用于访问和更改另一个类中的某些私有变量。

我被告知要编写一个程序来创建一副纸牌,打印它,洗牌,最后打印洗好的牌。作业说我必须使用良好的面向对象原则。

我写了这段代码,它可以正常工作

import java.util.Random;

public class CardDeck {

static String[] suitArray = {"Clubs", "Diamonds", "Hearts", "Spades"};

static String[] faceValue = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10","Jack", "Queen", "King"};

static String[] deckOfCards = new String[52];

public static void createDeck()
{
    int i = 0;
    for ( int j = 0; j < 4; j++ )  
    {
        for ( int k = 0; k < 13; k++ )
        {   
            getDeckOfCards()[i++] = getSuitArray()[j] + getFaceValue()[k];
        }
    }
    
    for(i = 0; i < 52; i++)
    {
        System.out.println(deckOfCards[i]);
    }
}

public static String[] getSuitArray() {
    return suitArray;
}

public static void setSuitArray(String[] suitArray) {
    CardDeck.suitArray = suitArray;
}

public static String[] getFaceValue() {
    return faceValue;
}

public static void setFaceValue(String[] faceValue) {
    CardDeck.faceValue = faceValue;
}

public static String[] getDeckOfCards() {
    return deckOfCards;
}

public static void setDeckOfCards(String[] deckOfCards) {
    CardDeck.deckOfCards = deckOfCards;
}
}

我只包含了创建套牌的部分。

使用 getter 和 setter 方法有什么害处吗?如果没有,我会保留它们,以防我的教练希望看到我使用它们

【问题讨论】:

  • 一般来说不会,尽管可以使用具有逻辑的 getter,它过滤或转换它返回的值。您不需要需要删除设置器,如果您不需要它们做任何事情,您可以删除它们,但您的教师可能希望看到它们,或者您稍后可能需要它们。它们只是额外未使用的代码,没什么特别的。
  • 这能回答你的问题吗? Why use getters and setters/accessors?
  • 看起来围绕这个问题存在强烈的不同意见。我个人倾向于不将 getter 或 setter 用于最终变量,无论是公共的还是私有的,对于我倾向于始终使用它们的可变变量。不过,我不准备公开捍卫这些选择。
  • 我个人喜欢尽可能使用 getter/setter,以避免在需要调整返回的值时发生潜在的代码重构。这可以被认为是一种叫做 speculative generality 的代码味道(有点……它被使用但不一定有用),所以你的里程可能会因你发现这样做的有用程度而有所不同。
  • “作业说我必须使用良好的面向对象原则”——如果这是真的,那么代码中的所有static 关键字都需要删除。

标签: java oop object getter


【解决方案1】:

这段代码并不是真正面向对象的,因为它只是操纵一些静态变量。

如果我给出这样的任务,我希望你创建一个Card 类,并创建52 个左右的实例,并为其套件和等级设置适当的属性;也许排名会用一个数值和一个人性化的名称来表示。如果您了解 enum 类型,套件将表示为枚举值。

此外,Deck 类可以使用洗牌方法创建,也许还有一些静态工厂方法来构建不同类型的牌组。 (例如,新套牌会包括 Jokers 吗?A 高还是低?)

回到最初的问题,如果访问器可以被子类覆盖,那么您应该在类中使用它,而不是直接访问字段。在这种情况下,我认为不需要扩展 Card,所以您的类可能是 final。换句话说,“为继承设计和记录类,或者禁止它。”

【讨论】:

  • 如果 card 类没有任何功能,它就没有意义。
【解决方案2】:

面向对象编程的基本概念之一是封装;也就是说,对象的实现细节应该保持隐藏。它与抽象的概念重叠。如果您直接通过公共变量或间接通过访问器方法(getter/setter)提供对该对象内部工作的访问,那么您正在破坏封装。这被称为leaky abstraction.

回到您的示例:仅从需求来看,您只需要一种类型:一副纸牌,或者只是一个interface deck。它应该有两种方法:deck.print()deck.shuffle()。我希望interface deck 知道如何自己打印和洗牌。

【讨论】:

    【解决方案3】:

    我建议您为您的案例创建简单的实体,例如真实世界的示例,您可以实现 Card 类,例如,然后是 Game 或 Manager 类来组织 Card Deck 操作逻辑。

    【讨论】:

      猜你喜欢
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 2017-04-15
      相关资源
      最近更新 更多