如果我有一个具体的类 Foo
,并且我想添加一个名为 Bar
的“别名”,它扩展了 Foo
但不覆盖任何方法 - Java 会让我这样做吗?
编辑:上下文 - 目标是最终将 Foo
重命名为 Bar
,因为 Foo
的命名很糟糕;但是,Foo
被另一个项目依赖,我无法在同一提交中同时更改 Foo
和 FooCaller
。为了避免破坏 FooCaller
,我将进行三项更改:(1) 添加 Bar
,(2) 将 FooCaller
更改为 BarCaller
(相同的行为),(3) 完全删除 Foo
(当不再有 FooCaller
时)。
这里有什么问题吗?或者 Bar
的行为与 Foo
相同吗?
最佳答案
是的,Java 将允许您对非 final
进行子类化具体类只是为了给原始类起别名。
public class Foo { /* implementation */ }
public class Bar extends Foo {}
这将是最小的实现,假设Foo
中只有一个默认构造函数。 。如果 Foo
中有接受参数的构造函数,那么您必须在 Bar
中提供构造函数对于您计划调用来创建 Bar
的每个构造函数实例,例如:
public class Foo {
public Foo(String baz) { /* constructor implementation */ }
}
public class Bar extends Foo {
public Bar(String baz) { super(baz); }
}
所有非private
Foo
中的方法将由 Bar
继承.
唯一可能不起作用的地方是如果您打算使用 Bar
代替Foo
作为泛型类型参数。
例如,如果您替换 List<Foo>
与 List<Bar>
,然后是你的List
不能再容纳任何Foo
实例,或可能扩展 Foo
的任何其他类的实例.
此外,由于 Java 的泛型是不变的,所以 List<Bar>
不是 List<Foo>
的子类型,即使 Bar
是 Foo
。请参阅Is List a subclass of List? Why aren't Java's generics implicitly polymorphic?了解为什么会出现这种情况的详细信息。另外,如果您使用List<? extends Foo>
,您也许可以绕过它。这样您就可以使用 List<Foo>
或List<Bar>
,但是你将无法add
除了null
之外什么都没有.
您声明您不会在泛型中使用它,但如果您的需求有所扩展,则值得记住。
总之,是的,Java 编译器会让您这样做,但好处有限——使用 Bar
而不是Foo
作为一个别名——以及一个潜在的缺点,我认为没有理由使用这个别名过程。
关于java - 没有覆盖的子类(别名类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36699246/