2

我有一个简单的继承层次结构和一个单一的接口。考虑将由 B 类扩展的 A 类。我希望这两个类都实现接口 I 并且 A 类是抽象的。在java中,我大致有以下内容:

public interface I {
    public double foobar();
    public void print();
}

public abstract class A implements I {
    @Override public double foobar() { /*return foo*/}
    @Override public void print() {
        System.out.print(foobar());   
    }
}

public class B extends A {
    @Override public double foobar() { /*return bar*/ }
    @Override public void print() {
        super.print();
        System.out.print(foobar);
    }
}

我的意图是,当我实例化 B 类型的对象并调用它的 print() 时,让 B 类型的对象首先打印 A 类的 foo,然后打印 B 类的 bar;但是,当我编译执行此代码时,它在两种情况下都从 B 类调用 foobar()。例如,如果 foo 等于 1 并且 bar 等于 2,则上述代码的输出将如下所示:

2 2

但我希望它是 1 2

我尝试过使用各种类型转换调用该方法,但没有运气。有什么建议么?

编辑:感谢您的许多建议,并澄清一下,我希望 A 的每个潜在子类都实现 I 并且我为没有明确说明而道歉。此外,我目前通过在 A privateFooBar() 中添加一个由 A 的 print 和 A 的 foobar 调用的附加方法来获得工作代码;但是,我仍然想知道是否有更优雅的方法来完成这项任务。

4

4 回答 4

3

foobar()在 B 类中被覆盖。因此,每次在 B 类的实例上调用它时,都会调用该方法的 B 类版本。这就是多态性的全部意义所在。

如果您希望 A 中的 foobar() 方法始终返回 A 的 foobar 版本,并且不希望子类中的方法更改它,foobar()则应final在 A 中进行。

或者您可以委托给privateA 中的方法:

public abstract class A implements I {
    @Override 
    public double foobar() { 
        return privateFoobar();
    }

    private double privateFoobar() {
        /* return foo */
    }

    @Override public void print() {
        System.out.print(privateFoobar());   
    }
}

public class B extends A {
    @Override public double foobar() { /*return bar*/ }
    @Override public void print() {
        super.print();
        System.out.print(foobar());
    }
}
于 2013-03-10T08:28:21.650 回答
0

As Class B Override Class A 的 foobar 方法 Class B 总是调用 Class B 版本的 foobar。

如果您希望 Class B 将更改 so print 的方法行为,它将在不调用 super.print() 的情况下打印 foo 和 bar 的值。

在 B 类中为 bar 定义新方法,而不是 A 类的覆盖方法。

public class B extends A {
    public double bar() { /*return bar*/ }
    @Override public void print() {
        System.out.print(bar());
        System.out.print(foobar());
    }
}

当您更改 print() 方法时,重写 print() 而不是 foobar() 方法是正确的。

于 2013-03-10T08:59:27.743 回答
0

在您的 A 类中,您正在调用 foobar(),它在 B 类中被覆盖

public abstract class A implements I {
    @Override public double foobar() { /*return foo*/}
    @Override public void print() {
        System.out.print(foobar()); // HERE 
    }
}

您可以将方法设为最终方法或私有方法

于 2013-03-10T08:33:41.893 回答
0

这是一个关于 foobar 的方法。您可以从 B 调用 super.foobar(),并调整覆盖的 print() 方法。final 或 private 将不起作用,因为那样您就无法覆盖该方法。这是代码:

PS:我将返回类型更改为 String 以返回 "foo" 和 "bar" :)

public class P4  {
    public static void main (String[] args) {
    new B().print();
    System.out.println();
}}

interface I {
    public String foobar();
    public void print();
}

abstract class A implements I {
    @Override public String foobar() { return "foo";}
    @Override public void print() {
        System.out.print(foobar());   
    }
}

class B extends A {
    @Override public String foobar() { return "bar"; }
    @Override public void print() {
        System.out.print(super.foobar());
        super.print();
    }
}
于 2013-03-10T08:45:55.640 回答