封装这个非常理论的概念很容易记住——隐藏数据——因为它在实践中被使用,getter、setter、私有方法和变量等。在实践中如何使用多态性?我确定我一直都在使用它,但我不知道。也许当我发现时,我会很快记住。
ED:我是否正确理解多态性是方法的覆盖/重载(仅此而已?)?
封装这个非常理论的概念很容易记住——隐藏数据——因为它在实践中被使用,getter、setter、私有方法和变量等。在实践中如何使用多态性?我确定我一直都在使用它,但我不知道。也许当我发现时,我会很快记住。
ED:我是否正确理解多态性是方法的覆盖/重载(仅此而已?)?
多态性是对象在运行时改变其行为的属性。在编译时,方法调用被重定向到包含它的类,在运行时,被重定向到创建它的类。您经常使用父类和接口来确定变量的类型,但创建子类对象并分配对该变量的引用。
例如像这样:
该变量只能调用父类中定义的方法,但如果这些方法在子类中被覆盖,那么对该方法的调用会被转发到该方法被覆盖的子类中。
并且由于父类可以有许多子类,这些子类具有相同签名的虚方法,在父类中被覆盖,并有自己的实现,您可以将这些子类中的任何一个对象分配给一个变量,然后将相应的子类方法将被调用,尽管在父类中这个方法有它自己的实现。
实际上,接口和抽象方法是纯虚拟的,因为它们没有实现,并且在代码中使用它们会导致多态性,因为它们的实现是在子类中。
在实践中,我们经常扩展类并用另一个替换原始实现并希望它工作。因为它对我们的对象一无所知,所以它调用它的方法而不知道实际执行了什么。当您需要更改对象的行为时,这种方法通常用于测试,因为您使用运行时存根并将它们替换为真实对象。
假设我们正在编写一个报告生成器。我们有一个特定的类,它将其中一个报告作为输入并构建它。我们的报告是不同的,但总的来说,它们的构建顺序是相同的:
我们的类从报表类
ReportBuilder请求数据,通过从报表类请求模板将其放置在 Excel 中,然后保存结果。现在我们可以创建不同的报表类,它们有自己的模板和自己的数据收集逻辑:
之后我们可以这样做:
这样:
ReportBuidler:它负责使用 Excel,保存和发布报表。createReport()确保相应类collectData()的方法template()也将在其中被调用。分为覆盖和重载 覆盖是在抽象类/接口中声明抽象方法,然后在第一个后继/实现类中覆盖它们。重载是当有相同的返回类型和名称的方法,但输入参数不同时,它们被认为是不同的方法和工作,因此方法被重载。
没有错。这就像一个必要条件。是的,在 Java 中,方法重载是多态的——也就是说,在 Java 中,所有方法都是多态的,但假设在 C++ 中,情况并非如此。方法重载与多态不同。在C++中,还有一个关键字
virtual,就是方法必须也被指定为virtual,才具有多态性。多态最简单的例子就是所有程序员都在不知不觉中使用的——方法
Object.toString(),例如:两种情况下的输出都是相同的。如果没有多态性,第一种情况的输出将是:
在第二种情况下:
即对象的哈希值
但是由于多态性,输出是相同的。