示例方法和变量的java继承解析

1bqhqjot  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(357)

根据java,示例方法解析基于参数的运行时类型。
但在解析示例变量时,它使用不同的方法,如下所示。
程序输出为。。

Child
Parent
ParentNonStatic

这里,第一个输出基于参数的运行时类型,但第三个输出不是。
有人能解释一下吗?

public class Child extends Parent {

        public static String foo = "Child";
        public String hoo = "ChildNonStatic";

        private Child() {
            super(1);
        }

        @Override
        String please() {
            return "Child";
        }

        public static void main(String[] args) {
            Parent p = new Parent();
            Child c = new Child();

           //Resolving method
            System.out.println(((Parent) c).please());

           //Resolving Static Variable
            System.out.println(((Parent) c).foo);

           //Resolving Instance Variable
            System.out.println(((Parent) c).hoo);
        }
    }
class Parent {

    public static String foo = "Parent";
    public String hoo = "ParentNonStatic";

    public Parent(int a) {
    }

    public Parent() {
    }

    String please() {
        return "Tree";
    }
}
axr492tv

axr492tv1#

当你向上投射一个对象时,你实际上并没有改变你所引用的项目的内容,只是改变了你对待它的方式。因此,当您将c向上转换为parent并调用please()时,您在父级上调用please(),但动态类型仍然是子级,因此真正被调用的是child中的重写版本,并打印“child”。
当您向上转换c并引用foo时,您不是在进行函数调用。编译器可以在编译时确定所引用的内容。在本例中,具有parent类型的对象的字段foo。字段和静态字段不被覆盖。相反,它们是隐藏的。实际上,这个向上转换的最终结果是帮助java选择隐藏的版本(来自父级的版本),而不是来自子级的版本。类似地,使用hoo可以得到父级的版本。
以下是java教程中的一些信息:http://java.sun.com/docs/books/tutorial/java/iandi/hidevariables.html

uubf1zoe

uubf1zoe2#

字段的重写方式与方法不同。将c强制转换为parent表示“.hoo”是指parent上的“hoo”字段,而不是child上的字段(从技术上讲,字段访问并不是多态的。)

qjp7pelc

qjp7pelc3#

在java中,实际上并不“cast”。当您请求强制转换时,java实际上什么都不做,只是检查对象是否可以被强制转换为该类型,因此为什么强制转换可以抛出“classcastexception”。
但是编译器理解类型转换,因此使用它们来验证方法调用是否合适。
对于静态字段,编译器实际上会删除任何示例变量,并根据返回类型通过类引用字段。

Parent p = new Parent();
Child c = new Child(); 
Parent pc = new Child();

System.out.println(c.foo); // will print Child
System.out.println(p.foo); // will print Parent
System.out.println(pc.foo); // will print Parent
System.out.println(((Child)pc).foo) // will print Child

田地似乎也是这样。
简而言之,我认为java对方法进行动态绑定,对字段进行静态绑定。

相关问题