使用java继承和接口调用的方法版本不正确

时间:2013-03-10 08:24:06

标签: java inheritance interface

我有一个简单的继承层次结构和一个接口。考虑将由类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的每个潜在子类都能实现我,我为没有明确说明而道歉。另外,我目前通过在A privateFooBar()中添加一个额外的方法来获得工作代码,该方法由A的print和A的foobar调用;但是,我仍然想知道是否有更优雅的方法来完成这项任务。

4 个答案:

答案 0 :(得分:3)

在类B中重写了

foobar()。所以每次调用类B的实例时,都会调用该方法的B类版本。这就是多态性的全部意义所在。

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

或者您可以委托给A:

中的private方法
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());
    }
}

答案 1 :(得分: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 
    }
}

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

答案 2 :(得分: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();
    }
}

答案 3 :(得分:0)

作为B类覆盖A类B类的foobar方法总是调用B类版本的foobar。

如果你想要B类将改变so print的方法行为,它将打印foo和bar的值而不调用super.print()。

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

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()方法是正确的。