Java 不带重写的子类(别名类)
如果我有一个具体的类Java 不带重写的子类(别名类),java,subclass,Java,Subclass,如果我有一个具体的类Foo,我想添加一个名为Bar的“别名”,它扩展Foo,但不覆盖任何方法,Java会允许我这样做吗 编辑:上下文-目标是最终将Foo重命名为Bar,因为Foo的名称很差;但是,Foo依赖于另一个项目,我不能在同一个提交中同时更改Foo和FooCaller。为了避免破坏FooCaller,我将做三个更改:(1)添加Bar,(2)将FooCaller更改为BarCaller(相同行为),(3)完全删除Foo(当不再有FooCaller时) 这里是否有陷阱,或者Bar的行为是否与F
Foo
,我想添加一个名为Bar
的“别名”,它扩展Foo
,但不覆盖任何方法,Java会允许我这样做吗
编辑:上下文-目标是最终将Foo
重命名为Bar
,因为Foo
的名称很差;但是,Foo
依赖于另一个项目,我不能在同一个提交中同时更改Foo
和FooCaller
。为了避免破坏FooCaller
,我将做三个更改:(1)添加Bar
,(2)将FooCaller
更改为BarCaller
(相同行为),(3)完全删除Foo
(当不再有FooCaller
时)
这里是否有陷阱,或者
Bar
的行为是否与Foo
相同?只要使用适当的可见性,Bar的行为将与Foo相同。Bar将无法访问Foo中的私有方法和属性,受保护的方法和属性将假定为Bar中的私有方法和属性
下面的示例将向控制台输出“Foo”
class Example
{
public static void main (String[] args)
{
Bar b = new Bar();
System.out.println(b.getName());
}
}
class Foo {
protected String name; // Will be private in Bar
public Foo() {
this.name = "Foo";
}
public String getName() {
return this.name;
}
}
class Bar extends Foo {
}
是的,Java允许您对非
final
concrete类进行子类化,只是为了给原始类添加别名
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); }
}
Foo
中的所有非private
方法将由Bar
继承
它可能不起作用的唯一地方是,如果您打算使用Bar
代替Foo
作为泛型类型参数
例如,如果将列表
替换为列表
,则您的列表
不能再包含任何Foo
实例,或可能扩展Foo
的任何其他类的实例
此外,由于Java的泛型是不变的,
列表
不是列表
的子类型,即使条
是Foo
。有关原因的详细信息,请参阅。此外,如果您使用list,您可能可以绕过它。我认为您需要注意构造函数,但是没有义务重写父类的任何方法,除非父类是抽象的。您是否将Foo
或Bar
用作泛型类型参数,例如,列表
?@targetman不只是一个渐进重构的别名,Foo
和Bar
之间不应该有任何功能上的区别。但是,我想您不会介意它可能导致的设计混乱(如果它不添加任何附加功能,为什么Bar
extendFoo
)。此外,依赖getClass()的代码可能会表现不同。泛型问题是一个很好的观点。在我的特殊情况下,目标是最终将Foo重命名为Bar,因为Foo的名称很差;然而,Foo依赖于另一个项目,我不能在同一个提交中同时更改Foo和FooCaller。为了避免破坏FooCaller,我将做三个更改:(1)添加Bar,(2)将FooCaller更改为BarCaller(相同的行为),(3)完全删除Foo。@mfrankli这是一个很好的上下文,可以包含在您的问题中。我建议将Foo重命名为Bar,然后创建一个新的Foo来扩展Bar以实现向后兼容性。