English 中文(简体)
Java 的压倒性成员变量( 变量隐藏)
原标题:Overriding member variables in Java ( Variable Hiding)

我正在研究爪哇的压倒一切的成员职能,并思考如何试验压倒一切的成员变量。

所以我定义了班级

public class A{
    public int intVal = 1;
    public void identifyClass()
    {
        System.out.println("I am class A");
    }
}

public class B extends A
{
    public int intVal = 2;
    public void identifyClass()
    {
        System.out.println("I am class B");
    }
}

public class mainClass
{
    public static void main(String [] args)
    {
        A a = new A();
        B b = new B();
        A aRef;
        aRef = a;
        System.out.println(aRef.intVal);
        aRef.identifyClass();
        aRef = b;
        System.out.println(aRef.intVal);
        aRef.identifyClass();
    }
}

产出是:

1
I am class A
1
I am class B

我无法理解为什么一个参考文件设于b intVal 仍然属于A级?

最佳回答

当您在一个子类中做出一个同名变量时,该变量被称为 hidding 。 由此产生的子类现在将具有两个属性。 您可以使用 overu. var (SuperClass) (SuperClass) 来访问超级类中的变量。 var 。 这些变量甚至不必使用同一类型; 它们只是两个共享名称的变量, 类似于两个超载方法 。

问题回答

在 Java 中,变量不是多态的; 它们不会相互覆盖 。

爪哇的田地没有多种形态。 < 强>

Variables 裁决是在汇编时发生的,因此总是可以访问 < strong > base class 变数 (不是孩子的遗传变数)。

所以每当广告上扬时 总是记住

1) 将访问基础类变量。

2) 子类方法(如果压倒其他遗传方法,则由父权所继承的方法取代的方法)将称为子类方法(如果压倒其他遗传方法,则由母权所继承的方法)。

变量被解析 汇编时间, 方法运行时间。 aRef 是 A型, 因此 aref. Intvalue 被解析为 1 。

JLS Java SE 7版第15.11.1节:

由于缺乏对外地访问的动态搜索,使得程序能够以直接的实施来高效地运行。 过时约束和压倒一切的力量是存在的,但只有在使用实例方法时才能存在。

Oliver Charlesworth和Marko Topolnik的回答是正确的,

在爪哇中,'rel=“nofollown norefererr'” > 类成员 按参考类型而不是实际对象类型获得 。出于同样的原因,如果类中有 someother MethodInB () () ,在 aref 之后,您将无法从 aref 访问它。在编译时会解析身份(i clas、变量等名称),因此编译者依赖参考类型。

在您的示例中, 当运行 < code> System. out. primpln( aRef.intVal); 时, 它会打印 < intval 的值, 定义在 A < /code > 中, 因为这是您访问它所使用的引用类型。 编纂者看到 aref 是类型 < code> A , 并且它会访问 < code> < intval 。 不要忘记您在 < code> B 中既有 < / em > 字段。 JLS 也有类似您访问它的例子, “ 15. 11. 11. 11. 1 1.. Statical Connable for F域访问 ”, 如果您想查看的话, 。

但为什么方法会不同呢?答案是对于方法, Java 使用“ 强超超拉特绑定 < / 强 ” 。 这意味着在编译时, 它会找到最合适的方法来在运行期间搜索 < / em > 。 搜索涉及到某类中该方法被推翻的情况 。

OverRiding Concept in Java Functions will override depends on object type and variables will accessed on reference type.

  1. Override Function: In this case suppose a parent and child class both have same name of function with own definition. But which function will execute it depends on object type not on reference type on run time.

例如用于:

Parent parent=new Child();
parent.behaviour();

这里 parent 是父母阶级的参考,但带有儿童阶级的标的,因此在这种情况下,儿童阶级功能将被调用。

Child child=new Child();
child.behaviour();

这里 child 持有儿童类的物品,因此儿童类功能将被调用。

Parent parent=new Parent();
parent.behaviour();

这里 parent 持有父类的对象, 因此父类函数将被调用 。

  1. Override Variable: Java supports overloaded variables. But actually these are two different variables with same name, one in the parent class and one in the child class. And both variables can be either of the same datatype or different.

当尝试访问变量时,它取决于引用类型对象,而不是对象类型。

例如用于:

Parent parent=new Child();
System.out.println(parent.state);

参考类型是父类,因此访问父类变量,而不是子类变量。

Child child=new Child();
System.out.println(child.state);

这里的参考类型是“Child”,所以儿童类变量不是“父母类变量”。

Parent parent=new Parent();
System.out.println(parent.state);

这里的参考类型是父类, 所以父类变量被访问 。

我希望这能有助于:

public class B extends A {
//  public int intVal = 2;

    public B() {
        super();
        super.intVal = 2;
    }

    public void identifyClass() {
        System.out.println("I am class B");
    }
}

因此基本等级的压倒性变量是不可能的,但基本等级变量值可以从继承等级的建造者处设定(修改)。

这被称为变量隐藏 。 当你指定 aref = b; 时, aref 有两个英寸Val, 1 名称只是 intval , 另一名称在 A.intval (见调试器屏幕截图)下隐藏(见调试器截图), 因为变量属于类型 类A , 即使您打印了 Val java 智能地接收了 A.intval

Answer 1 :获取儿童类 s intval 的方法之一是 System.out.println((B)aref.intval);

Answer 2 :另一种方法就是 Java 反射,因为当您使用反射 java cant 智能移动隐藏的 A.intval 时,它必须取出以字符串命名的变量名称 -- --

import java.lang.reflect.Field;

class A{
    public int intVal = 1;
    public void identifyClass()
    {
        System.out.println("I am class A");
    }
}

class B extends A
{
    public int intVal = 2;
    public void identifyClass()
    {
        System.out.println("I am class B");
    }
}

public class Main
{
    public static void main(String [] args) throws Exception
    {
        A a = new A();
        B b = new B();
        A aRef;
        aRef = a;
        System.out.println(aRef.intVal);
        aRef.identifyClass();
        aRef = b;
        Field xField = aRef.getClass().getField("intVal");
        System.out.println(xField.get(aRef));
        aRef.identifyClass();
    }
}

产出 -

1
I am class A
2
I am class B

嗯,我希望你得到了答案。如果不是的话, 你可以尝试在调试模式下看到。 B 子类可以同时进入 IntVal 。 它们不是多形态的, 因此它们不是被覆盖的 。

如果您使用 B s 引用, 就会得到 B s intval 。 如果您使用 A S 引用, 就会得到 A intval 。 就这么简单 。

按照爪哇的规格,例变数在扩展时不会被一个子类从超级类中推翻。

因此,子类中的变量只能被视为具有相同名称的变量。

此外,当A的建造者在B例创建时被调用时,变数(半衰期)被初始化,从而产生输出。

这是因为当给 aref 指定 b 时,它就解决了,导致 aref 仅仅是A类。这意味着 aref 无法访问任何 B 类 S 字段或方法。如果您使用 b.int Val 而不是使用 b.int Val 来呼唤 IntVal,您将得到 2 。

Java有一个羽毛的封装羽毛 意味着它紧紧绑着一个物体的属性和行为。所以只有通过类参考,我们才能把它称为改变它属性的行为。

在继承中,只有方法高于一切,只能影响财产。

正如许多用户已经指出的,这不是多形态主义,多形态主义只适用于方法(功能)。

至于为什么打印 A 类的 ItVal 值, 这是因为您可以看到参考文献 aRef 是 A 型 。

我理解你为什么被它混淆了。 同样的程序, 你访问过被覆盖的前方法。 方法识别Classs (), 但不是直接证明我所写第一行的变量 。

现在,为了访问变量,您可以做(( Superclass)c.) var。

Note here that the Superclass can be many levels up for example A<-B<-C. That is C extends B and B extends A. If you wanted the value of var of A then you could have done ((A)c).var .

EDIT:正如用户之一指出的,这种伎俩不适用于静态方法,因为它们是静态的。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...