Java 对象和数据结构有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23406307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Whats the difference between objects and data structures?
提问by Hoodlum
I've been reading the book Clean Code: A Handbook of Agile Software Craftsmanshipand in chapter six pages 95-98 it clarifies about the differences between objects and data structures:
我一直在阅读Clean Code: A Handbook of Agile Software Craftsmanship这本书,在第 6 章第 95-98 页中阐明了对象和数据结构之间的区别:
Objects hide their data behind abstractions and expose functions that operate on that data. Data structures expose their data and have no meaningful functions.
Object expose behavior and hide data. This makes it easy to add new kinds of objects without changing existing behaviors. It also makes it hard to add new behaviors to existing objects.
Data structures expose data and have no significant behavior. This makes it easy to add new behaviors to existing data structures but makes it hard to add new data structures to existing functions.
对象将它们的数据隐藏在抽象之后,并公开对这些数据进行操作的函数。数据结构暴露了它们的数据并且没有有意义的功能。
对象公开行为并隐藏数据。这使得在不改变现有行为的情况下轻松添加新类型的对象。这也使得向现有对象添加新行为变得困难。
数据结构公开数据并且没有重要的行为。这使得向现有数据结构添加新行为变得容易,但使得向现有函数添加新数据结构变得困难。
I'm a tad bit confused whether some classes are objects or data structures. Say for example HashMaps in java.util, are they objects? (because of its methods like put(), get(), we dont know their inner workings) or are they data structures? (I've always thought of it as data structures because its a Map).
我有点困惑某些类是对象还是数据结构。比如说 java.util 中的 HashMaps,它们是对象吗?(因为像 put()、get() 这样的方法,我们不知道它们的内部工作原理)还是它们是数据结构?(我一直认为它是数据结构,因为它是一个 Map)。
Strings as well, are they data structures or objects?
字符串也是如此,它们是数据结构还是对象?
So far majority of the code I've been writing have been the so called "hybrid classes" which try to act as an object and a data structure as well. Any tips on how to avoid them as well?
到目前为止,我编写的大部分代码都是所谓的“混合类”,它们试图充当对象和数据结构。关于如何避免它们的任何提示?
采纳答案by Ferdinand Beyer
The distinction between data structures and classes/objects is a harder to explain in Java than in C++. In C, there are no classes, only data structures, that are nothing more than "containers" of typed and named fields. C++ inherited these "structs", so you can have both "classic" data structures and "real objects".
数据结构和类/对象之间的区别在 Java 中比在 C++ 中更难解释。在 C 中,没有类,只有数据结构,它们只不过是类型化和命名字段的“容器”。C++ 继承了这些“结构”,因此您可以同时拥有“经典”数据结构和“真实对象”。
In Java, you can "emulate" C-style data structures using classes that have no methods and only public fields:
在 Java 中,您可以使用没有方法而只有公共字段的类来“模拟”C 风格的数据结构:
public class VehicleStruct
{
public Engine engine;
public Wheel[] wheels;
}
A user of VehicleStruct
knows about the parts a vehicle is made of, and can directly interact with these parts. Behavior, i.e. functions, have to be defined outside of the class. That's why it is easy to change behavior: Adding new functions won't require existing code to change. Changing data, on the other hand, requires changes in virtually every function interacting with VehicleStruct
. It violates encapsulation!
用户VehicleStruct
了解车辆的组成部件,并可以直接与这些部件进行交互。行为,即函数,必须在类之外定义。这就是为什么很容易改变行为的原因:添加新函数不需要改变现有代码。另一方面,更改数据需要更改与VehicleStruct
. 它违反了封装!
The idea behind OOP is to hide the data and expose behavior instead. It focuses on what you can dowith a vehicle without having to know if it has engine or how many wheels are installed:
OOP 背后的想法是隐藏数据并公开行为。它专注于您可以用车辆做什么,而不必知道它是否有发动机或安装了多少个车轮:
public class Vehicle
{
private Details hidden;
public void startEngine() { ... }
public void shiftInto(int gear) { ... }
public void accelerate(double amount) { ... }
public void brake(double amount) { ... }
}
Notice how the Vehicle
could be a motorcycle, a car, a truck, or a tank -- you don't need to know the details. Changing data is easy -- nobody outside the class knows about data so no user of the class needs to be changed. Changing behavior is difficult: All subclasses must be adjusted when a new (abstract) function is added to the class.
注意它Vehicle
可能是摩托车、汽车、卡车或坦克——你不需要知道细节。更改数据很容易——类之外没有人知道数据,因此不需要更改类的用户。改变行为是很困难的:当一个新的(抽象的)函数被添加到类中时,所有的子类都必须进行调整。
Now, following the "rules of encapsulation", you could understand hiding the data as simply making the fields private and adding accessor methods to VehicleStruct
:
现在,遵循“封装规则”,您可以将隐藏数据理解为简单地将字段设为私有并将访问器方法添加到VehicleStruct
:
public class VehicleStruct
{
private Engine engine;
private Wheel[] wheels;
public Engine getEngine() { return engine; }
public Wheel[] getWheels() { return wheels; }
}
In his book, Uncle Bob argues that by doing this, you still have a data structure and not an object. You are still just modeling the vehicle as the sum of its parts, and expose these parts using methods. It is essentially the same as the version with public fields and a plain old C struct
-- hence a data structure. Hiding data and exposing methods is not enough to create an object, you have to consider if the methods actually expose behavioror just the data!
在他的书中,鲍勃叔叔认为,通过这样做,你仍然拥有一个数据结构,而不是一个对象。您仍然只是将车辆建模为其部件的总和,并使用方法来显示这些部件。它本质上与具有公共字段和普通旧 C 的版本相同struct
——因此是一种数据结构。隐藏数据和公开方法不足以创建对象,您必须考虑方法是否真正公开行为或仅公开数据!
When you mix the two approaches, e.g. exposing getEngine()
along with startEngine()
, you end up with a "hybrid". I don't have Martin's Book at hand, but I remember that he did not recommend hybrids at all, as you end up with the worst of both worlds: Objects where both data and behavior is hard to change.
当你混合这两种方法时,例如getEngine()
与 一起暴露startEngine()
,你最终会得到一个“混合”。我手头没有 Martin 的书,但我记得他根本不推荐混合,因为你最终会遇到两个世界中最糟糕的情况:数据和行为都难以改变的对象。
Your questions concerning HashMaps and Strings are a bit tricky, as these are pretty low level and don't fit quite well in the kinds of classes you will be writing for your applications. Nevertheless, using the definitions given above, you should be able to answer them.
您关于 HashMaps 和 Strings 的问题有点棘手,因为它们的级别非常低,并且不太适合您将为应用程序编写的类。尽管如此,使用上面给出的定义,您应该能够回答它们。
A HashMap
is an object. It exposes its behavior to you and hides all the nasty hashing details. You tell it to put
and get
data, and don't care which hash function is used, how many "buckets" there are, and how collisions are handled. Actually, you are using HashMap
solely through its Map
interface, which is quite a good indication of abstraction and "real" objects.
AHashMap
是一个对象。它向您公开其行为并隐藏所有令人讨厌的散列细节。你告诉它put
和get
数据,而不关心使用哪个散列函数,有多少“桶”,以及如何处理冲突。实际上,您HashMap
仅通过其Map
界面使用,这很好地表明了抽象和“真实”对象。
Don't get confused that you can use instancesof a Map as a replacement for a data structure!
不要对您可以使用Map 的实例作为数据结构的替代品感到困惑!
// A data structure
public class Point {
public int x;
public int y;
}
// A Map _instance_ used instead of a data structure!
Map<String, Integer> data = new HashMap<>();
data.put("x", 1);
data.put("y", 2);
A String
, on the other hand, is pretty much an array of characters, and does not try to hide this very much. I guess one could call it a data structure, but to be honest I am not sure if much is to be gained one way or the other.
String
另一方面,A几乎是一个字符数组,并不会试图隐藏它。我想人们可以称它为一种数据结构,但老实说,我不确定以这种方式或另一种方式是否可以获得很多。
回答by peter.petrov
An object is an instance of a class. A class can model various things from the real world. It's an abstraction of something (car, socket, map, connection, student, teacher, you name it).
对象是类的实例。一个类可以模拟现实世界中的各种事物。它是某种事物的抽象(汽车、插座、地图、连接、学生、老师,等等)。
A data structure is a structure which organizes certain data in a certain way. You can implement structures in ways different that by using classes (that's what you do in languages which don't support OOP e.g.; you can still implement a data structure in C let's say).
数据结构是以某种方式组织某些数据的结构。您可以以与使用类不同的方式实现结构(这就是您在不支持 OOP 的语言中所做的事情,例如;您仍然可以在 C 中实现数据结构,比如说)。
HashMap in java is a class which models a map data structure using hash-based implementation, that's why it's called HashMap.
Java 中的 HashMap 是一个类,它使用基于哈希的实现对地图数据结构进行建模,这就是它被称为 HashMap 的原因。
Socket in java is a class which doesn't model a data structure but something else (a socket).
java中的套接字是一个类,它不建模数据结构,而是建模其他东西(套接字)。
回答by Nazgul
Data structures(DS) are an abstract way of saying that a structure holds some data'. HashMap with some key value pairs is a data structure in Java. Associated arrays are similarly in PHP etc. Objects is a little lower than the DS level. Your hashmap is a data structure. now to use a hashmap you create an 'object' of it and add data to that object using put method. I can have my own class Employee which has data and is thus a DS for me. But to use this DS to do some operations like o see if the employee is a male or a female colleague i need an instance of an Employee and test its gender property.
数据结构(DS)是一种抽象的说法,表示一个结构包含一些数据。带有一些键值对的 HashMap 是 Java 中的一种数据结构。关联数组在 PHP 等中类似。对象比 DS 级别低一点。您的哈希图是一种数据结构。现在要使用哈希图,您可以创建它的“对象”并使用 put 方法向该对象添加数据。我可以拥有自己的 Employee 类,它有数据,因此对我来说是一个 DS。但是要使用此 DS 执行一些操作,例如查看员工是男性还是女性同事,我需要一个 Employee 实例并测试其性别属性。
Don't confuse objects with data structures.
不要将对象与数据结构混淆。
回答by Sumanth
A data structure is only an abstraction, a special way of representing data. They are just human-made constructs, which help in reducing complexity at the high-level, i.e. to not work in the low-level. An object may seem to mean the same thing, but the major difference between objects and data structures is that an object might abstract anything. It also offers behaviour. A data structure does not have any behaviour because it is just data-holding memory.
数据结构只是一种抽象,一种表示数据的特殊方式。它们只是人造结构,有助于降低高层的复杂性,即在低层不起作用。一个对象似乎意味着同一件事,但对象和数据结构之间的主要区别在于对象可能抽象任何东西。它还提供行为。数据结构没有任何行为,因为它只是保存数据的内存。
The libraries classes such as Map, List,etc. are classes, which representdata structures. They implement and setup a data structure so that you can easily work with them in your programs by creating instances of them (i.e. objects).
Map、List等库类。是表示数据结构的类。它们实现并设置了一个数据结构,以便您可以通过创建它们的实例(即对象)在程序中轻松地使用它们。
回答by ethanfar
As I see it , what Robert Martin tries to convey, is that objects should not expose their data via getters and setters unless their sole purpose is to act as simple data containers. Good examples of such containers might be java beans, entity objects (from object mapping of DB entities), etc.
在我看来,Robert Martin 试图传达的是,对象不应通过 getter 和 setter 公开其数据,除非它们的唯一目的是充当简单的数据容器。此类容器的好例子可能是 java bean、实体对象(来自 DB 实体的对象映射)等。
The Java Collection Framework classes, however, are not a good example of what he's referring to, since they don't really expose their internal data (which is in a lot of cases basic arrays). It provides abstraction that lets you retrieve objects that they contain. Thus (in my POV) they fit in the "Objects" category.
然而,Java Collection Framework 类并不是他所指的一个很好的例子,因为它们并没有真正公开它们的内部数据(在很多情况下是基本数组)。它提供了让您检索它们包含的对象的抽象。因此(在我的 POV 中)它们属于“对象”类别。
The reasons are stated by the quotes you added from the book, but there are more good reasons for refraining from exposing the internals. Classes that provide getters and setters invite breaches of the Law of Demeter, for instance. On top of that, knowing the structure of the state of some class (knowing which getters/setters it has) reduces the ability to abstract the implementation of that class. There are many more reasons of that sort.
原因由您从书中添加的引文说明,但还有更多更好的理由可以避免暴露内部结构。例如,提供 getter 和 setter 的类会违反迪米特法则。最重要的是,知道某个类的状态结构(知道它有哪些 getter/setter)会降低抽象该类实现的能力。这类原因还有很多。
回答by Mikeologist
Your question is tagged as Java, so I will reference only Java here. Objects are the Eve class in Java; that is to say everything in Java extends Object and object is a class.
您的问题被标记为 Java,因此我将在此处仅引用 Java。对象是 Java 中的 Eve 类;也就是说,Java 中的一切都扩展了 Object 并且 object 是一个类。
Therefor, all data structures are Objects, but not all Objects are data structures.
因此,所有的数据结构都是对象,但并非所有的对象都是数据结构。
The key to the difference is the term Encapsulation.
区别的关键是术语封装。
When you make an object in Java, it is considered best practice to make all of your data members private. You do this to protect them from anyone using the class.
在 Java 中创建对象时,将所有数据成员设为私有被认为是最佳实践。您这样做是为了保护它们免受使用该类的任何人的侵害。
However, you want people to be able to access the data, sometimes change it. So, you provide public methods called accessors and mutators to allow them to do so, also called getters and setters. Additionally, you may want them to view the object as a whole in a format of your choosing, so you can define a toString method; this returns a string representing the object's data.
但是,您希望人们能够访问数据,有时会更改数据。因此,您提供称为访问器和修改器的公共方法以允许它们这样做,也称为 getter 和 setter。此外,您可能希望他们以您选择的格式查看整个对象,因此您可以定义一个 toString 方法;这将返回一个表示对象数据的字符串。
A structure is slightly different.
结构稍有不同。
It is a class.
它是一个类。
It is an Object.
它是一个对象。
But it is usually private within another class; As a Node is private within a tree and should not be directly accessible to the user of the tree. However, inside the tree object the nodes data members are publicly visible. The node itself does not need accessors and mutators, because these functions are trusted to and protected by the tree object.
但它通常在另一个类中是私有的;由于节点在树中是私有的,因此树的用户不应直接访问。但是,在树对象内部,节点数据成员是公开可见的。节点本身不需要访问器和修改器,因为这些函数受树对象信任和保护。
Keywords to research: Encapsulation, Visibility Modifiers
研究关键词:封装、可见性修饰符
回答by Enrique
This is what, I believe, Robert. C. Martin was trying to convey:
我相信,这就是罗伯特。C. 马丁试图传达:
Data Structures are classes that simply act as containers of structured data. For example:
public class Point { public double x; public double y; }
Objects, on the other hand, are used to create abstractions. An abstractionis understood as:
a simplification of something much more complicated that is going on under the covers The Law of Leaky Abstractions, Joel on Software
So, objects hide all their underpinnings and only let you manipulate the essenceof their data in a simplified way. For instance:
public interface Point { double getX(); double getY(); void setCartesian(double x, double y); double getR(); double getTheta(); void setPolar(double r, double theta); }
Where we don't know how the Point is implemented, but we do know how to consumeit.
数据结构是简单地充当结构化数据容器的类。例如:
public class Point { public double x; public double y; }
另一方面,对象用于创建抽象。一个抽象被理解为:
对隐藏的更复杂的事情的简化The Law of Leaky Abstractions, Joel on Software
因此,对象隐藏了它们的所有基础,只能让您以简化的方式操作其数据的本质。例如:
public interface Point { double getX(); double getY(); void setCartesian(double x, double y); double getR(); double getTheta(); void setPolar(double r, double theta); }
我们不知道 Point 是如何实现的,但我们知道如何使用它。
回答by Ben Arnao
An object is an instance of a class. A class can define a set of properties/fields that every instance/object of that class inherits. A data structure is a way to organize and store data. Technically a data structure is an object, but it's an object with the specific use for holding other objects (everything in Java is an object, even primitive types).
对象是类的实例。一个类可以定义该类的每个实例/对象都继承的一组属性/字段。数据结构是一种组织和存储数据的方式。从技术上讲,数据结构是一个对象,但它是一个具有特定用途的对象,用于保存其他对象(Java 中的所有内容都是对象,甚至是原始类型)。
To answer your question a String is an object anda data structure. Every String object you create is an instance of the String class. A String, as Java represents it internally, is essentially a character array, and an array is a data structure.
要回答您的问题,字符串是一个对象和一个数据结构。您创建的每个 String 对象都是 String 类的一个实例。字符串,正如 Java 内部表示的那样,本质上是一个字符数组,而数组是一种数据结构。
Not all classes are blueprints for data structures, however all data structures are technically objects AKA instances of a class (that is specifically designed to store data), if that makes any sense.
并非所有类都是数据结构的蓝图,但是所有数据结构在技术上都是类的对象 AKA 实例(专门设计用于存储数据),如果有任何意义的话。