我正准备接受采访并决定刷新我的OOP概念。 有数百篇文章可供使用,但似乎每篇文章都有不同的描述。 Some说
抽象是“识别具有的常见模式的过程 系统变化;抽象代表了共同的模式 并提供了一种指定使用哪种变体的方法“(理查德 加布里埃尔)。
并通过抽象类实现。
有些other说
抽象意味着只向客户展示必要的细节 对象
和
假设你的Employee类中有一个方法“CalculateSalary”, 它将EmployeeId作为参数并返回的工资 当前月份的员工为整数值。现在,如果有人 想要使用那种方法。他不需要关心员工的方式 对象计算工资?他唯一需要关注的是 方法的名称,其输入参数和结果的格式 构件,
我一遍又一遍地搜索,结果似乎都没有给我一个正确的答案。 现在,封装在哪里适合所有这些? 我搜索了一下stack overflow question。即使这些问题的答案也令人困惑 Here,它说
封装是一种用作抽象的一部分的策略。封装 指对象的状态 - 对象封装它们的状态和 把它从外面隐藏起来;班级的外部用户与之互动 通过它的方法,但不能直接访问类状态。所以 该类抽象出与其相关的实现细节 状态。
here另一位知名成员说,
它们是不同的概念。
抽象是精炼所有人的过程 对象的不需要/不重要的属性,只保留 最适合您所在领域的特征。
现在我搞砸了整个概念。我知道抽象类,继承,访问说明符和所有。我只是想知道当我被问及抽样和/或封装时我应该如何回答。
请勿将其标记为重复。我知道有几个类似的问题。但我想避免相互矛盾的解释之间的混淆。任何人都可以提出可靠的链接吗?除非再次造成混淆,否则也欢迎链接到stackoverflow问题。 :)
编辑:我需要答案,有点c#导向
答案 0 :(得分:92)
封装:使用getter和setter等隐藏数据。
抽象:使用抽象类和接口等隐藏实现。
答案 1 :(得分:44)
抽象意味着只向对象的客户显示必要的细节
实际上那就是封装。还可以看到维基百科文章的第一部分,以免被封装和数据隐藏混淆。 http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
请记住,通过简单地隐藏属性后面的所有类成员1:1根本不是封装。封装就是保护不变量和隐藏实现细节。
这里有一篇很好的文章。 http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/ 另请参阅该文章中链接的文章。
类,属性和访问修饰符是在c#中提供封装的工具。
你进行封装以降低复杂性。
抽象是识别具有系统变化的常见模式的过程。抽象表示共同模式,并提供指定使用哪种变体的方法。 (理查德加布里埃尔)。
是的,这是一个很好的抽象定义。
它们是不同的概念。 抽象是一个细化对象的所有不需要/不重要的属性的过程,只保留最适合您的域的特征。
是的,它们是不同的概念。请记住,抽象实际上只是使对象适合您的域。它是为了使对象一般适合于域!
如果您遇到实际问题并提供特定解决方案,则可以使用抽象来形式化更通用的解决方案,该解决方案还可以解决具有相同常见模式的更多问题。这样,您可以增加组件的可重用性,或者使用为同一域甚至不同域制作的其他程序员制作的组件。
很好的例子是.net框架提供的类,例如list或collection。这些是非常抽象的类,几乎可以在任何地方和许多领域中使用。想象一下,如果.net只实现了一个EmployeeList类和一个只能保存具有特定属性的员工和公司列表的CompanyList。在很多情况下,这样的课程将毫无用处。如果你不得不重新实现CarList的整个功能,那会是多么痛苦。那么" List"摘自员工,公司和汽车。 List本身是一个抽象的概念,可以由它自己的类实现。
接口,抽象类或继承和多态是在c#中提供抽象的工具。
你做抽象以提供可重用性。
答案 2 :(得分:43)
<子> Image source 子>
抽象:由猫的左上角和右上角图像勾勒出来。外科医生和老太太以不同的方式设计(或可视化)动物。同样,您可以在Cat类中添加不同的功能,具体取决于应用程序的需要。每只猫都有肝脏,膀胱,心脏和肺,但是如果你需要你的猫来咕噜咕噜叫只有,你会将你的应用程序的猫抽象到左上角而不是右上角的设计中。
封装:由站在桌子上的猫概述。那个猫外面的每个人应该把猫视为。他们不必担心猫的实际实施是左上角还是右上角,甚至是两者的组合。
PS: 在同一问题上转到here,听听完整的故事。 < / p>
答案 3 :(得分:25)
我将尝试以简单的方式演示封装和抽象。让我们看看..
封装是 -
封装实现抽象。
抽象是 -
让我们看一个例子 -
下面的图片显示了一个GUI&#34;要添加到数据库中的客户详细信息&#34;。
通过查看图片,我们可以说我们需要一个客户类。
步骤1:我的客户类需要什么?
即
存储客户代码和客户名称的2个变量。
1将客户代码和客户名称添加到数据库中的功能。
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
现在只有ADD方法不能单独使用。
步骤-2:验证将如何运作,ADD功能如何?
我们需要数据库连接代码和验证码(额外方法)。
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();
}
}
现在无需向最终用户显示额外方法(Validate()
; CreateDBObject()
[复杂和额外方法])。用户只需要查看并了解客户代码,客户名称和添加按钮,它将添加记录。最终用户不关心如何将数据添加到数据库?
第3步:隐藏一些并不涉及最终用户互动的额外复杂方法。
因此,将那些复杂和额外的方法变为私有而不是公开(即隐藏这些方法)并从类主程序中删除obj.Validate();
obj.CreateDBObject();
我们实现了封装。
换句话说,简化最终用户界面就是封装。
所以现在完整的代码如下所示 -
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();
}
}
摘要:
步骤-1 :我的客户类需要什么?是抽象。
第3步:第3步:私有化并不涉及最终用户互动的额外且复杂的方法是封装。
<强> P.S。 - 上面的代码很难而且很快。
更新: 此链接上有一个视频来解释样本: What is the difference between Abstraction and Encapsulation
答案 4 :(得分:9)
我认为它们的概念略有不同,但通常它们是一起应用的。封装是一种隐藏调用者实现细节的技术,而抽象更多的是一种设计理念,涉及创建类似于熟悉的对象/进程的对象,以帮助理解。封装只是可用于创建抽象的众多技术之一。
例如,选择“windows”。它们不是传统意义上的窗户,它们只是屏幕上的图形方块。但将它们视为窗口是有用的。这是一种抽象。
如果“windows API”隐藏了文本或图形在窗口边界内的物理渲染方式的详细信息,那就是封装。
答案 5 :(得分:6)
面向对象的分析和设计(OOAD)实际上基于四个原则。他们是:
抽象:表示您只包含设计中所需的实体功能。因此,如果每个银行帐户都有一个开放日期,但您的申请并不需要知道帐户的开放日期,那么您只需添加 OpeningDate 字段即可您的面向对象的BankAccount类设计。 † OOAD中的抽象与编程中的抽象类无关。通过这个原则,您的实体是抽象他们实际上是什么。您将银行帐户的抽象设计为仅满足您的应用程序所需的详细程度。
继承:更像是一个技巧而非实际原则,这使您无需重写您在其他地方编写的功能。唯一的问题是,您正在编写的新代码与您想要重用的旧代码之间必须存在关系。就像你可以继承你的父母一样。财富,您可以从父类继承字段和方法。因此,获取父类所拥有的所有东西,然后在需要时添加更多内容,就是继承。不要在面向对象设计中寻找继承。继承将出现。
多态性:是继承的结果。从父级继承方法很有用,但是如果情况需要,能够修改方法是多态的。您可以在子类中使用与父类完全相同的签名实现一个方法,以便在调用时,执行子类中的方法。这是多态性。
封装:意味着将相关功能捆绑在一起,并且只能访问所需的功能。这个原则是在面向对象设计中设计类的基础,其中:
另一个简化的答案是here。
† 认为&#34; OOAD的抽象导致OOP的抽象关键字&#的人34; ...... 那就是不正确。
示例:当您使用面向对象原则在应用程序中设计大学时,您只需设计一个&#34;抽象&#34;大学尽管几乎每所大学通常都有一台自动取款机,但如果您的申请不需要,您可能不会加入这一事实。现在虽然您只设计了大学的抽象,但您不需要在课堂声明中加入 abstract 。您的大学抽象设计将成为您申请中的正常课程。
答案 6 :(得分:4)
my 2c
封装的目的是隐藏您的类用户的实现细节,例如如果你在内部保留一个std :: item的项目列表,然后决定std :: vector会更有效,你可以在没有用户关怀的情况下改变它。也就是说,与stl容器交互的方式是由于抽象,例如,列表和向量可以使用类似的方法(迭代器)以相同的方式遍历。
答案 7 :(得分:2)
在抽象的背景下,我总是提到一个例子;汽车的自动变速器与手动变速器。手动变速器隐藏了一些换档的工作方式,但您仍需要作为驾驶员进行离合和换档。自动变速箱封装了变速齿轮的所有细节,即隐藏它,因此它是更换齿轮过程的更高抽象。
答案 8 :(得分:1)
封装:隐藏实现细节(注意:数据和/或方法),使得只有外部可读/可写/可用的内容才能被他们访问,其他所有内容都是“不可触及的”。
抽象:这有时特指一种无法实例化的类型,它通常通过子类化为其他类型提供模板。更一般地说,“抽象”是指制作/拥有不太详细,不太具体,不那么精细的东西。
概念之间存在一些相似性,重叠,但记住它的最佳方式是这样的:封装更多地是关于隐藏细节,而抽象更多是关于概括细节。
答案 9 :(得分:1)
抽象和封装是令人困惑的术语,并且相互依赖。 让我们举一个例子:
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id;
}
}
当您创建Person类时,您通过将属性和函数一起编写(Id,Name,CustomName)来进行封装。将此类作为
公开给客户端时执行抽象Person p = new Person();
p.CustomName();
您的客户在此功能中对Id和Name一无所知。 现在,如果您的客户想要知道姓氏而不打扰函数调用。你可以通过在Person类中添加一个属性来进行封装。
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string LastName {get; set;}
public string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id + "last name:- " + LastName;
}
}
看,即使在课程中添加了额外的属性,您的客户也不知道您对代码做了什么。这是你抽象的地方。
答案 10 :(得分:0)
据我所知,封装本身隐藏了类的数据,只有通过setter / getters才能访问它们,如果它们必须从外部世界访问的话。
抽象是自己的课堂设计。
意味着,你如何创建你的类树,哪些方法是通用的,哪些方法是继承的,可以被覆盖,哪些属性只在私有层上,或者在受保护的方面,你如何构建你的类继承树,Do您使用final类,abtract类,接口实现。
抽象更多地放在oo设计阶段,而封装也进入了发展阶段。
答案 11 :(得分:0)
我这样想,封装正在隐藏某些事情的完成方式。这可以是一个或多个动作。
抽象与“为什么”我首先将其封装起来有关。
我基本上是在告诉客户“你不需要了解我如何处理付款和计算运费等等。我只是想让你告诉我你要'结帐'我会照顾详细信息。“
这样我通过将(抽象)概括为Checkout请求来封装细节。
我真的认为抽象和封装是一体的。
答案 12 :(得分:0)
抽象
在Java中,抽象意味着将信息隐藏到现实世界中。它建立了当事人之间的合同,告诉我们“我们应该如何利用服务”。
示例,在API开发中,只向全世界展示了服务的抽象信息,而不是实际的实现。 java中的接口可以很好地帮助实现这个概念。
接口提供各方之间的合同,例如,生产者和消费者。生产者在不知道消费者如何制造产品的情况下生产商品。但是,通过界面,Producer让所有消费者都知道什么产品可以买到。在抽象的帮助下,生产者可以将产品推销给消费者。
封装:
封装是抽象的一个层次。同一产品公司尝试屏蔽彼此生产组的信息。例如,如果一家公司生产葡萄酒和巧克力,封装有助于屏蔽每种产品彼此之间的信息。