Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中调用特定的类方法(无多态性)_Java_Oop_Polymorphism - Fatal编程技术网

在Java中调用特定的类方法(无多态性)

在Java中调用特定的类方法(无多态性),java,oop,polymorphism,Java,Oop,Polymorphism,我在Java中遇到了一个问题。我有一个可以扩展的方法。问题是,这个方法调用类的其他方法,这些方法也可以扩展 考虑以下类别: public class Foo { protected int xLast; public updateMe(int x, int y) { updateX(x); } protected updateX(int x) { this.xLast = x; } } public class Bar

我在Java中遇到了一个问题。我有一个可以扩展的方法。问题是,这个方法调用类的其他方法,这些方法也可以扩展

考虑以下类别:

public class Foo {
    protected int xLast;

    public updateMe(int x, int y) {
        updateX(x);
    }

    protected updateX(int x) {
        this.xLast = x;
    }
}
public class Bar extends Foo {
    protected int xAverage = 0;
    protected int xCount = 0;
    protected int y;

    public updateMe(int x, int y) {
        super.updateMe(x, y);       
        updateX(x);
        updateY(x);
    }

    protected updateX(int x) {
        this.xAverage = (this.xAverage * this.xCount) + x;
        this.xCount++;
        this.xAverage /= xCount;
    }

    protected updateY(int y) {
        this.y = y;
    }
}
该类由以下类扩展:

public class Foo {
    protected int xLast;

    public updateMe(int x, int y) {
        updateX(x);
    }

    protected updateX(int x) {
        this.xLast = x;
    }
}
public class Bar extends Foo {
    protected int xAverage = 0;
    protected int xCount = 0;
    protected int y;

    public updateMe(int x, int y) {
        super.updateMe(x, y);       
        updateX(x);
        updateY(x);
    }

    protected updateX(int x) {
        this.xAverage = (this.xAverage * this.xCount) + x;
        this.xCount++;
        this.xAverage /= xCount;
    }

    protected updateY(int y) {
        this.y = y;
    }
}
这门课也包括:

public class Abc extends Foo {
}
当我执行以下操作时:

Foo myBar = new Bar();
myBar.updateMe(1, 2);
不会调用
Foo.updateX
方法,但会调用两次
Bar.updateX
方法。有几种解决方案,有些效果不好或相当难看:

  • Bar.updateX
    中调用
    super.updateX
    。这将导致两个
    updateX
    方法被调用两次
  • 删除
    Foo.updateMe
    中的
    updateX
    调用,强制扩展类调用
    super.updateX
    。这将导致类
    Abc
    包含它不需要的无用代码,否则Abc类根本不会调用
    updateX
  • 重命名这些方法,使它们不会相互重写。这会起作用,但不安全(将来可能会被忘记并导致问题),而且语言不会强制执行
  • 我知道这有点代码味道,但我认为没有更好的方法来做到这一点

    基本上,我希望这样做:在
    Foo.updateMe
    中,我想专门调用
    Foo.updateX
    ,而不仅仅是变形ed
    updateX

    我相信像C#中的
    new
    method关键字这样的东西可以解决我的问题,但Java似乎没有一个或任何其他方法来实现这一点

    编辑:


    最后,我选择了重命名这个有问题的方法。我只有一个方法会导致这个问题,这里建议的解决方案,虽然从设计的角度来看,声音会使这个特定的代码更难理解和维护。

    Java,所有实例方法调用都是通过动态绑定的方式调用的。据我所知,没有优雅的方式来完成你想要的

    若你们不关心原则和优雅,你们可以在Foo上检查一个实例的类

    public updateMe(int x, int y) { 
       if (getClass()==Foo.class)         
            updateX(x);     
    }  
    

    Java中,所有实例方法调用都是通过动态绑定的方式调用的。据我所知,没有优雅的方式来完成你想要的

    若你们不关心原则和优雅,你们可以在Foo上检查一个实例的类

    public updateMe(int x, int y) { 
       if (getClass()==Foo.class)         
            updateX(x);     
    }  
    

    伊莱,看来你想取消OOP。首先是不好。如果需要,请更改您的设计。Java是纯面向对象的语言,因此所有调用都是多态的。如果您扩展了类并覆盖了它的一些功能,这意味着您需要这个,因此应该调用这个功能。这就是调用
    Bar
    中的
    updateX()
    的原因


    顺便说一句,要做您想做的事情,您应该创建静态方法并以这种方式调用它:Foo.updateX()。

    Eli,您似乎想取消OOP。首先是不好。如果需要,请更改您的设计。Java是纯面向对象的语言,因此所有调用都是多态的。如果您扩展了类并覆盖了它的一些功能,这意味着您需要这个,因此应该调用这个功能。这就是调用
    Bar
    中的
    updateX()
    的原因

    顺便说一句,要做您想做的事情,您应该创建静态方法,并以如下方式调用它:Foo.updateX()。

    我会这样做:

  • 从Bar.updateMe()中删除updateX()调用,因为super.updateMe()已经调用了updateX()
  • 从Bar.updateX()调用super.updateX(),因为同名的方法应该扩展功能,而不是替换它
  • 在这种情况下,不必更改Abc,两个updateX()方法都将被调用一次。

    我会这样做:

  • 从Bar.updateMe()中删除updateX()调用,因为super.updateMe()已经调用了updateX()
  • 从Bar.updateX()调用super.updateX(),因为同名的方法应该扩展功能,而不是替换它

  • 在这种情况下,不必更改Abc,两个updateX()方法都将被调用一次。

    您还可以将updateX()设为私有。然后,实现updateX()的子类是“隐藏”,而不是“重写”该方法

    缺点: 由于updateX()在概念上是模板模式的一部分,因此它确实“感觉”应该受到保护

    你不能把
    abstract private void updateX()
    在超类中强制用户实现它

    updateMe()的所有实现必须始终记住调用updateX()

    可能的缺点和优点:

    将调用所有私有updateMe()方法。(对我来说这是需要的,YMMV)


    我最近遇到了这个问题,并选择了这个解决方案,尽管我考虑过重命名方法和一些非常接近(getClass()==MyFoo.class)技巧的东西。我认为所有这些都是合理的。

    您还可以将updateX()设置为私有。然后,实现updateX()的子类是“隐藏”,而不是“重写”该方法

    缺点: 由于updateX()在概念上是模板模式的一部分,因此它确实“感觉”应该受到保护

    你不能把
    abstract private void updateX()
    在超类中强制用户实现它

    updateMe()的所有实现必须始终记住调用updateX()

    可能的缺点和优点:

    将调用所有私有updateMe()方法。(对我来说这是需要的,YMMV)


    我最近遇到了这个问题,并选择了这个解决方案,尽管我考虑过重命名方法和一些非常接近(getClass()==MyFoo.class)技巧的东西。我认为所有这些都是合理的。

    我不太明白你想要什么,尽管你可以使用IOC(控制反转)这个问题与IOC有什么关系?。。国际奥委会不是解决我们永恒问题的灵丹妙药,我不是