Java Isn';多态性仅仅是封装的效果吗?

Java Isn';多态性仅仅是封装的效果吗?,java,Java,我一直在阅读Herbert Schildt的Java“完整参考”第8版 第二章第22页有一段 最后一个属性,多态性,清楚地反映在能力中 许多汽车制造商基本上提供了各种各样的选择 同一辆车。例如,您可以安装防抱死制动系统 或传统的制动器、动力或齿轮齿条式转向以及4-、6-、, 或8缸发动机。无论哪种方式,你都会踩下刹车 踩下踏板停止,转动方向盘改变方向,然后按下 当您想要移动时,请打开加速器。可以使用相同的接口 控制许多不同的实现 现在,在第18页封装的同一章中 此外,传输内部发生的情况不会影响对

我一直在阅读Herbert Schildt的Java“完整参考”第8版

第二章第22页有一段

最后一个属性,多态性,清楚地反映在能力中 许多汽车制造商基本上提供了各种各样的选择 同一辆车。例如,您可以安装防抱死制动系统 或传统的制动器、动力或齿轮齿条式转向以及4-、6-、, 或8缸发动机。无论哪种方式,你都会踩下刹车 踩下踏板停止,转动方向盘改变方向,然后按下 当您想要移动时,请打开加速器。可以使用相同的接口 控制许多不同的实现

现在,在第18页封装的同一章中

此外,传输内部发生的情况不会影响对象 在变速器外面。例如,换档不转动 打开前灯!因为自动变速器是封装的, 几十家汽车制造商可以以他们喜欢的任何方式实现一个。 然而,从驾驶员的角度来看,它们的工作原理是一样的。 同样的想法也适用于编程

这不是汽车制造商改变这些(防抱死)系统的唯一原因 制动系统或传统制动器、动力或齿轮齿条式制动器 转向和4缸、6缸或8缸发动机),因为 系统由这些组件封装而成,不会受到更改的影响 他们

对不起,如果我在什么地方出错了

我的问题是,


封装真的与多态性有因果关系吗?

它们是两个截然不同的概念。任何一方都可以在没有另一方的情况下存在

封装是指不公开其内部实现细节的类或模块。这是一个黑盒子。您观察输入和输出。它从输入到输出的方式应该隐藏起来,并防止潜在的外部干扰


多态性,或者更具体地说,子类型化,是一种共享公共实现细节的方法:字段、方法等。因此,您可以认为这种“共享”实际上在某种程度上破坏了封装。

简单的答案是不,多态性不是封装

多态性是父类和子类之间的“is-a”关系的名称

封装是两个类之间的“has-a”关系的名称

来自现实世界的示例: 多态性:雷克萨斯是一辆汽车。
封装:雷克萨斯有一个发动机。

通过封装,您的汽车由不同的部件组成。你可能有4个轮子,头灯等,它们都包含在“汽车”里。汽车不需要知道如何点亮,它只需要通过开关让前照灯点亮即可

使用多态性,您可以用不同的系统(实现)替换一个系统(实现),而不必注意。例如,您可以用LED前照灯更换前照灯。它们是一个完全不同的系统,但你仍然只需按下相同的开关,它们就会启动

所以我想你可以说汽车中包含的灯是封装的,能够在不改变你使用的接口的情况下将它们切换到不同的实现就是多态性


而且,作为一个概括性的概念,封装通常使用相同的代码——除非结合多态性,否则通常不会在运行时切换封装类的实现方式——多态性是封装类在运行时如何更改代码/实现以及数据。

封装和多态性都有“实现”的概念,但两者观点不同

要扩展您的书中的汽车示例,可以显示以下两个透视图。假设您有一个定义以下方法的接口:

interface Vehicle {
    public void start();
}
关于多态性:
多态性是指以统一的方式查看和使用类型的能力,而它具体可以是各种类型:

Vehicle vehicle;

vehicle = new AutomaticCar();
vehicle.start(); //runs automatic car's logic

vehicle = new ManualCar();
vehicle.start(); //runs manual car's logic
变量
vehicle
以统一的方式声明和使用,但它可以是不同的形式,这意味着它可以由不同的类型具体表示。此外,当运行
vehicle.start()
时,它是实际类提供的
run
实现。这意味着第一个
vehicle.start()
将根据自动车辆的详细信息执行,而第二个将根据手动车辆的详细信息执行。在这方面,它是多态的。请记住:多态性关注类型和特定于类型的行为

关于封装:
封装从一个类的实现细节的角度来看待其他类。为了举例说明,让我们对这两个类进行伪编码:

class AutomaticCar implements Vehicle {
    public void start() {
        this.doAutomaticMagic();
    }

    private void doAutomaticMagic() {
        //clever automatic stuff
    }
}
假设该类有一个直接客户端:

public class Main {
    public static void main(String... args) {
        AutomaticCar automaticCar = new AutomaticCar();
        automaticCar.doAutomaticMagic(); //PROBLEM HERE
    }
}
现在,我们都知道,
automaticar.doAutomaticMagic()Main
中的code>,但让我们看看原理:类
AutomaticCar
封装了其
start
方法的实现细节,这意味着它阻止了其他类与其特定逻辑直接交互。这也可以说是关于数据的


与多态性不同,多态性是关于为接口提供实现的类型,封装是关于实现细节和/或其他类无法访问的数据。多态性与类型有关,而封装则与类所持有和执行的内容有关(当然,这些概念可以扩展,例如扩展到包和模块)。但这两个方面都可以看作是“实现”细节(至少在某种程度上)

封装和多态性是两个彼此不同的概念

源于enca的理念
void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *))