如何在调用方法时绕过java中的继承

时间:2009-02-04 11:38:52

标签: java inheritance oop

    class Super {

        public void anotherMethod(String s) {
            retValue(s)
        }


        public String retValue(String s) {
            return "Super " + s;
        }

    }

    class Sub extends Super {

        public void anotherMethod(String s) {
            retValue(s)
        }

        public String retValue(String s) {
            return "Sub " + s;
        }

    }
  

如果在main中假设,

Super s = new Sub();
s.anotherMethod("Test");
  

输出将是,Sub Test

你能否告诉我如何使用主要中的给定序列获得输出超级测试

  
    

让我解释为什么我想要这个,比如我有一个类有方法test(),它可以被子类覆盖,在某些情况下我想要覆盖test(),在某些情况下我想要超级本身的test(),有很多方法可以做到这一点,最好的建议会有所帮助。

  

10 个答案:

答案 0 :(得分:10)

你为什么要这样做?

多态的全部意义是调用正确的方法而不需要知道你得到了哪种实例......

答案 1 :(得分:7)

每当我发现自己要求(或被问到)这样的问题时,我明确地知道,我在设计和/或对象定义中犯了错误。返回到您的对象层次结构并检查,仔细检查并重复检查每个继承关系是否代表“IS-A”,而不是“HAS-A”或更弱的东西。

答案 2 :(得分:3)

  

让我解释一下为什么我要这个,   说我有一个有方法的课   test()和它可以被覆盖   子类,我想要的一些情况   覆盖test(),在某些情况下   超级本身的test(),那里   有很多方法可以做到这一点   如果有人可以是最好的,   溶液

如果您的子类重写test()则覆盖test() - 这是对象继承的全部要点。您只需调用对象上的方法,这些方法将根据对象的运行时类动态解析为适当的实现。这就是多态类型的优点,事实上,调用者根本不需要知道任何这些,并且子类确定它们的行为与超类的不同之处。

如果您有时希望它充当其超类方法并且有时希望它充当其子类方法,那么您需要提供执行此操作所需的上下文。您可以定义两种测试类型方法;一个永远不会被覆盖的东西,因此总是返回超类的行为(你甚至可以用final标记定义以确保它没有被覆盖),以及正常的子类被子类覆盖。

或者,如果有一些可用的上下文信息,您可以让子类决定如何处理它;例如,他们的实现可以检查一些原则,并根据决定是否调用super.test()或继续执行他们自己的覆盖实现。

你选择哪一个取决于概念上你的main方法(即调用者)或(子)类对象本身是否最适合判断超类的方法是否应该是是否打电话。

但是在任何情况下你都不能覆盖一个方法并期望它有时不会被覆盖。

答案 3 :(得分:2)

你必须走的路是:

Super s = new Super();
s.anotherMethod("Test");

...但如果你还需要Sub得到的东西,那将会破坏继承的目的。你可以像下面那样破解它,但这似乎是一种不太优雅的方式。

class Sub extends Super {

    public String anotherMethod( String s, boolean bSuper ) {
        if( bSuper )
            return super.retValue(s);
        else
            return retValue(s);
    }

    public String retValue(String s) {
        return "Sub " + s;
    }

}

答案 4 :(得分:0)

从Sub类中你可以调用super.anotherMethod(“bla”),但你不能在main方法中访问超类的方法 - 这将违背使用子类的整个想法。

答案 5 :(得分:0)

s的运行时类型为Sub,因此您只需要调用该类的方法。

答案 6 :(得分:0)

虽然我同意其他海报,认为这不是世界上最好的主意,但我相信这可以通过一点点的修补来完成。

如果您的子课程被定义为:

    class Sub extends Super {

        public void anotherMethod(String s) {
            retValue(s)
        }

        public void yetAnotherMethodString s) {
            super.retValue(s)
        }

        public String retValue(String s) {
            return "Sub " + s;
        }

    }

然后在你的主要调用这个新方法,你就可以打印出“超级测试”。

看起来不是一个非常好的计划。如果要从子类访问父功能,则不要覆盖父方法,只需编写一个新方法!

答案 7 :(得分:0)

我很想发布这个作为答案,因为这个问题非常可怕 - 但静态方法大致可以做出OP似乎想要的东西。具体来说,它们在变量的编译时声明的类上解析,而不是在运行时在该变量中保存的实例的类上解析。

所以修改原始示例:

class Super {
public static void staticMethod(String s) { System.out.println("Super " + s); } }

class Sub extends Super {

    public static void staticMethod(String s) {
        System.out.println("Sub " + s);
    }

}

public static void main(String[] args) {

    Super s = new Sub();
    s.staticMethod("Test");

}

然后main()将打印出“超级测试”。

但是在你理解为什么要这样做之前仍然不要这样做,并且你认识到你正在引入子类,然后无偿地解决它们在那里的问题。例如,大多数IDE会在上面的示例中标记大量警告,并说明您不应该在实例变量上调用静态方法(即更喜欢class Sub extends Super { public static void staticMethod(String s) { System.out.println("Sub " + s); } } public static void main(String[] args) { Super s = new Sub(); s.staticMethod("Test"); } 而不是Super.staticMethod("Test")),正是出于这个原因。

答案 8 :(得分:0)

你不能直接修改Sub或Super吗?如果您可以控制使用Sub的哪个实例,您可以执行以下操作:

Super sub = new Sub() {
  @Override
  public String retValue() {
    // re-implement Super.retValue()
  }
};
otherObject.use(sub);

当然,这要求您拥有或能够重现Super.retValue()的源代码,并且此方法不能使用您无法从匿名子项访问的任何内容。如果API设计得很糟糕,你可能会考虑将其更改为其他内容。

答案 9 :(得分:-1)

  

你们能帮助我讲述一下吗?   获得输出“Super Test”   给定main中的序列。

  • 首先不要覆盖anotherMethod()中的retValue()Sub

  • 在S ub.anotherMethod()中,返回 super .retValue(s)而不是retValue(s)