没有覆盖的子类(别名类)

时间:2016-04-18 16:15:20

标签: java subclass

如果我有一个具体的类Foo,并且我想添加一个名为Bar的“别名”,它扩展Foo但不覆盖任何方法 - 请Java让我这样做?

修改:上下文 - 目标是最终将Foo重命名为Bar,因为Foo命名不佳;但是,Foo依赖于另一个项目,我无法在同一次提交中更改FooFooCaller。为避免中断FooCaller,我将进行三项更改:(1)添加Bar,(2)将FooCaller更改为BarCaller(相同行为),(3)删除完全Foo(当没有FooCaller s时)。

此处是否存在问题,或Bar的行为是否与Foo完全相同?

2 个答案:

答案 0 :(得分:1)

只要您使用适当的可见性,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 {

}

答案 1 :(得分:1)

是的,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是{ {1}}。有关案例原因的详细信息,请参阅Is List a subclass of List? Why aren't Java's generics implicitly polymorphic?。此外,如果您使用Foo,则可以绕过它,以便您可以使用List<? extends Foo>List<Foo>,但之后您将无法{{}除了List<Bar>之外的其他任何内容。

您声明您不会在泛型中使用它,但如果您的要求得到扩展,请记住这一点。

总之,是的,Java编译器会允许你这样做,但有一个有限的优势 - 使用add而不是null作为别名 - 并且潜在的缺点,我看不到使用此别名过程的原因。