Java继承问题

Java继承问题,java,inheritance,Java,Inheritance,我有类似的设置: public class Base { public String getApple() {return "base apple"}; } public class Extended extends Base{ public String getApple() {return "extended apple"}; } 在代码的其他地方,我有: { Base b = info.getForm(); if (b instanceof Exten

我有类似的设置:

public class Base {
    public String getApple() {return "base apple"};
}

public class Extended extends Base{
    public String getApple() {return "extended apple"};
}
在代码的其他地方,我有:

{
    Base b = info.getForm();

    if (b instanceof Extended){
        b = (Extended) b;
    }

    System.out.println(b.getApple()); // returns "base apple" even when if clause is true why??

}

如何实现这一点?

获得该行为的唯一方法是在扩展类中返回super.getApple(),这实际上与不首先重写它相同。唯一有帮助的方法是传入一个参数来决定返回哪个。不是说这是个好设计


忘了提到,正如Yuval所说,强制转换对对象没有任何作用。

获得该行为的唯一方法是在扩展类中返回super.getApple(),这实际上与不首先重写它相同。唯一有帮助的方法是传入一个参数来决定返回哪个。不是说这是个好设计

忘了提到,正如尤瓦尔所说,演员对对象没有任何影响。

首先:

if (b instanceof Extended){
    b = (Extended) b;
}
什么都不做。你基本上说的是
b=b
,这没什么意思。您甚至没有更改引用

其次,
getApple()
将始终动态绑定,并且应该始终调用“extended apple”-假定子类确实扩展了基类,并且方法确实被重写

基本上,为了实现正确的
getApple()
行为,您需要做什么:

  • 删除if子句。它什么也不做
  • 确保您的类确实在扩展基类
  • 确保
    getApple()
    方法覆盖基类方法。(如果不确定,请使用
    @override
    注释)
首先:

if (b instanceof Extended){
    b = (Extended) b;
}
什么都不做。你基本上说的是
b=b
,这没什么意思。您甚至没有更改引用

其次,
getApple()
将始终动态绑定,并且应该始终调用“extended apple”-假定子类确实扩展了基类,并且方法确实被重写

基本上,为了实现正确的
getApple()
行为,您需要做什么:

  • 删除if子句。它什么也不做
  • 确保您的类确实在扩展基类
  • 确保
    getApple()
    方法覆盖基类方法。(如果不确定,请使用
    @override
    注释)

如前所述,您的代码将无法编译,这使我认为您的问题出在其他地方。return语句的末尾没有分号。相反,它们出现在
}
后面。可能您还有其他问题(可能是您的子类拼写错误了getApple()),但您仍然在使用旧的类文件,因为您的新东西没有编译

此代码适用于:

class Base {
   public String getApple() { return "base apple"; }
}
class Extended extends Base {
  public String getApple() { return "extended apple"; }
}
public class Test {
  public static void main(String[] args) {
     Base b = new Extended();
     System.out.println(b.getApple());
  }
}
控制台:

#javac Test.java
#java Test
extended apple

如前所述,您的代码将无法编译,这使我认为您的问题在别处。return语句的末尾没有分号。相反,它们出现在
}
后面。可能您还有其他问题(可能是您的子类拼写错误了getApple()),但您仍然在使用旧的类文件,因为您的新东西没有编译

此代码适用于:

class Base {
   public String getApple() { return "base apple"; }
}
class Extended extends Base {
  public String getApple() { return "extended apple"; }
}
public class Test {
  public static void main(String[] args) {
     Base b = new Extended();
     System.out.println(b.getApple());
  }
}
控制台:

#javac Test.java
#java Test
extended apple

首先,if块应该是不必要的。这基本上是禁止的

其次,这不是您真正的代码,因为它甚至不编译。返回语句后缺少分号


我怀疑您的问题在于,您真正的代码有一个打字错误,使得两个getApple方法的签名不同。这意味着Extended有两个方法:一个是从Base继承的,另一个是本身具有不同签名的。由于您使用Base.getApple方法的签名进行调用,因此您总是会得到这种行为。不过,这只是一个猜测,因为您发布的代码没有显示您所描述的问题。

首先,if块不应该是必需的。这基本上是禁止的

其次,这不是您真正的代码,因为它甚至不编译。返回语句后缺少分号

我怀疑您的问题在于,您真正的代码有一个打字错误,使得两个getApple方法的签名不同。这意味着Extended有两个方法:一个是从Base继承的,另一个是本身具有不同签名的。由于您使用Base.getApple方法的签名进行调用,因此您总是会得到这种行为。不过,这只是一个猜测,因为您发布的代码没有显示您所描述的问题。

您在
块中的强制转换没有任何效果是正确的。如果
,您可以尝试将上一条语句与
组合:

if (b instanceof Extended)
{
    // Prints "extended apple" if reached.
    System.out.println(((Extended)b).getApple()); 
}
您在
if
块中的强制转换没有效果是正确的。如果
,您可以尝试将上一条语句与
组合:

if (b instanceof Extended)
{
    // Prints "extended apple" if reached.
    System.out.println(((Extended)b).getApple()); 
}

您应该调查是什么构造了从
info.getForm()
返回的实例。您可能希望将基础抽象化,以防止它被实例化,这样您将很快看到构造发生的位置。

您应该调查是什么构造了从
info.getForm()返回的实例。
。您可能希望将基础抽象化,以防止它被实例化,这样您将很快看到构造发生的位置。

添加到子类中的方法并重新编译。这将帮助您发现您是否实际上没有重写您认为是的方法

i、 e

添加到子类中的方法并重新编译。这将帮助您发现您是否实际上没有重写您认为是的方法

i、 e


您确定问题中提供的代码示例与您正在使用的代码完全匹配吗?我询问的原因是,您描述的行为发生在您使用对象指针访问公共字段时,而不是访问公共方法时

例如:<