没有覆盖的 Subclass(别名 class)

Subclass with no overrides (alias class)

如果我有一个具体的 class Foo,我想添加一个名为 Bar 的 "alias" 扩展 Foo 但不覆盖任何方法 - Java 让我这样做吗?

编辑:上下文 - 目标是最终将 Foo 重命名为 Bar,因为 Foo 的命名很糟糕;但是,Foo 依赖于另一个项目,我无法在同一提交中同时更改 FooFooCaller。为避免破坏 FooCaller,我将进行三项更改:(1) 添加 Bar,(2) 将 FooCaller 更改为 BarCaller(相同行为),(3) 删除总共 Foo(当没有更多 FooCaller 时)。

这里有什么陷阱吗,或者 Bar 的行为是否与 Foo 相同?

只要您使用适当的可见性,Bar 就会像 Foo 一样工作。 Foo 中的私有方法和属性将无法被 Bar 访问,受保护的方法和属性将被假定为 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 可以让你子class 一个非final 具体的 class 只是为了给原来的 class 添加别名。

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 作为泛型类型参数。

例如,如果您将 List<Foo> 替换为 List<Bar>,那么您的 List 将无法再容纳任何 Foo 个实例,或任何其他 class 可能会扩展 Foo.

此外,因为 Java 的泛型是不变的,所以 List<Bar> 不是 List<Foo> 的子类型,即使 List<Foo> =15=] 是一个 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 作为别名——以及潜在的缺点,我认为没有理由使用这个别名过程。