【问题标题】:Cast an object of super class to a sub class - down casting将超类的对象转换为子类 - 向下转换
【发布时间】:2012-01-06 12:53:35
【问题描述】:

我知道转换实际上只能从子类到超类(向上转换),但这个例子说明了我想做的事情。

Class Super {}
Class Sub extends Super {}

Super super = new Super();
Sub sub = (Sub)super;

我相信这被称为“向下”强制转换,因此是不允许的......

在给定 Super 类型的对象的情况下,创建 Sub 类型的对象的最佳方法是什么。

编辑:

这就是问题 - 将动物转换为猫的最佳方法是什么。

答案?从基本类型的动物开始,然后将属性复制到猫。添加毛皮和尾巴等。基本上是一个复制构造函数。这是正确的答案(还是一个好的答案)?

另一个编辑:

我认为我的问题很清楚,但可能太笼统了。要求做某事的“最佳”方式往往会给出很多不同的回应。我意识到最好的方法在不同的情况下可能会有所不同。

我不是在寻找有关 Java 或 OO 基础知识的教程。只是征求意见,以便我可以使用最佳实践来解决这个问题。

【问题讨论】:

  • 从你的问题来看,根本不清楚你知道什么,不知道什么。因此,当人们回答 我相信这被称为“向下”转换,这是不允许的部分而不是(非常模糊的)“实际问题”时,不要感到惊讶。是的,复制构造函数就是这样。不,它不是唯一的,工厂方法就可以了。不,这不是最好的——我们不知道你有什么限制和假设。
  • @alf 我可以说我的问题对你来说很清楚 - 你能提供更多关于如何表达问题的建议吗?我希望能够提出一个可以为网站增加价值并获得有价值的回复的问题,但在这种情况下,我似乎有点失败了......被误解了,被否决了,我最终有点沮丧。
  • 嗯,我可以看到投票的细分,并且没有投票反对。也没有投票,但这不是重点,是吗?标准的 HOWTO 将是 catb.org/~esr/faqs/smart-questions.html — 这很好而且很中肯。关于当前的问题,我想说把责任归咎于那些试图提供帮助的人并不是一个很有成效的想法。当您需要两次编辑时,说您的问题很清楚,这几乎是罪魁祸首,以至于只有少数人会注意到差异。在此处添加“感谢您实际阅读我的问题”,您将获得相当大的攻击性。善待。修正错误。不要责备
  • ...而且,是的,“我可以说我的问题对你来说很清楚”——如果有人假装知道他们的想法,人们通常会生气。我确实。在真正的一对一聊天中可能会很好,但在公共场合就不行。
  • 郑重声明,我并没有试图(或无意)责备,而是试图反驳和澄清。

标签: java oop


【解决方案1】:

CatAnimal

如果我给你一只动物(不一定是猫),你会如何把它变成一只猫?

编辑:

几乎可以做任何事情。大多数时候,你不应该。我相信更好的设计将消除向下转换的需要。但是你可以:

  • Super 中有一个以Sub 作为参数的构造函数。

  • 实现Super 的工厂,并拥有一个以Sub 作为参数的方法。

我建议您扩展您的问题,准确告诉我们您需要什么,因为我真的认为存在更优雅的解决方案。

【讨论】:

  • @Matthew - 只是因为有办法做到这一点,并不意味着你应该这样做。你最好不要静态你想要达到的目标。向下转换很少是答案,我 99% 确定在您的情况下存在更好的解决方案。
  • 感谢您的回答。我可能只是做一些研究,找出在这种情况下我可能还需要什么,然后提出一个更详细和具体的问题。这肯定会满足我现在所需要的,因为我只是要求一个一般性的答案,但我知道我会遇到以后需要更具体的东西的情况。
【解决方案2】:

只有当实际对象是“Sub”类型时,您才能向下转换。 例如:

Super subAsSuper = new Sub();
Sub sub = (Sub)subAsSuper

你的方法行不通,因为 super 不是 sub 的子类。所以你会得到一个运行时错误。

【讨论】:

    【解决方案3】:

    您可以向Sub 类添加一个构造函数,该类将Super 对象作为参数。

    【讨论】:

      【解决方案4】:

      编辑:从你的问题来看,你知道什么和你不知道什么都不是很清楚。所以当人们回答这个问题时不要感到惊讶

      我相信这被称为不允许的“向下”强制转换

      部分而不是(非常模糊的)“实际问题”。

      是的,复制构造函数就是这样。

      不,它不是唯一的,工厂方法就可以了。

      不,这不是最好的——我们不知道你有什么限制和假设。


      旧版本: 转换可以通过任何一种方式进行,通常不需要向上转换(除非您需要选择特定的重载方法)。

      除了创建一个方法来根据给定对象的数据构造一个新对象之外,通常没有办法在给定 Super 类型的对象的情况下创建 Sub 类型的对象

      为了进行转换,您必须确保您要转换的对象实际上是您转换到的类型(或其子类型)。

      【讨论】:

      • 我明确表示我知道允许向上转换,但我知道不允许向下转换。我通过询问在给定这些信息的情况下执行 x 的最佳方法是什么来完成它。我现在有点修辞——我怎么不清楚?
      • @Matthew 好吧,向下转换允许的。不清楚您是否知道“向下转换”是什么,因为它确实是允许的,所以要么是通常的“那个与哪个”问题,要么是缺乏理解。根据以往的经验,许多人认为缺乏理解。
      • 我想我可以说“我知道在这种特殊情况下不允许向下转换”...“。”
      • @Matthew 那会让事情变得更容易,真的。除了放弃“我相信它被称为”之外——间接通常意味着缺乏信心,所以每个人都急于告诉你什么是垂头丧气:)
      【解决方案5】:

      记住这个想法 -

      Class Super {}
      Class Sub {
          public Super super = new Super();
      }
      
      Sub sub = new Sub();
      sub.super = super;
      

      我在这里做了一个非常基本的例子,但是你可以用它去任何你想去的地方,你可以让它像继承一样工作。并且它不会返回任何错误。

      【讨论】:

        猜你喜欢
        • 2013-09-03
        • 1970-01-01
        • 2012-07-22
        • 2014-03-09
        • 1970-01-01
        • 1970-01-01
        • 2022-09-29
        • 1970-01-01
        • 2021-01-23
        相关资源
        最近更新 更多