1

Java是面向对象的编程语言。继承是最重要的特性之一。我们使用封装来隐藏对象状态。在下面的程序中,我应该对年龄和计数器使用私有访问修饰符,但为了测试这种继承,我使用了公共。

  1. 为什么在直接对象状态访问(原始类型或对象引用)的情况下继承不起作用。SOP 3 输出与预期不同。
  2. 由于编译器在 SOP 13 和 SOP 14 行中没有给出任何错误。为什么打印父类详细信息而不是子类。

.

public class Father {

    public int age = 50;
    /*
     * Counter keeps track of total no of instances created so far.
     */
    public static int counter = 0;

    public Father(){
        super();
        synchronized (Father.class) {
            ++Father.counter;   
        }
    }

    public int getAge(){
        return this.age;
    }

    public static int getStaticCount(){
        return Father.counter;
    }

}

public class Child extends Father {

    public int age = 25;
    public static int counter = 0;

    public Child(){
        super();
        synchronized (Child.class) {
            ++Child.counter;    
        }
    }

    public int getAge(){
        return this.age;
    }

    public static int getStaticCount(){
        return Child.counter;
    }

    public static void main(String args[]){

        Father father = new Father();
        Father child = new Child();
        Child realChild = new Child();

        System.out.println("Expecting Father Class details to be printed");
        System.out.println("SOP 1 : Father Age : "+father.age);     //prints 50 as expected.
        System.out.println("SOP 2 : Father Age : "+father.getAge());//prints 50 as expected.

        System.out.println("Expecting Child Class details to be printed");
        /*
         * Why inheritance does not work in case of direct integer access.
         */
        System.out.println("SOP 3 : Child Age : "+child.age); //prints 50 ?? , Father Age . Why ?
        System.out.println("SOP 4 : Child Age : "+child.getAge());//prints 25 as expected.

        System.out.println("Expecting Child Class details to be printed");
        System.out.println("SOP 5 : Child Age : "+realChild.age); //prints 25 as expected.
        System.out.println("SOP 6 : Child Age : "+realChild.getAge());//prints 25 as expected.

        /*
         *Total No of static Count : proper way of accessing static field using Class Name. 
         */
        System.out.println("SOP 7 : Father Instance Count : Using Class Reference :"+Father.counter);
        System.out.println("SOP 8 : Father Instance Count : Using Class Reference :"+Father.getStaticCount());

        /*
         * Incorrect Way to use static. Since Compiler allows this lets see output.
         */

        System.out.println("SOP 9 : Father Instance Count : Using Object Reference :"+father.counter); //prints 3 as expected.
        System.out.println("SOP 10 : Father Instance Count : Using Object Reference :"+father.getStaticCount());//prints 3 as expected.

        /*
         *Total No of static Count : proper way of accessing static field using Class Name.  
         */
        System.out.println("SOP 11 : Child Instance Count : Using Class Reference :"+Child.counter); // output is 2 as expected
        System.out.println("SOP 12 : Child Instance Count : Using Class Reference :"+Child.getStaticCount()); // output is 2 as expected

        /*
         * Incorrect Way to use static.Since Compiler allows this lets see output.
         * This invokes function of parent class. Why ? Inheritance does not work for static fields.
         */
        System.out.println("SOP 13 : child Instance Count : Using Object Reference :"+child.counter); // output is 3 but expected is 2 .          why ? 
        System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount()); // output is 3 but expected is 2 .  why ?

        /*
         * Incorrect Way to use static.Since Compiler allows this lets see output.
         * This invokes function of parent class. Why ?
         */
        System.out.println("SOP 15 : child Instance Count : Using Object Reference :"+realChild.counter); // output is 2 as expected
        System.out.println("SOP 16 : child Instance Count : Using Object Reference :"+realChild.getStaticCount()); // output is 2 as expected
    }

}

我的问题是为什么继承只适用于实例方法。为什么 SOP 3、SOP 13 和 SOP 14 的输出不同。

4

4 回答 4

3

原因是多态性不适用于实例变量。您正在做的是可变阴影

在 SOP 3 和 4 中,子类中具有相同名称的变量会隐藏基类中的变量。由于这是在编译时解决的,因此选择了静态类型的值。

在 SOP 13 和 SOP 14 中,发生这种情况的原因相同。在该方法的范围内,孩子的类隐藏变量是未知的。

来自 JSL:

在类类型 C(第 8.1.6 节)中声明或继承的成员 m 的声明范围是 C 的整个主体,包括任何嵌套类型声明。

于 2012-09-15T20:34:05.290 回答
1

("SOP 3 : Child Age : "+child.age);

没有这样的事情"overriding fields"。您可以隐藏字段,但不能覆盖它们。 Fields aren't polymorphic. 6.4.1 of the Java Language Specification有关详细信息,请参阅部分。

/////-------------问题结束:1--------/////

("SO 13 : child Instance Count : Using Object Reference :"+child.counter);

child.counter指向父类static counter variable,正如我之前提到的Fields are not Polymorphic

/////-------------问题结束:2-------/////

("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount());

child.getStaticCount()是指向static counter variable类的父亲

尝试一下realChild结果将是 2static counter variable ,正如预期的那样,它指向Child Class

System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+realChild.getStaticCount());

于 2012-09-15T20:39:49.390 回答
0

当编译器正在查看 SOP 3 的行时,它不知道child包含除Father实例之外的任何内容......您已将子类放入其中的事实是无关紧要的,编译器将绑定字段查找基于这是一个Father类......所以它访问Father.age整数字段,所以预期的输出是 50 而不是 25。

SOP 13 与 SOP 3 相同...唯一的区别是您正在通过实例变量访问静态字段...这被认为是不好的风格,因为它只会引起您的困惑。

SOP 14 正在通过实例访问静态方法......并且该变量再次保存了 class 的对象Father,所以它Father.getStaticCount()就是返回的。这又是一种糟糕的风格。

您可以通过访问获得类似的效果((Father)realChild).ageFather.counter并且Father.getStaticCount在每种情况下,您都指定您想要Father类的字段/方法。

这是因为 Java 中没有字段重载,并且静态方法也没有重载。

如果要从子类中访问父字段,只需调用对父类的强制转换。

于 2012-09-15T20:51:02.710 回答
0
System.out.println("SOP 3 : Child Age : "+child.age);
System.out.println("SOP 13 : child Instance Count : Using Object Reference :"+child.counter); // output is 3 but expected is 2 .          why ? 
System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount()); // output is 3 but expected is 2 .  why ?

在上面的示例中,您创建了子类的对象Father child = new Child();并将其存储在父类引用变量中,该变量是子类的超类。如果您将尝试调用任何方法或尝试通过“子”引用变量访问任何实例变量,它首先检查超类,然后如果在超超中找到它,则进入子类超级被执行。

于 2012-09-15T21:16:23.413 回答