我很困惑为什么或者什么时候要使用向下转换、向上转换和多态性。
请告诉我我是对还是错。这将是一个很大的帮助。
如果我们说这个Gift gift = new Pen();
,我们不仅可以利用多态性的使用(如果子类有任何覆盖的方法),而且我们将在堆中只创建一个对象,就像如果进一步如果我们说要访问Pen类方法,我们可以说Pen pen = (Pen) gift;
这一行可以用来访问超类方法以及它自己的方法。
但我的观点是,这里我们不必在堆中创建一个新对象,而是可以向下转换。
所以,如果我们说像Gift gift = new Gift()
,然后我们想使用Pen类方法,我们需要在堆中再次创建对象,如Pen pen = new Pen()
。
基本上,我们可以只创建一个对象,然后向下转换它,而不是在堆中创建两个对象。这不仅有助于编写高效的代码,而且可以在维护良好的代码中利用多态性。
1条答案
按热度按时间mv1qrgav1#
您正在解决两个相关的问题:使用哪个接口访问对象(为此,我将
class
也视为一种接口)。如果你事先知道你需要访问
Pen
方法,你应该首先将变量输入为Pen
。但另一方面,你应该通过它们的接口来引用对象(来自约书亚Bloch的Effective Java),所以如果你不需要访问Pen
方法,就不要通过那个类来访问它。您的第二个问题是关于创建访问类方法的对象。但这种方法不是面向对象编程的目的:你创建了一个类,这样你就只能通过类的方法来访问内部数据(在对象中)。因此,首先创建一个
Gift
示例,然后再为更多的方法创建一个Pen
示例的想法并不理想,因为Pen
的方法也需要更多的数据,这些数据必须在某个时间点初始化(通常在构建Pen
时)。如果您只有一个可用的Gift
示例,那么您从哪里获得这些数据?如果您首先拥有数据,为什么不立即创建
Pen
?您还可以为
Pen
提供一个工厂方法,该方法从Gift
示例加上Pen
示例所需的所有额外数据创建一个新示例。这并不总是一个理想的解决方案,所以你的问题的答案既不是是也不是,而是:那要看情况。根据您想要解决的实际问题,选择的最佳解决方案可能会有所不同,因此如果您有实际问题要解决,您应该将其添加到您的问题中以获得更多建议,或者添加另一个问题。
更新:(根据OP要求)
你能告诉我为什么要用
Gift gift = new Pen()
吗?由于你没有提供任何周围的代码,我不能说出确切的原因,但在上面的链接中,你可以找到一个解释为什么你应该使用“最不具体”的接口。
为此,我们将类也视为接口(具有实现)。方法也是一种与接口实现者的契约。因此,如果您使用最不特定的接口,则不依赖于实际的实现,而是依赖于该接口的方法的契约。因此,如果有必要,您可以在以后轻松地更改实现。
一个很好的和非常常用的例子是例如。
java.util.List
接口你只想知道(基本上)你是在一个有序的集合上操作。作为接口的“用户”,你不关心列表是如何排序的,或者它是否由数组或链表支持(或从数据库延迟加载等)。如果你使用java.util.ArrayList
,你总是必须将所有东西加载到一个数组中,或者至少假装你这样做了--如果你从那个类继承并覆盖方法,这对于代码维护者来说将是超级复杂的。为什么我们使用Downcasting?
一个很好的用例(但可能不是唯一的)是:通常,您希望使用的现有代码需要特定的
class
或interface
对象。但是现有的类不符合您的需要,所以您继承或实现现有的和预期的内容。您创建了一个更具体的实现。但是您不能或不想更改现有的代码,因此您可以将实现向下转换为所需的任何内容。通常,继承的类甚至不实现新方法,而只是重写一些现有的方法。我想了解Java中的向下转换,多态性的概念(为什么使用和何时使用它)
多态性并不总是有帮助的,过去的经验表明它也可能是一种负担,特别是对于在较长时间内维护和扩展的代码,以及对于设计糟糕的新代码。很难给予一个一般性的建议,但你试着去了解它是很好的。
我建议你至少阅读《Effective Java》一书中的“Favor Composition over Inheritance”一章,但可以推荐整本书。它不仅对Java开发人员有用,而且对一般的OOP都有用(示例和特定章节仅适用于Java)。