公共领域有哪些替代方案?

Jam*_*mes 13 c++ java field class public

我正在使用java编写游戏,并且作为问题标题建议我在我的课程中使用公共字段.(暂且)

从我所看到的公共领域是坏的,我有一些理解为什么.(但如果有人可以澄清你为什么不使用它们,那将不胜感激)

事情是,从我所看到的,(并且似乎合乎逻辑)是使用私有字段,但使用getter和setter来访问它们也不好,因为它首先破坏了使用私有字段的观点.

所以,我的问题是,有哪些替代方案?或者我真的必须使用私人领域与吸气剂和制定者?

这里是我的一个类及其一些方法的参考.

如果需要,我会详细说明.

public double health;
//The player's fields.
public String name;
public double goldCount;
public double maxWeight;
public double currentWeight;
public double maxBackPckSlts;
public double usedBackPckSlts; // The current back pack slots in use
public double maxHealth; // Maximum amount of health
public ArrayList<String> backPack = new ArrayList<String>();

//This method happens when ever the player dynamically takes damage(i.e. when it is not scripted for the player to take damage.
//Parameters will be added to make it dynamic so the player can take any spread of damage.
public void beDamaged(double damage)
{
    this.health -= damage;
    if (this.health < 0)
    {
        this.health = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:为了检查目的,这是我的Weapon班级现在的样子:(代码示例由于某种原因不起作用,所以看起来不正确.)

private final double DAMAGE;
private final double SPEED;

public Weapon(double initialDmg,double initialSpd,String startName,double initialWg)
{
    DAMAGE = initialDmg;
    SPEED = initialSpd;
    setItemName(startName);
    setItemWeight(initialWg);
}

public double getSpeed() 
{
    return SPEED;
}


public double getDamage()
{
    return DAMAGE;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的那样,由于Weapon's DAMAGE并且SPEED不需要更改,它们暂时可以是最终的.(如果,在游戏的后期,我决定这些值可以"升级"可以这么说,我可以添加setter然后,通过验证,或者只是使用升级后的值制作新武器)它们在Weapon's构造函数中设置.

结论:吸气剂和固定剂都很好,只要它们被巧妙地使用,并且仅在需要时使用.(然而)

Pau*_*lin 21

使用getter和setter是很常见的,而不是让其他对象直接更改字段的权限.当你看到99.99%的getter和setter没有做任何事情时,这可能没有任何意义,除了你可以直接访问字段所做的事情.但是当你决定当一名球员受到超过一分的伤害时,会发生什么呢?或者你想限制魔法物品可以使用多少背包槽?您可能需要搜索代码中修改字段的所有位置,或者,如果您使用了getter和setter,则完全在类中进行更改.这是面向对象编程的核心 - 您已经封装了对象在对象内部所做的"知识",而不是在与该对象交互的所有对象中进行扩展.

  • 如果你不相信访问代码做正确的事情,那么getter/setter(在这种情况下是调整器)是必不可少的.例如,如果代码被其他开发人员或团队使用,这是一个好主意.如果您在这两种情况下都是开发人员,但是您不相信自己能够做到正确,或者能够解决它,请使用getter/setter.;)我个人更喜欢在字段不可变时删除getter.在另一个模块中访问的可变字段更可能需要getter/setter.如果您有适当的单元测试,您应该通过直接更改字段来获取可能发生的错误. (2认同)

coo*_*ird 18

面向对象编程的核心概念之一是封装 - 即从外部隐藏对象的状态(例如,对象中的数据),并让对象处理它自己的状态.

当封装完成时,对象的状态只能通过对象提供的接口来影响外部世界,例如对象具有的方法.

我认为你的代码已经开始使用封装了.

我们来看看代码吧

我们来看看这个beDamaged方法.

public void beDamaged(double damage)
{
    this.health -= damage;

    if (this.health < 0)
    {
        this.health = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们可以看到这个方法将被外界调用,玩家的健康状况将受到影响.它还包含逻辑,因此健康不能是负数.beDamaged您编写的播放器方法是将对象的状态保持在您定义为有效状态的参数内.

让我们推断一下玩家的情况

现在,从上面看,我想我可以推断出以下关于玩家对象:

玩家health不能是负数.

我们推断总是如此吗?

让我们看看你提供的代码是否总是如此.

啊哈!我们这里有一点问题:

public double health;
Run Code Online (Sandbox Code Playgroud)

在该health字段存在的情况下public,外部世界可以直接操作该字段,以便通过以下某些代码将玩家对象的状态置于可能不需要的状态:

Player player = new Player();
player.health = -100
Run Code Online (Sandbox Code Playgroud)

我猜测玩家不应该处于health负数的状态.

我们对于它可以做些什么呢?

怎么可以避免这个?- 通过health领域private.

现在,影响玩家的唯一方法health是通过beDamagedgainHealth方法,这可能是外界影响你的球员健康的正确方法.

这也意味着这一点 - 当你创建一个字段时private,这并不意味着你应该为该字段制作getter和setter.

私人领域不需要吸气剂和制定者

getter和setter通常是一种直接影响对象所具有的字段的方法,可能需要进行一些验证以防止错误的输入使得对象具有不应该存在的状态,但是有时候对象本身应该是负责影响数据,而不是外部实体.

  • "我应该验证设置方法" - > Bingo!这是使用setter而不是公共字段可以获得的优势; 有机会验证您的输入并拒绝不良数据,以使您的对象保持在可接受的状态. (2认同)

Arj*_*jms 8

在Java中,如果您的类的外部客户端确实需要访问这些字段,则建议使用带有getter/setter的私有字段.

否则,将它们保留为私有字段,并且不提供getter/setter.

这是最佳做法的原因有多种:

  1. 如果客户直接使用您的字段,以后需要更改某些内容,那么您就会陷入困境.使用getter,您可以在访问字段之前执行大量操作.
  2. 有一种叫做JavaBeans规范的东西要求你使用getter/setter.没有它们,你的类(当时称为bean)将无法与之互操作.JSP和JSF的EL是需要您的类遵守JavaBeans标准的一个示例.

(ps与您的问题无关,但您最好不要将backPack声明为ArrayList.声明为List;代码接口,而不是实现)