简体   繁体   English

我不了解这种继承功能

[英]I dont understand this inheritance functionality

Consider the following illegal code :- 考虑以下非法代码:

class WrongCode{
    int i;
    static int i;
}

Here, the compiler says that we have duplicate fields in the same class. 在这里,编译器说我们在同一个类中有重复的字段。

Now, consider the following classes in the same file. 现在,在同一文件中考虑以下类。

class Parent{
    int i = 10;
}

class Child extends Parent{
    static int i = 100;
}

public class Main{
    public static void main(String ... aaa){
        Parent ob = new Child();
        System.out.println(ob.i);   // This prints Parent's i
    }
}

Since the actual object is of Child, shouldn't ob refer to Child's i? 由于实际对象是Child,所以不应该引用Child的i吗? And if it is refering to Parent's "i", then in a way it is also having Parent's "i" in its own class along with its own static "i" which is NOT ALLOWED. 而且,如果它引用了Parent的“ i”,那么在某种程度上,它也将Parent的“ i”与自己的静态“ i”一起放在自己的类中,而静态“ i”是不允许的。

Child static i overshadows Parent i. 子静态i遮盖了父i。 And Parent's i is not static, so then how is it accessed directly using instance and not className? 而且Parent的i不是静态的,那么如何使用实例而不是className直接访问它?

You have instance field i in Parent class and it remain an instance field in Child class. 您在Parent类中有实例字段i ,而在Child类中仍是实例字段。

System.out.println(ob.i);  // must be 10

Have a look at - Oracle Java Tutorial - Hiding Fields 看看-Oracle Java教程-隐藏字段

It is important to realize here that there is no way System.out.println(ob.i); 在这里重要的是要意识到没有办法System.out.println(ob.i); could print Child 's i : it only knows that ob is of declared type Parent , not that it was instantiated with an actual Child . 可以打印Childi :它只知道ob的声明类型是Parent ,而不是用一个实际的Child实例化的。 Thus, if Parent did not have any i , there would be a compile error. 因此,如果Parent没有任何i ,则会出现编译错误。 If parent has an i , this is printed. 如果parent有一个i ,则将其打印出来。

I have seen it mentioned on SO that access of class variables via instances (ie ob.i being equivalent to Parent.i ) should be considered a serious design flaw of Java. 我已经在SO上看到它提到通过实例访问类变量(即ob.i等同于Parent.i )应该被视为Java的严重设计缺陷。 I agree it can be sometimes confusing. 我同意这有时会令人困惑。 Anyway, both your parent and child could also have a non-static i and it need not be the same. 无论如何,您的父母和孩子也可以有一个非静态的i ,并且不必相同。 The argument above should be applicable to reasoning which one would be printed in which situation. 上面的论点应适用于推理在哪种情况下应打印的内容。

In ob , the static int i of child is never visible since ob is of type Parent, irrespective of how it was instantiated( base class or derived class). ob ,因为ob的类型为Parent,所以child的static int i永远是不可见的,而与实例化方式(基类或派生类)无关。

That's why you have the value as 10 , that Parent s i value. 这就是为什么您将值10表示为Parenti值。

Java lets your class have its own variables that have the same name as a variable in the parent. Java让您的类拥有自己的变量,这些变量与父变量中的变量同名。 But it can't just let you randomly redefine parent variables, as that would cause other stuff to break. 但这不能只让您随机地重新定义父变量,因为那样会导致其他内容中断。 So what it does...when you have a variable obj that's declared as the parent class, even if it holds an instance of a child class, obj.i will refer to the parent class's i rather than the child's. 所以它的作用是...当您将变量obj声明为父类时,即使它拥有子类的实例, obj.i也会引用父类的i而不是子类的i

When you access class member fields (instance variables) like ob.i. 当您访问类成员字段(实例变量)(如ob.i)时。 you'll get the results from the class that's known at compile time, not what is known at run time. 您将从编译时已知的类而不是运行时已知的类中得到结果。 Thats why you have value as 10 which is parents value. 这就是为什么您拥有10的价值,这就是父母的价值。

For method calls they are dispatched at run time to an object of the actual class the reference points. 对于方法调用,它们在运行时被分派到实际类的参考点。

Regarding shadowing here is what Java lang spec says: 关于阴影,这里是Java lang规范所说的:

If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class. 如果类声明了具有特定名称的字段,则称该字段的声明隐藏了超类和该类的超接口中所有相同名称的字段的所有可访问声明。

A hidden field can be accessed by using a qualified name (if it is static) 可以使用限定名称访问隐藏字段(如果它是静态的)

language spec 语言规范

You may refer "Field Declarations" section. 您可以参考“字段声明”部分。

实际上,它的多态性和ob只能访问父类字段和行为(如果有)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM