理解封装和抽象的简单方法

学习 OOP 概念,特别是对深入理解抽象和封装感兴趣。

已经看过下面了

抽象 VS 信息隐藏 VS 封装

抽象和封装的区别?

我发现,如果没有一个真实而简单的示例类/代码片段,就很难理解这些概念。

我的一个同事说抽象不过是创造抽象 用作用域保护其成员变量的 叫做封装。

有没有一个简单的方法可以让我理解并帮助别人明白他们到底是什么,而不是重复下面的内容?

抽象和封装是互补的概念: 抽象 关注对象的可观察行为... 封装 重点放在导致这种行为的实现上..。 封装通常是通过信息隐藏来实现的 是隐藏所有对象的秘密的过程 有助于它的本质特征。

208687 次浏览

抽象是这样一个过程,在这个过程中,您丢弃了计划在设计中捕获/表示的实体中不必要的细节,只保留与您的领域相关的实体的属性。
例如: 代表汽车,你会保留,例如型号和价格,当前位置和当前速度,忽略颜色和座位数量等。

封装是在一个抽象单元(即类)中操作属性和操作的“绑定”。
因此,汽车将有 accelarate stop操纵位置和当前速度等。

抽象 隐藏信息或者只向客户机提供必要的细节。

例如汽车刹车——你只知道踩下踏板会让车停下来,但是你不需要知道它内部是如何工作的。

抽象优势 明天如果制动器实现从鼓式制动器改为盘式制动器,作为客户,你不需要改变(即你的代码不会改变)

封装 将数据和行为绑定在一个单元中。 此外,它还是一种语言机制,用于限制对某些组件的访问(这可以通过诸如 private、 protected 等访问修饰符来实现)

例如,同学们具有属性(即数据)和行为(即对该数据进行操作的方法)

public abstract class Draw {
public abstract void drawShape(); // this is abstraction.  Implementation detail need not to be known.
// so we are providing only necessary detail by giving drawShape(); No implementation. Subclass will give detail.




private int type;    // this variable cannot be set outside of the class. Because it is private.
// Binding private instance variable with public setter/getter method is encapsulation


public int getType() {
return type;
}


public void setType(int type) {  // this is encapsulation. Protecting any value to be set.
if (type >= 0 && type <= 3) {
this.type = type;
} else {
System.out.println("We have four types only. Enter value between 0 to 4");
try {
throw new MyInvalidValueSetException();
} catch (MyInvalidValueSetException e) {
e.printStackTrace();
}


}
}
}

Abstraction与实现细节未知的方法有关,这是一种实现隐藏。
ABc0与实例变量绑定有关,是一种数据隐藏方法。

一个使用 C # 的例子

//abstraction - exposing only the relevant behavior
public interface IMakeFire
{
void LightFire();
}


//encapsulation - hiding things that the rest of the world doesn't need to see
public class Caveman: IMakeFire
{
//exposed information
public string Name {get;set;}


// exposed but unchangeable information
public byte Age {get; private set;}


//internal i.e hidden object detail. This can be changed freely, the outside world
// doesn't know about it
private bool CanMakeFire()
{
return Age >7;
}


//implementation of a relevant feature
public void LightFire()
{
if (!CanMakeFire())
{
throw new UnableToLightFireException("Too young");
}
GatherWood();
GetFireStone();
//light the fire


}


private GatherWood() {};
private GetFireStone();
}


public class PersonWithMatch:IMakeFire
{
//implementation
}

任何穴居人都能生火,因为它实现了 IMakeFire的“功能”。拥有一组火灾制造者(列表) ,这意味着穴居人和人与匹配都是有效的选择。

这意味着

  //this method (and class) isn't coupled to a Caveman or a PersonWithMatch
// it can work with ANY object implementing IMakeFire
public void FireStarter(IMakeFire starter)
{
starter.LightFire();
}

因此,您可以有许多实现者,它们具有大量的细节(属性)和行为(方法) ,但是在这个场景中,重要的是它们生火的能力。这是 抽象。

由于生火需要一些步骤(GetWood 等) ,这些步骤是隐藏在视图之外的,因为它们是类的内部关注点。穴居人还有许多其他的公共行为可以被外界称为。但是一些细节总是会被隐藏起来,因为它们与内部工作有关。它们是私有的,只存在于对象中,永远不会暴露。这是 封装

抽象化 访问任何类的数据成员和成员函数被简单地称为抽象化... ..。

封装: 绑定变量和函数或者1可以说数据成员或成员函数在一个单元中被称为数据封装..。

抽象 是一个只显示“相关”数据并向用户“隐藏”对象的不必要细节的过程。考虑一下你的手机,你只需要知道发送信息或打电话需要按哪些按钮,当你按下一个按钮时会发生什么,你的信息是如何发送的,你的电话是如何连接的,这些都是从用户那里抽象出来的。

封装 是将数据和函数组合成单个单元的过程,称为 class。在封装中,不直接访问数据; 通过类中存在的函数访问数据。简单地说,类的属性保持为私有,并且提供了公共 getter 和 setter 方法来操作这些属性。因此,封装使数据隐藏的概念成为可能。

enter image description here

抽象化 : DA 只是简单地过滤了具体的项目。通过类,我们可以实现纯粹的抽象,因为在创建类之前,我们只能考虑关于类的相关信息。

封装 : 这是一种机制,我们通过它来保护数据不受外部的影响。

抽象是一个广义术语,即封装是抽象的子集。

抽象是一种管理复杂系统的强有力的方法,通过定义良好的对象及其层次分类来管理抽象。

例如, 汽车本身是一个定义良好的对象,它由几个其他较小的对象组成,如齿轮系统、转向机构、发动机,它们也有自己的子系统。但对于人类来说,汽车是一个单一的对象,它可以通过其子系统的帮助来管理,即使它们的内部细节是未知的。 礼貌


封装: 将数据成员和方法封装成单个单元(即类)称为封装。

封装就像封装在胶囊中。它将与对象相关的相关操作和数据封装到该对象中。

封装就像你的书包,你可以把你的笔、书等放在里面。这意味着这是封装成员和函数的属性。

class Bag{
book;
pen;
ReadBook();
}

封装意味着隐藏对象的内部细节,即对象如何做某事。

封装阻止客户端看到它的内部视图,即实现抽象行为的内部视图。

封装是一种用于保护对象中的信息不受其他对象影响的技术。

为安全起见隐藏数据,例如将变量设置为私有,并公开属性以访问将为公共的私有数据。

因此,当您访问该属性时,您可以验证数据并设置它。 礼貌

封装可以被认为是包装纸用来绑定数据和功能一起作为一个单一的单位,保护它免受各种外部污垢(我的意思是外部功能)。

抽象涉及到缺乏细节和使用简单的接口来控制复杂的系统。

例如,我们可以通过按一个按钮来点亮一个灯泡,而不用担心底层的电气工程(抽象)。

然而,你不能以任何其他方式点亮灯泡。(封装)

我将用一个真实世界的例子来解释抽象。假设在你家里有一个电源插头,许多设备可以连接到同一个插头,但是插头永远不会知道它连接到哪个设备,换句话说,设备的细节被抽象(隐藏)到插头上。

想想看,如果我们把一个设备直接连接到没有插头的电线上会怎么样?比如说把灯泡直接连到电线上,这样电线就知道它连到哪个设备上了,当我们需要更换灯泡的时候,我们就必须把灯泡的电线连接去掉,这意味着灯泡和电线是紧密连接在一起的。换句话说,灯泡和电线知道它所连接的细节,而不是抽象的。

在面向对象的世界中,抽象的工作方式完全相同。使用其他类的函数/属性的类不需要知道它使用的是哪些类的函数/属性,所有东西都应该用接口/抽象类进行抽象。

让我来编写相同的示例。这里我有一个类“ ElectricPlug”,它正在运行一个设备。但是“ ElectricPlug”类并不知道它运行的是哪个设备。它可以是实现接口“ IDdevice”的任何类,这意味着“ RunDevice”的实现是从“ ElectricPlug”抽象出来的。这是完整的示例代码,

class Program
{
static void Main(string[] args)
{
ElectricPlug electricPlug = new ElectricPlug(new Bulb());
}
}


public class ElectricPlug
{
private readonly IDevice _device;
public ElectricPlug(IDevice device)
{
_device = device;
}


public void Run()
{
_device.Rundevice();
}
}




public interface IDevice
{
void Rundevice();
}




public class Bulb : IDevice
{
public void Rundevice()
{
Console.WriteLine("Switched on bulb");
}
}

封装就像它听起来的那样,是将盒子放在某物周围以保护其内容的一种方法。抽象是提取某种东西的功能属性,这样您就可以只使用您提取的东西来执行操作,而不需要知道内部工作原理。

当我们说两种物质是液体时,我们用“液体”作为我们选择讨论的物质性质的抽象。这种抽象告诉我们,我们可以用这些物质做些什么,因为我们以前对液体有过经验。

抽象也与层次结构无关。你可以有另一个抽象,比如“金属”,它以不同的方式提取物质的特性。

抽象会忘记细节,所以如果你在使用一个特定的抽象,你不应该问抽象没有赋予的底层物质的属性。如果你把牛奶和水混合在一起,你会很难问你有多少牛奶。

函数是对具有映射概念的事物的抽象,也就是说,您可以在其内部内容上运行一个函数,将内部位转换为其他任何内容。外在的东西保持不变。

这个方法有用的地方在于,如果你有一个在 List 上工作的函数,你意识到你只依赖于 map 接口,你可以取而代之依赖于 Functor,然后你的函数可以处理流、承诺、也许、元组,以及其他任何共享抽象的东西。

像 Haskell 这样的函数式语言具有非常强大的抽象能力,使得极端的代码重用变得可行。

抽象就像使用计算机。

除了用图形用户界面(图形用户界面)和外部硬件(例如屏幕)看到的东西,你完全不知道它发生了什么。那些漂亮的颜色。您只是作为一个普通消费者提供了与您相关的细节。

封装 隐藏不相关的细节的实际行为。

您使用您的计算机,但是您看不到它的 CPU (中央处理器)是什么样子的(除非您尝试闯入它)。它隐藏(或封装)在所有的铬和塑料后面。

在面向对象编程(面向对象程序设计)语言的环境中,通常会有这样的设置:

CLASS {
METHOD {
*the actual code*
}
}

“封装”的一个例子是拥有一个普通用户看不到的方法(私有)。“抽象”是经常使用方法的用户,他们可以(公共)为了使用私有的。

抽象 是为了简化接口而隐藏细节 < em > 的一种方法。

因此,以汽车为例,汽车中的所有控件都是抽象的。这使您可以操作一辆车,而不理解的基本细节的转向,加速,或减速系统。

很好抽象广泛地标准化了一个接口,跨越类似问题的多个实例。很好抽象可以改变一个行业。

现代的方向盘、刹车踏板和油门踏板都是非常抽象的例子。汽车转向起初看起来更像自行车转向。刹车和油门都是手动操作的。但是我们今天使用的抽象是如此强大,它们席卷了整个行业。

--

封装 是一种隐藏细节 < em > 的方法,以保护它们不受外部操作的影响。

封装可以防止驾驶员操纵汽车的行驶方式ーー从转向、悬挂和制动的刚度,到油门和变速器的特性。大多数汽车都不提供改变这些事情的接口。这种封装确保车辆将按照制造商的意图运行。

有些汽车提供少量的驾驶模式ーー比如豪华、运动和经济ーー这使得驾驶者可以同时改变多种驾驶模式。通过提供驾驶模式,制造商允许驾驶员在一定程度上控制驾驶体验,同时防止他们选择使车辆不那么愉快或不安全的综合属性。通过这种方式,制造商隐藏了细节,以防止不安全的操作。这是封装。

抽象是向用户显示必要的信息,封装向用户隐藏不需要的数据(产品来自用户)。

封装实现抽象。

抽象是封装实际实现它的过程。 对于 Eg. 添加用户逻辑-> ,我们需要验证用户,创建 DB 连接并插入 User。所以用户不知道首先需要调用验证函数,创建数据库连接,然后在数据库中插入值。他只调用 AddUser 函数,该函数用 in 调用内部的所有逻辑,这只是封装(将特性分组并隐藏方法)。

封装: 我认为这在很大程度上与如何将事物绑定到一个实体而不是隐藏有关。如果你选择隐藏什么,你可以。

抽象: 抽象与隐藏事物有很大关系,可能存在不同的抽象层次。例如,在函数抽象中,我们可能会说能够将项目添加到列表中是很重要的,但是如何实现这一点的细节是没有意义的,应该隐藏起来。使用抽象化,我们可以说一个列表是一个我们可以存储信息的地方,但是这个列表实际上是如何实现的(例如,作为一个数组或者一系列链接的位置)并不重要,应该被隐藏起来。

参考文献

用简单的语言来说,抽象可以说是一种方法,它使用户远离复杂的细节或某些系统的详细工作。您还可以假定它是在设计和接口级别上解决任何问题的一种简单方法。

可以说,抽象的唯一目的是隐藏可能使用户感到困惑的细节。因此,为了简化目的,我们可以使用抽象。抽象也是一个面向对象程序设计的概念。它隐藏了实际的数据,只显示必要的信息。例如,在 ATM 机器中,您不知道它在内部是如何工作的。只有您关心使用 ATM 接口。因此,可以将其视为一种抽象过程。

封装 -封装也是面向对象程序设计的一部分。在这里,您所要做的就是将数据和代码封装在一起,以便它们能够作为一个单元工作。它在实现级别工作。它还改进了应用程序的维护。

封装主要关注保存信息的过程。在这里,您必须保护数据不被外部使用。