Apa*_*ran 70 c# oop encapsulation abstraction
我正在准备面试,并决定刷新我的OOP概念.有数百篇文章可供使用,但似乎每篇文章都有不同的描述. 有人说
抽象是"识别具有系统变化的共同模式的过程;抽象代表了常见模式,并提供了指定使用哪种变体的方法"(Richard Gabriel).
并通过抽象类实现.
一些其他的说
抽象意味着仅向对象的客户端显示必要的细节
和
假设您的Employee类中有一个方法"CalculateSalary",它将EmployeeId作为参数,并将当前月份的员工薪水作为整数值返回.现在,如果有人想要使用该方法.他不需要关心Employee对象如何计算薪水?他唯一需要关注的是方法的名称,输入参数和结果成员的格式,
我一遍又一遍地搜索,结果似乎没有给我一个正确的答案. 现在,封装在哪里适合所有这些? 我搜索并发现了堆栈溢出问题.即使答案到问题被混淆 在这里,它说
封装是一种用作抽象的一部分的策略.封装是指对象的状态 - 对象封装其状态并将其隐藏在外部; 类的外部用户通过其方法与之交互,但无法直接访问类状态.因此,该类抽象出与其状态相关的实现细节.
而这里的另一个知名的成员说,
它们是不同的概念.
抽象是精炼对象的所有不需要/不重要的属性并且仅保留最适合您的域的特征的过程.
现在我搞砸了整个概念.我知道抽象类,继承,访问说明符和所有.我只是想知道在面试中被问及抽象和/或封装时我该如何回答.
请不要将其标记为重复.我知道有几个类似的问题.但我想避免相互矛盾的解释之间的混淆.任何人都可以提出可靠的链接吗?除非再次造成混淆,否则也欢迎链接到stackoverflow问题.:)
编辑:我需要答案,有点c#导向
小智 96
封装:使用getter和setter等隐藏数据.
抽象:使用抽象类和接口等隐藏实现.
Egi*_*Egi 48
抽象意味着仅向对象的客户端显示必要的细节
实际上那就是封装.还可以看到维基百科文章的第一部分,以免被封装和数据隐藏混淆.http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
请记住,通过简单地隐藏属性后面的所有类成员1:1根本不是封装.封装就是保护不变量和隐藏实现细节.
这里有一篇很好的文章. http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/ 还会查看该文章中链接的文章.
类,属性和访问修饰符是在c#中提供封装的工具.
你做封装以降低复杂性.
抽象是"识别具有系统变化的共同模式的过程;抽象代表了常见模式,并提供了指定使用哪种变体的方法"(Richard Gabriel).
是的,这是一个很好的抽象定义.
它们是不同的概念.抽象是精炼对象的所有不需要/不重要的属性并且仅保留最适合您的域的特征的过程.
是的,它们是不同的概念.请记住,抽象实际上只是使对象适合您的域.它是为了使对象一般适用于域!
如果您遇到实际问题并提供特定解决方案,则可以使用抽象来形式化更通用的解决方案,该解决方案还可以解决具有相同常见模式的更多问题.这样,您可以增加组件的可重用性,或者使用为同一域甚至不同域制作的其他程序员制作的组件.
很好的例子是.net框架提供的类,例如list或collection.这些是非常抽象的类,几乎可以在任何地方和许多领域中使用.想象一下,如果.net只实现了一个EmployeeList类和一个只能保存具有特定属性的员工和公司列表的CompanyList.在很多情况下,这样的课程将毫无用处.如果你必须重新实现CarList的整个功能,那将是多么痛苦.所以"清单"是从员工,公司和汽车中抽离出来的.List本身是一个抽象的概念,可以由它自己的类实现.
接口,抽象类或继承和多态是在c#中提供抽象的工具.
你做抽象,以提供可重用性.
小智 26
我将尝试以一种简单的方式演示Encapsulation和Abstraction.让我们看看..
封装是 -
封装实现抽象.
和抽象是 -
让我们看一个例子 -
下图显示了"要添加到数据库中的客户详细信息"的GUI.

通过查看图像,我们可以说我们需要一个客户类.
第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:私有化不涉及最终用户交互的额外且复杂的方法是封装.
PS - 上面的代码很难,很快.
更新:此链接上有一个视频来解释样本: 抽象和封装之间有什么区别
小智 9
我认为它们的概念略有不同,但通常它们是一起应用的.封装是一种隐藏调用者实现细节的技术,而抽象更多的是一种设计理念,涉及创建类似于熟悉的对象/进程的对象,以帮助理解.封装只是可用于创建抽象的众多技术之一.
例如,取"窗口".它们不是传统意义上的窗户,它们只是屏幕上的图形方块.但将它们视为窗口是有用的.这是一种抽象.
如果"windows API"隐藏了文本或图形在窗口边界内的物理渲染方式的详细信息,那就是封装.
面向对象的分析和设计(OOAD)实际上基于四个原则.他们是:
抽象:表示您只包含设计中所需的实体的那些功能.因此,如果每个银行帐户都有一个开放日期,但您的应用程序不需要知道帐户的开放日期,那么您只是不在BankAccount类的面向对象设计中添加OpeningDate字段.† OOAD中的抽象与编程中的抽象类无关.通过这个原则,您的实体是他们实际的抽象.您将银行帐户的抽象设计为仅满足应用程序所需的详细程度.
继承:更像是一种技巧,而不是一种实际原则,它可以帮助您重新编写您在其他地方编写的功能.唯一的问题是,您正在编写的新代码与您想要重用的旧代码之间必须存在关系.就像您可以继承父母的财富一样,您可以从父类继承字段和方法.因此,获取父类所拥有的所有东西,然后在需要时添加更多内容,就是继承.不要在面向对象设计中寻找继承.继承将呈现出来.
多态性:是遗传的结果.从父级继承方法很有用,但是如果情况需要,能够修改方法是多态的.您可以在子类中实现一个方法,该方法具有与父类完全相同的签名,以便在调用时,执行子类中的方法.这是多态性.
封装:意味着将相关功能捆绑在一起,只允许访问所需的功能.这个原则是在面向对象设计中设计类的基础,其中:
另一个简化的答案在这里.
†认为"OOAD的抽象导致OOP的抽象关键字"的人......嗯,这根本就不正确.
示例:当您使用面向对象原则在应用程序中设计大学时,您只需设计一个大学的"抽象".尽管几乎每所大学通常都有一台自动取款机,但如果您的申请不需要,您可能不会加入这一事实.现在,虽然您只设计了大学的抽象,但您不需要提交abstract课程声明.您的大学抽象设计将成为您申请中的正常课程.