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(),有很多方法可以做到这一点,最好的建议会有所帮助。
答案 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)
。