简体   繁体   English

当有许多属性时,不使用Java中的set和get方法

[英]Not using set and get methods in Java when there are many attributes

So I have been learning about OOP. 所以我一直在学习OOP。 I am currently trying to create simple "Hero Profiles" with HP, Mana, intelligence, strength, agility, armor etc. As you can see, there are a lot of attributes I want to add to Hero objects. 我目前正在尝试使用HP,Mana,智能,力量,敏捷,装甲等创建简单的“英雄配置文件”。正如您所看到的,我想要添加到Hero对象中的属性很多。 But these attributes are declared in private not public (Because I was told that it was best to declare these private) and when I declare them in private I have to form set and get methods to each of these attributes. 但是这些属性是私有的而不是公开的(因为我被告知最好将这些属性声明为私有),当我私下声明它们时,我必须为每个属性创建set和get方法。 And it consumes so much time and I feel like it is not practical. 它消耗了很多时间,我觉得它不实用。

Is there a more practical way? 有更实用的方法吗? Do coders really type these get and set methods even though there are a dozen of them? 编码员是否真的键入了这些get和set方法,即使它们有十几种? All I want to do is create two Hero Profiles with these attributes and then simulate a 1v1 battle between the two. 我想做的就是用这些属性创建两个Hero Profiles,然后模拟两者之间的1v1战斗。

Having getters ans setters around your properties is really important. 在你的房产周围设置getters和setter非常重要。 Otherwise, you break encapsulation. 否则,你打破了封装。

Unfortunately, Java does not provide a suitable shortcut for programmers to declare getters and setters. 不幸的是,Java没有为程序员提供合适的快捷方式来声明getter和setter。 However, many IDEs do provide tools for you to generate accessor methods. 但是,许多IDE确实为您提供了生成访问器方法的工具。

Whoever told you, that individual attributes of the object should be private was absolutely right ! 无论谁告诉你,对象的个别属性应该是私有的绝对正确

One of the basic principles of OOP is Encapsulation . OOP的基本原则之一是封装 Simply put, it means that the internal structure of the object (the "fields") should be hidden. 简单地说,这意味着应该隐藏对象的内部结构(“字段”)。 This is the most important aspect of OOP, from which most of the advantages of OOP come from. 这是OOP最重要的方面,OOP的大部分优势都来自于此。

Now, accessor methods (setters and getters) violate encapsulation , the same way just making them public does, since you are no longer hiding the internal structure. 现在,访问器方法 (setter和getter) 违反封装 ,就像公开它们一样,因为你不再隐藏内部结构。 It is not just about protecting internal fields, it's about hiding them. 它不仅仅是保护内部领域,而是隐藏它们。

Unfortunately accessor methods are a common idiom in Java (and C# too), but if you are serious about learning OOP, you should avoid them at all costs! 不幸的是,访问器方法是Java中常见的习惯用法(也是C#),但如果你认真学习OOP,你应该不惜一切代价避免使用它们! Later, when you have more experience, you might make exceptions in a few cases, but I would urge you just avoid them for now. 之后,当你有更多的经验时,你可能会在少数情况下做出例外,但我会敦促你暂时避免它们。 Avoid Project Lombok and avoid IDE features to auto-generate stuff. 避免使用Project Lombok并避免IDE功能自动生成内容。

Here is a brilliant article from Allen Holub on the subject. 是Allen Holub关于这个主题的精彩文章。

Back to your actual question: Yes, you declare your fields private, but you don't define setters/getters for them at all. 回到你的实际问题:是的,你声明你的字段是私有的,但你根本没有为它们定义setter / getters。 What we do instead, is think about what responsibilities/features/functions/logic the object should have. 我们所做的是考虑对象应具有的职责/特征/功能/逻辑。

So instead of thinking about the stats, think about what you are using those stats for. 因此,而不是思考的统计,想想你正在使用这些统计信息是什么 An object-oriented Hero might look like this then: 面向对象的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);
    }
    ...
}

Of course, that's only an example, but you probably get the point. 当然,这只是一个例子,但你可能会明白这一点。 There's no need at all to publish the internal fields at all, if your design is right. 如果您的设计是正确的,根本不需要发布内部字段。

Yes, you should write or generate getters and setters thanks to your IDE to encapsulate your fields, moreother than a good practice, you haven't to change the get() and set() calls in your code when you change the variable's name, or type (from Collection to List for instance), and it's more usefull in java8 for the use of lambda methods call 是的,你应该编写或生成getter和setter,这要归功于你的IDE封装了你的字段,而不是一个好的做法,当你改变变量的名字时,你不必更改代码中的get()和set()调用,或类型(例如,从Collection到List),并且在java8中使用lambda方法调用更有用

Plus, YOUR class is managing its attributes, and no one can change their state in an unconvinient way 此外,你的班级正在管理其属性,没有人能够以不方便的方式改变他们的状态

If you hate to make getters and setter, or you think they create confusion/ they are unnecesarry, you can use Lombok. 如果你不想制造吸气剂和制定者,或者你认为它们造成混乱/它们是不必要的,你可以使用龙目岛。 Maybe it is not a beginner thing to use external frameworks but it is interesting. 也许使用外部框架并不是一个初学者的事情,但它很有趣。

https://projectlombok.org/ https://projectlombok.org/

check this : 检查一下:

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

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

@huzo, Welcome to OOP and Thanks for trying Java. @huzo,欢迎来到OOP,感谢您尝试使用Java。 Answering your question ,for IntelliJ use https://www.jetbrains.com/help/idea/2017.1/generating-getters-and-setters.html and once you become familiar do try out https://projectlombok.org/ as suggested by @Rjiuk to avoid setters and getters. 回答你的问题,对于IntelliJ使用https://www.jetbrains.com/help/idea/2017.1/generating-getters-and-setters.html ,一旦熟悉, 按照建议尝试https://projectlombok.org/由@Rjiuk来避免制定者和吸气者。

I am currently trying to create simple "Hero Profiles" with HP, Mana, intelligence, strength, agility, armor etc. As you can see, there are a lot of attributes I want to add to Hero objects. 我目前正在尝试使用HP,Mana,智能,力量,敏捷,装甲等创建简单的“英雄配置文件”。正如您所看到的,我想要添加到Hero对象中的属性很多。

Looking at these line I can say, Here you have inheritance tree. 看看这些我可以说,这里有继承树。 You can take a parent class for these and keep common members(variables and methods) in it. 您可以为这些创建父类,并在其中保留常用成员(变量和方法)。 Parent class can be interface or abstract class or concrete class. 父类可以是interfaceabstract class或具体类。 So then you can pass values for member variables through the constructor. 那么你可以通过构造函数传递成员变量的值。

In fact, think you have strength class and you have member variable called armStrength (as a example). 事实上,你认为你有strength等级,并且你有一个名为armStrength成员变量(作为例子)。 When you create new instance of this class you can pass value through the constructor. 当您创建此类的新实例时,您可以通过构造函数传递值。 But later on arm become weak/broken. 但后来手臂变得虚弱/破碎。 In this case you need to update armStrength . 在这种情况下,您需要更新armStrength

To accomplish that also you need a setter method. 要实现这一点,您还需要一个setter方法。 Having getter and setters is a better thing in OOP. 拥有getter和setter在OOP中更好。 Because of encapsulation is one of the main point of an in OOP. 因为封装是OOP中的一个主要观点。

In order to avoid confusion when having lot of getters and setters you can keep those in a separate class. 为了避免在拥有大量的getter和setter时出现混淆,你可以将它们保存在一个单独的类中。

Luckily, rather than typing all the getters and setters you can use IDE shortcuts to genetate those for you. 幸运的是,您可以使用IDE快捷方式为您设置所有getter和setter,而不是键入所有getter和setter。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM