C# 抽象和封装有何不同?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16938667/
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
How abstraction and encapsulation differ?
提问by Aparan
I am preparing for an interview and decided to brush up my OOP concepts. There are hundreds of articles available, but it seems each describes them differently. Somesays
我正在准备面试并决定重温我的 OOP 概念。有数百篇文章可用,但似乎每篇文章对它们的描述都不同。 有人说
Abstraction is "the process of identifying common patterns that have systematic variations; an abstraction represents the common pattern and provides a means for specifying which variation to use" (Richard Gabriel).
抽象是“识别具有系统变化的共同模式的过程;抽象代表共同模式并提供指定使用哪个变化的方法”(Richard Gabriel)。
and is achieved through abstract classes.
并且是通过抽象类实现的。
Some othersays
一些其他的说
Abstraction means to show only the necessary details to the client of the object
抽象意味着只向对象的客户端显示必要的细节
and
和
Let's say you have a method "CalculateSalary" in your Employee class, which takes EmployeeId as parameter and returns the salary of the employee for the current month as an integer value. Now if someone wants to use that method. He does not need to care about how Employee object calculates the salary? An only thing he needs to be concern is name of the method, its input parameters and format of resulting member,
假设您的 Employee 类中有一个方法“CalculateSalary”,它以 EmployeeId 作为参数,并以整数值返回员工当月的工资。现在,如果有人想使用该方法。他不需要关心 Employee 对象如何计算工资?他唯一需要关心的是方法的名称,它的输入参数和结果成员的格式,
I googled again and again and none of the results seem to give me a proper answer. Now, where does encapsulation fit in all these?I searched and found a stack overflow question. Even the answers to that questions were confusing Here, it says
我一次又一次地用谷歌搜索,似乎没有一个结果给我一个正确的答案。 现在,封装在哪里适合所有这些?我搜索并发现了一个堆栈溢出问题。甚至这些问题的答案也令人困惑 在这里,它说
Encapsulation is a strategy used as part of abstraction. Encapsulation refers to the state of objects - objects encapsulate their state and hide it from the outside; outside users of the class interact with it through its methods, but cannot access the classes state directly. So the class abstracts away the implementation details related to its state.
封装是一种用作抽象一部分的策略。封装是指对象的状态——对象封装自己的状态,对外隐藏;类的外部用户通过其方法与其交互,但不能直接访问类状态。因此该类抽象出了与其状态相关的实现细节。
And hereanother reputed member says,
而这里的另一个知名的成员说,
They are different concepts.
Abstraction is the process of refining away all the unneeded/unimportant attributes of an object and keep only the characteristics best suitable for your domain.
它们是不同的概念。
抽象是提炼出对象所有不需要/不重要的属性并仅保留最适合您的领域的特征的过程。
Now I m messed up with the whole concept. I know about abstract class, inheritance, access specifiers and all. I just want to know how should I answer when I am asked about abstraction and/or encapsulation in an interview.
现在我搞砸了整个概念。我了解抽象类、继承、访问说明符等等。我只是想知道当我在面试中被问及抽象和/或封装时我应该如何回答。
Please don't mark it as a duplicate. I know there are several similar questions. But I want to avoid the confusion among the conflicting explanations. Can anyone suggest a credible link? A link to stackoverflow question is also welcome unless it creates confusion again. :)
请不要将其标记为重复。我知道有几个类似的问题。但我想避免相互矛盾的解释之间的混淆。谁能建议一个可靠的链接?除非再次引起混乱,否则也欢迎提供指向 stackoverflow 问题的链接。:)
EDIT: I need answers, a bit c# oriented
编辑:我需要一些答案,有点面向 c#
采纳答案by Egi
Abstraction means to show only the necessary details to the client of the object
抽象意味着只向对象的客户端显示必要的细节
Actually that is encapsulation. also see the first part of the wikipedia article in order to not be confused by encapsulation and data hiding. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
其实就是封装。另请参阅维基百科文章的第一部分,以免被封装和数据隐藏混淆。http://en.wikipedia.org/wiki/Encapsulation_(面向对象的编程)
keep in mind that by simply hiding all you class members 1:1 behind properties is not encapsulation at all. encapsulation is all about protecting invariants and hiding of implementation details.
请记住,通过简单地将所有类成员 1:1 隐藏在属性后面根本不是封装。封装是关于保护不变量和隐藏实现细节。
here a good article about that. http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/also take a look at the articles linked in that article.
这里有一篇关于这个的好文章。 http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/也看看那篇文章中链接的文章。
classes, properties and access modifiers are tools to provide encapsulation in c#.
类、属性和访问修饰符是在 C# 中提供封装的工具。
you do encapsulation in order to reduce complexity.
您进行封装以降低复杂性。
Abstraction is "the process of identifying common patterns that have systematic variations; an abstraction represents the common pattern and provides a means for specifying which variation to use" (Richard Gabriel).
抽象是“识别具有系统变化的共同模式的过程;抽象代表共同模式并提供指定使用哪个变化的方法”(Richard Gabriel)。
Yes, that is a good definition for abstraction.
是的,这是抽象的一个很好的定义。
They are different concepts. Abstraction is the process of refining away all the unneeded/unimportant attributes of an object and keep only the characteristics best suitable for your domain.
它们是不同的概念。抽象是提炼出对象所有不需要/不重要的属性并仅保留最适合您的领域的特征的过程。
Yes, they are different concepts. keep in mind that abstraction is actually the opposite of making an object suitable for YOUR domain ONLY. it is in order to make the object suitable for the domain in general!
是的,它们是不同的概念。请记住,抽象实际上与使对象仅适用于您的领域相反。就是为了让对象适合一般的领域!
if you have a actual problem and provide a specific solution, you can use abstraction to formalize a more generic solution that can also solve more problems that have the same common pattern. that way you can increase the re-usability for your components or use components made by other programmers that are made for the same domain, or even for different domains.
如果您有实际问题并提供特定解决方案,则可以使用抽象来形式化更通用的解决方案,该解决方案也可以解决更多具有相同通用模式的问题。通过这种方式,您可以提高组件的可重用性,或者使用其他程序员为同一域甚至不同域制作的组件。
good examples are classes provided by the .net framework, for example list or collection. these are very abstract classes that you can use almost everywhere and in a lot of domains. Imagine if .net only implemented a EmployeeList class and a CompanyList that could only hold a list of employees and companies with specific properties. such classes would be useless in a lot of cases. and what a pain would it be if you had to re-implement the whole functionality for a CarList for example. So the "List" is ABSTRACTED away from Employee, Company and Car. The List by itself is an abstract concept that can be implemented by its own class.
很好的例子是 .net 框架提供的类,例如列表或集合。这些是非常抽象的类,您几乎可以在任何地方和许多领域中使用它们。想象一下,如果 .net 只实现了一个 EmployeeList 类和一个 CompanyList ,它们只能保存具有特定属性的员工和公司的列表。在很多情况下,这样的类是无用的。例如,如果您必须为 CarList 重新实现整个功能,那将是多么痛苦。所以“列表”是从员工、公司和汽车中抽象出来的。List 本身是一个抽象概念,可以由它自己的类来实现。
Interfaces, abstract classes or inheritance and polymorphism are tools to provide abstraction in c#.
接口、抽象类或继承和多态是在 C# 中提供抽象的工具。
you do abstraction in order to provide reusability.
您进行抽象以提供可重用性。
回答by Taj
Encapsulation: hiding data using getters and setters etc.
封装:使用 getter 和 setter 等隐藏数据。
Abstraction: hiding implementation using abstract classes and interfaces etc.
抽象:使用抽象类和接口等隐藏实现。
回答by icbytes
As I knowit, encapsulation is hiding data of classes in themselves, and only making it accessible via setters / getters, if they must be accessed from the outer world.
据我所知,封装将类的数据隐藏在自身中,并且只有在必须从外部世界访问时才能通过 setter/getter 访问它们。
Abstraction is the class design for itself.
抽象是自己的类设计。
Means, how You create Your class tree, which methods are general ones, which are inherited, which can be overridden,which attributes are only on private level, or on protected, how Do You build up Your class inheritance tree, Do You use final classes, abtract classes, interface-implementation.
意思是,你如何创建你的类树,哪些方法是通用的,哪些是继承的,哪些可以被覆盖,哪些属性仅在私有级别,或在受保护的级别,你如何建立你的类继承树,你是否使用 final类,抽象类,接口实现。
Abstraction is more placed the oo-design phase, while encapsulation also enrolls into developmnent-phase.
抽象更多地处于面向对象设计阶段,而封装也进入了开发阶段。
回答by Mike Panter
I think they are slightly different concepts, but often they are applied together. Encapsulation is a technique for hiding implementation details from the caller, whereas abstraction is more a design philosophy involving creating objects that are analogous to familiar objects/processes, to aid understanding. Encapsulation is just one of many techniques that can be used to create an abstraction.
我认为它们是略有不同的概念,但通常它们一起应用。封装是一种对调用者隐藏实现细节的技术,而抽象更多是一种设计理念,涉及创建类似于熟悉的对象/过程的对象,以帮助理解。封装只是可用于创建抽象的众多技术之一。
For example, take "windows". They are not really windows in the traditional sense, they are just graphical squares on the screen. But it's useful to think of them as windows. That's an abstraction.
例如,以“窗口”为例。它们并不是传统意义上的真正窗口,它们只是屏幕上的图形方块。但是将它们视为窗口很有用。那是一种抽象。
If the "windows API" hides the details of how the text or graphics is physically rendered within the boundaries of a window, that's encapsulation.
如果“windows API”隐藏了如何在窗口边界内物理呈现文本或图形的细节,那就是封装。
回答by Lorentz Vedeler
One example has always been brought up to me in the context of abstraction; the automatic vs. manual transmission on cars. The manual transmission hides some of the workings of changing gears, but you still have to clutch and shift as a driver. Automatic transmission encapsulates all the details of changing gears, i.e. hides it from you, and it is therefore a higher abstraction of the process of changing gears.
一个例子总是在抽象的背景下出现在我面前;汽车上的自动变速器与手动变速器。手动变速箱隐藏了换档的一些工作,但作为驾驶员,您仍然必须离合和换档。自动变速器封装了换档的所有细节,即对您隐藏,因此它是换档过程的更高抽象。
回答by AndersK
my 2c
我的 2c
the purpose of encapsulation is to hide implementation details from the user of your class e.g. if you internally keep a std::list of items in your class and then decide that a std::vector would be more effective you can change this without the user caring. That said, the way you interact with the either stl container is thanks to abstraction, both the list and the vector can for instance be traversed in the same way using similar methods (iterators).
封装的目的是向类的用户隐藏实现细节,例如,如果您在类中内部保留了一个 std::list 项目,然后决定 std::vector 会更有效,您可以在没有用户的情况下进行更改关心。也就是说,您与 stl 容器交互的方式归功于抽象,例如可以使用类似的方法(迭代器)以相同的方式遍历列表和向量。
回答by Sanchit
I will try to demonstrate Encapsulation and Abstraction in a simple way.. Lets see..
我将尝试以简单的方式演示封装和抽象..让我们看看..
- The wrapping up of data and functions into a single unit (called class) is known as encapsulation. Encapsulation containing and hiding information about an object, such as internal data structures and code.
- 将数据和函数包装成一个单元(称为类)称为封装。包含和隐藏对象信息的封装,例如内部数据结构和代码。
Encapsulation is -
封装是 -
- Hiding Complexity,
- Binding Data and Function together,
- Making Complicated Method's Private,
- Making Instance Variable's Private,
- Hiding Unnecessary Data and Functions from End User.
- 隐藏复杂性,
- 将数据和函数绑定在一起,
- 将复杂方法设为私有,
- 使实例变量私有,
- 对最终用户隐藏不必要的数据和功能。
Encapsulation implements Abstraction.
封装实现抽象。
And Abstraction is -
而抽象是——
- Showing Whats Necessary,
- Data needs to abstract from End User,
- 显示什么是必要的,
- 数据需要从最终用户那里抽象出来,
Lets see an example-
让我们看一个例子——
The below Image shows a GUI of "Customer Details to be ADD-ed into a Database".
下图显示了“要添加到数据库中的客户详细信息”的 GUI。


By looking at the Image we can say that we need a Customer Class.
通过查看图像,我们可以说我们需要一个客户类。
Step - 1: What does my Customer Class needs?
步骤 - 1:我的客户类别需要什么?
i.e.
IE
2 variables to store Customer Code and Customer Name.
1 Function to Add the Customer Code and Customer Name into Database.
2 个变量来存储客户代码和客户名称。
1 将客户代码和客户名称添加到数据库中的函数。
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
Now only ADD method wont work here alone.
现在只有 ADD 方法不能单独在这里工作。
Step -2: How will the validation work, ADD Function act?
第 -2 步:验证将如何工作,ADD 函数将如何操作?
We will need Database Connection code and Validation Code (Extra Methods).
我们将需要数据库连接代码和验证代码(额外方法)。
public bool Validate()
{
//Granular Customer Code and Name
return true;
}
public bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.Validate();
obj.CreateDBObject();
obj.ADD();
}
}
Now there is no need of showing the Extra Methods(Validate(); CreateDBObject()[Complicated and Extra method] ) to the End User.End user only needs to see and know about Customer Code, Customer Name and ADD button which will ADD the record.. End User doesn't care about HOW it will ADD the Data to Database?.
现在不需要向最终用户展示额外的方法(Validate();CreateDBObject()[复杂和额外的方法])。最终用户只需要查看和了解客户代码、客户名称和添加记录的添加按钮。最终用户不关心它如何将数据添加到数据库?。
Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction.
第 -3 步:私有不涉及最终用户交互的额外和复杂的方法。
So making those Complicated and Extra method as Private instead Public(i.e Hiding those methods) and deleting the obj.Validate();obj.CreateDBObject();from main in class Program we achieve Encapsulation.
因此,将那些复杂和额外的方法设为私有而不是公共(即隐藏这些方法)并obj.Validate();obj.CreateDBObject();从类 Program 中的 main 中删除我们实现了封装。
In other words Simplifying Interface to End User is Encapsulation.
换句话说,简化最终用户的接口就是封装。
So now the complete code looks like as below -
所以现在完整的代码如下所示 -
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
private bool Validate()
{
//Granular Customer Code and Name
return true;
}
private bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.ADD();
}
}
Summary :
概括 :
Step -1: What does my Customer Class needs? is Abstraction.
第 -1 步:我的客户类需要什么?是抽象。
Step -3: Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction is Encapsulation.
步骤-3:步骤-3:私有的不涉及最终用户交互的额外和复杂的方法是封装。
P.S. - The code above is hard and fast.
PS - 上面的代码很难而且很快。
UPDATE: There is an video on this link to explain the sample: What is the difference between Abstraction and Encapsulation
更新:此链接上有一个视频来解释示例: 抽象和封装之间的区别是什么
回答by FrankO
I think of it this way, encapsulation is hiding the way something gets done. This can be one or many actions.
我是这样想的,封装隐藏了某些事情的完成方式。这可以是一项或多项操作。
Abstraction is related to "why" I am encapsulating it the first place.
抽象与我首先封装它的“为什么”有关。
I am basically telling the client "You don't need to know much about how I process the payment and calculate shipping, etc. I just want you to tell me you want to 'Checkout' and I will take care of the details for you."
我基本上是在告诉客户“你不需要知道我如何处理付款和计算运费等。我只是想让你告诉我你想‘结账’,我会为你处理细节.”
This way I have encapsulated the details by generalizing (abstracting) into the Checkout request.
通过这种方式,我通过概括(抽象)到 Checkout 请求中来封装细节。
I really think that abstracting and encapsulation go together.
我真的认为抽象和封装是相辅相成的。
回答by displayName
Below is a semester long course distilled in a few paragraphs.
下面是一个学期的课程,分为几段。
Object-Oriented Analysis and Design (OOAD) is actually based on not just two but four principles. They are:
面向对象的分析和设计 (OOAD) 实际上不仅基于两个而是基于四个原则。他们是:
Abstraction:means that you only incorporate those features of an entity which are required in your application. So, if every bank account has an opening date but your application doesn't need to know an account's opening date, then you simply don't add the OpeningDatefield in your Object-Oriented Design (of the BankAccount class). ?Abstraction in OOAD has nothing to do with abstract classes in OOP.
Per the principle of Abstraction, your entities are an abstractionof what they are in the real world. This way, you design an abstraction of Bank Account down to only that level of detail that is needed by your application.
Inheritance:is more of a coding-trick than an actual principle. It saves you from re-writing those functionalities that you have written somewhere else. However, the thinking is that there must be a relation between the new code you are writing and the old code you are wanting to re-use. Otherwise, nobody prevents you from writing an Animalclass which is inheriting from BankAccount, even if it is totally non-sensical.
Just like you may inherit your parents' wealth, you may inherit fields and methods from your parent class. So, taking everything that parent class has and then adding something more if need be, is inheritance. Don't go looking for inheritance in your Object Oriented Design. Inheritance will naturally present itself.
Polymorphism:is a consequence of inheritance. Inheriting a method from the parent is useful, but being able to modify a method if the situation demands, is polymorphism. You may implement a method in the subclass with exactly the same signatureas in parent class so that when called, the method from child class is executed. This is the principle of Polymorphism.
Encapsulation:implies bundling the related functionality together and giving access to onlythe needful. Encapsulation is the basis of meaningful class designingin Object Oriented Design, by:
- putting related data and methods together; and,
- exposing only the pieces of data and methods relevant for functioning with external entities.
抽象:意味着您只包含应用程序中所需的实体的那些功能。因此,如果每个银行帐户都有一个开户日期,但您的应用程序不需要知道帐户的开户日期,那么您只需不要在面向对象的设计(BankAccount 类的)中添加OpeningDate字段。? OOAD 中的抽象与 OOP 中的抽象类无关。
根据抽象原则,您的实体是它们在现实世界中的抽象。通过这种方式,您可以将银行账户的抽象设计到您的应用程序所需的详细程度。
继承:与其说是实际原则,不如说是一种编码技巧。它使您免于重新编写您在其他地方编写的那些功能。但是,我们的想法是,您正在编写的新代码与您想要重用的旧代码之间必须存在某种关系。否则,没有人会阻止您编写从BankAccount继承的Animal类,即使它完全没有意义。
就像您可以继承父母的财富一样,您也可以从父类继承字段和方法。因此,获取父类拥有的所有内容,然后根据需要添加更多内容,这就是继承。不要在面向对象的设计中寻找继承。继承自然会出现。
多态:是继承的结果。从父级继承方法很有用,但如果情况需要,能够修改方法是多态性。您可以在子类中使用与父类中完全相同的签名来实现一个方法,以便在调用时执行子类中的方法。这就是多态的原理。
封装:意味着将相关的功能捆绑在一起,并只允许访问需要的。封装是面向对象设计中有意义的类设计的基础,通过:
- 将相关数据和方法放在一起;和,
- 仅公开与外部实体的功能相关的数据和方法。
Another simplified answer is here.
另一个简化的答案是here。
?People who argue that "Abstraction of OOAD results in the abstract keyword of OOP"...Well that is incorrect.
? 那些争论“OOAD 的抽象导致 OOP 的抽象关键字”的人......这是不正确的。
Example: When you design a University in an application using object oriented principles, you only design an "abstraction" of the university. Even though there is usually one cash dispensing ATM in almost every university, you may not incorporate that fact if it's not needed for your application. And now though you have designed only an abstraction of the university, you are not required to put abstractin your class declaration. Your abstract design of university will be a normal class in your application.
示例:当您使用面向对象的原则在应用程序中设计大学时,您只设计了大学的“抽象”。尽管几乎每所大学通常都有一个提款机,但如果您的申请不需要它,您可能不会考虑这一事实。现在虽然你只设计了大学的抽象,你不需要放入abstract你的类声明。你的大学抽象设计将是你申请中的一个普通班级。
回答by displayName
Abstraction:is outlined by the top left and top right images of the cat. The surgeon and the old lady designed (or visualized) the animal differently. In the same way, you would put different features in the Cat class, depending upon the need of the application. Every cat has a liver, bladder, heart and lung, but if you need your cat to 'purr' only, you will abstract your application's cat to the design on top-left rather than the top-right.
抽象:由猫的左上角和右上角的图像勾勒出来。外科医生和老太太设计(或想象)动物的方式不同。同样,您可以根据应用程序的需要在 Cat 类中放置不同的功能。每只猫都有肝脏、膀胱、心脏和肺,但是如果您只需要您的猫“发出咕噜声”,您可以将应用程序的猫抽象到左上角而不是右上角的设计中。
Encapsulation:is outlined by the cat standing on the table. That's what everyone outside the cat should see the cat as. They need not worry whether the actual implementation of the cat is the top-left one or the top-right one or even a combination of both.
封装:由猫站在桌子上勾勒出来。这就是猫之外的每个人都应该看到的猫。他们不必担心猫的实际实现是左上角的还是右上角的,甚至是两者的组合。
PS:Go hereon this same question to hear the complete story.
PS:在同一个问题上去这里听完整的故事。

