Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.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_Inheritance - Fatal编程技术网

Java 方法的继承与变量的继承有何不同?

Java 方法的继承与变量的继承有何不同?,java,inheritance,Java,Inheritance,在为OCJP考试做准备时,我偶然发现了一个我无法集中注意力的问题。下面是一个问题的代码(我做了一些修改): class Foo { public int a = 3; public void addFive() { a += 5; System.out.print("f "); } } class Bar extends Foo { public int a = 8; public void addFive() {

在为OCJP考试做准备时,我偶然发现了一个我无法集中注意力的问题。下面是一个问题的代码(我做了一些修改):

class Foo {
    public int a = 3;
    public void addFive() {
        a += 5;
        System.out.print("f ");
    }
}

class Bar extends Foo {
    public int a = 8;
    public void addFive() {
        a += 5;
        System.out.print("b ");
    }
}

public class TestInheritance {
    public static void main(String [] args) {
        // part 1
        Foo f = new Bar();
        f.addFive();
        System.out.println(f.a);

        // part 2
        Bar b = new Bar();
        b.addFive();
        System.out.println(b.a);
    }
}
输出为:

b 3
b 13
第二部分我能理解。这并不奇怪。然而,第一部分不让我晚上睡觉。我理解为什么运行
Bar.addFive
,但为什么在第1部分
f.a
中,当我使用
newbar()
实例化对象时,打印
Foo.a
?看起来继承对方法的作用与对变量的作用大不相同。我在这里遗漏了什么来理解这个概念?我在哪些方面失败了

 Foo f = new Bar();
这一行意味着访问Bar中的实现和来自Foo的成员:)

因此,您将从
Foo
获得
a
,并从
Bar

看起来继承对方法的作用与对变量的作用大不相同

更准确地说,继承不会使变量多态。当您声明相同的方法时,派生类中的方法将重写基中的方法。声明相同的变量时,基类中的变量将被派生类中的变量隐藏

在您的示例中,
Bar
有两个变量
a
,但只有一个方法
addFive()
。本质上,每个
Bar
对象都包含两个整数-
Foo.a
Bar.a
。这两个是独立的变量。但是,
addFive
方法是在
Bar
中定义的方法,因为它覆盖(替换)了
Foo
中的
addFive


请注意,Java允许
Bar
通过调用
super.addFive()
访问
Foo.addFive
,但是
Bar
的用户没有这种可能性。

变量不是多态的。只有方法是有效的


但是,如果它们被声明为
protected
public
或通过setter和getter来访问它们,则可以从父类访问它们。为了理解第1部分,您需要理解静态绑定和动态绑定之间的区别

静态绑定发生在编译时,私有、最终和静态方法和变量使用静态绑定。静态绑定使用类型(类)信息进行绑定

基于上述定义,当行Foo f=new Bar()时;编译后,变量a初始化为3

方法使用动态绑定解析,动态绑定使用对象解析绑定。 由于对象是Bar()类的对象,因此执行Bar类的addFive()方法。因此,输出b3

可能与