可以继承Java中的方法访问子类字段

JG1*_*212 1 java methods inheritance

我在理解继承时遇到了麻烦。在下面的代码中,为什么继承的方法不能访问子类中的字段?有什么方法可以访问子类字段而不覆盖继承的方法?

class Fish {
    private String fishType = "Fish";
    public String getFishType() {
        return fishType;
    }
}

class Marlin extends Fish {
    private String fishType = "Marlin";
}

public class InheritanceTest {
    public static void main(String[] args) {
        Fish fish1 = new Fish();
        Fish marlin1 = new Marlin();
        System.out.println(fish1.getFishType());
        System.out.println(marlin1.getFishType());
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码打印

Fish
Fish
Run Code Online (Sandbox Code Playgroud)

但我期待

Fish
Marlin
Run Code Online (Sandbox Code Playgroud)

每个人似乎都是基于私有字符串来回答的,但是即使我将字段更改为公开字符串,我仍然会遇到问题。问题不在于继承私有字段。

请在下面查看更新的代码。

class Fish {
    public String fishType = "Fish";
    public String getFishType() {
        return fishType;
    }
}

class Marlin extends Fish {
    public String fishType = "Marlin";
}

public class InheritanceTest {
    public static void main(String[] args) {
        Fish fish1 = new Fish();
        Marlin marlin1 = new Marlin();
        System.out.println(fish1.getFishType());
        System.out.println(marlin1.getFishType());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出和我的期望与上面相同。

Mak*_*oto 5

首先,是字段(和方法)private不能继承。您的Marlin班级甚至都不知道其父级字段。

其次,Java将根据您在运行时使用的实例选择最合适的方法进行调用。由于未定义Marlin方法getFishType,因此将使用其父方法。

您可以采取几种方法来解决这个问题。其中之一是覆盖getFishType内部的方法Marlin

@Override
public String getFishType() {
    return fishType;
}
Run Code Online (Sandbox Code Playgroud)

使用新代码,您实际上通过在中重新声明变量隐藏变量Marlin

如果类声明了具有特定名称的字段,则称该字段的声明隐藏了超类和该类的超接口中所有相同名称的字段的所有可访问声明。

不重新声明变量,很容易解决。而是在构造时分配所需的值。

public Marlin() {
    fishType = "Marlin";
}
Run Code Online (Sandbox Code Playgroud)

另外,为了使代码更简洁,您可以使用父方法而不是在子方法中重写方法来重组类。这确实需要父类中的几个构造函数。

class Fish {
    private final String fishType;

    // Default constructor; used in nominal cases
    public Fish() {
        this("Fish");
    }

    // Constructor used to populate the fishType field
    public Fish(final String fishType) {
        this.fishType = fishType;
    }

    public String getFishType() {
        return fishType;
    }
}

class Marlin extends Fish {
    public Marlin() {
        super("Marlin"); // invoke super's constructor
    }
}
Run Code Online (Sandbox Code Playgroud)

再次,因为没有合适的方法getFishTypeMarlin,它会寻找到Fish类,并使用它的方法来代替。但是,这次,我们真正想要实现的价值就是我们期望的价值。