【问题标题】:Redefine static members in a derived class. Java重新定义派生类中的静态成员。爪哇
【发布时间】:2014-12-20 06:36:14
【问题描述】:

所以我在读这本书,作者说“静态成员不涉及运行时多态性。你不能覆盖派生类中的静态成员,但你可以重新定义它们。”

这是什么意思?你也能给我举个例子吗?

谢谢。

【问题讨论】:

    标签: java static static-methods


    【解决方案1】:

    如果您在子类中重新定义静态成员(方法或变量),则会隐藏超类的定义。

    public class Super
    {
        public static void methodA()
        {
    
        }
    }
    
    public class Sub extends Super
    {
        public static void methodA()
        {
    
        }
    }
    

    这里静态methodA在子类中被重新定义,但并没有覆盖超类的methodA

    调用Sub.methodA 将调用SubmethodA。如果Sub 没有methodA,则调用Sub.methodA 将调用SupermethodA

    【讨论】:

    • 仍然不确定我是否理解,抱歉。可以举个例子吗?
    • 那么如果上面的方法不是静态的,那么它会被覆盖而不是重新定义,对吗?
    • @taimeili123 是的,如果方法不是静态的,子类中的方法将覆盖超类中的方法。
    【解决方案2】:

    如果在子类中重新定义静态方法,则称为方法隐藏。静态方法在编译时而不是运行时解析,您可以根据类调用它们,例如:

    class A {
        public static void mymthod() {}
    }
    
    class B extends A {
        public static void mymthod() {}
    }
    

    你叫:

    A a = new B();
    a.mymthod();//resolved at compile time and associated with class A (compiler will warn although as static method doesnt necessarily need an object to call)
    

    【讨论】:

    • 如果我错了,请原谅我,但重新定义方法与覆盖方法不同吗?如果该方法不是静态的,那么它被认为是您给出的示例中的覆盖?
    • 是的,没错。但是请参阅从直接类调用对象与调用的上下文,运行时与编译时间。请参阅该方法与 CLASS 相关联而不是对象。一旦定义了它的定义并且不能更改,因为它是静态的。
    【解决方案3】:

    你可以自己看看这个

    class A {
    
        static int x = 1;
        int y = 1;
    
        int f() {
            return 1;
        }
    
        static int sf() {
            return 1;
        }
    }
    
    class B extends A {
    
        static int x = 2;
        int y = 2;
    
        int f() {
            return 2;
        }
    
        static int sf() {
            return 2;
        }
    
    }
    
    public class Test {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            A b = new B();
            System.out.println("A.x=" + ((A) b).x);
            System.out.println("B.x=" + b.x);
            System.out.println("A.y=" + ((A) b).y);
            System.out.println("B.y=" + b.y);
            System.out.println("A.f() = " + ((A) b).f());
            System.out.println("B.f() = " + b.f());
            System.out.println("A.sf() = " + ((A) b).sf());
            System.out.println("B.sf() = " + b.sf());
    
        }
    
    }
    

    它打印:

    A.x=1 B.x=1 A.y=1 B.y=1 A.f() = 2 B.f() = 2 A.sf() = 1 B.sf() = 1

    人们会期望 B.sf 打印为 2 但不是。

    同样的人会期望 B.x 和 B.y 打印为 2,但也不会,因为字段也不是多态的,只有函数。

    我不确定这是否有很大的实用价值,在犯错之后肯定会知道这一点。 不过,这可能会在更糟糕的工作面试中被问到。

    【讨论】:

      【解决方案4】:

      子类中的变量将同名变量隐藏在超类中。

      【讨论】:

        猜你喜欢
        • 2018-11-30
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        • 1970-01-01
        • 2011-03-11
        • 2023-03-23
        • 1970-01-01
        相关资源
        最近更新 更多