重写私有方法(非

我有这个测试代码示例:

public class Test {

    private static class Test3 {

        private void print1() {
            System.out.println("1");
        }
    }
    private static class Test4 extends Test3 {

        private void print1() {
            System.out.println("2");
        }
    }

    public static void main(String[] args) {
        System.out.println("Overriden call to private method ----------------");
        OuterTest.Test1 test1 = new OuterTest.Test1();
        OuterTest.Test2 test2 = new OuterTest.Test2();
        OuterTest.Test1 test12 = new OuterTest.Test2();

        test1.invokeOverriden();
        test2.invokeOverriden();
        test12.invokeOverriden();

        System.out.println("Call to private method from parent class ----------------");

        test1.invokeNotOverriden();
        test2.invokeNotOverriden();
        test12.invokeNotOverriden();

        System.out.println(" Some magic ----------------");

        Test3 test3 = new Test3();
        Test4 test4 = new Test4();
        Test3 test34 = new Test4();

        test3.print1();
        test4.print1();
        test34.print1();
    }
}

class OuterTest {

    public static class Test1 {
        public void invokeOverriden() {
            print1();
        }
        public void invokeNotOverriden() {
            print1();
        }

        private void print1() {
            System.out.println("1");
        }
    }

    public static class Test2 extends Test1 {

        @Override
        public void invokeOverriden() {
            print1();
        }
        private void print1() {
            System.out.println("2");
        }
    }
}

首先,我认为它应该:

Overriden call to private method ----------------
1
2
2

然后,如果我调用未实现的父方法,继承类的私有方法消失。 它可以解释为“所有私有方法对派生类都是最终的和隐藏的”,所以invokeNotOverriden()对Test2类中的方法没有任何了解:

Call to private method from parent class ----------------
1
1
1

最后,在静态类中,当我调用非静态私有方法时,突然出现一些魔法:

Some magic ----------------
1
2
1

我预计1 2 2在这里。 为什么我错了?


你在some magic部分有1 2 1 ,因为私有方法没有使用多态性解析,所以编译器创建对包含在类型变量中的方法的调用,在你的例子中是Test3 。 在Test3 print1声明为非私有的(因此,在Test4因为它禁止修改方法的访问修饰符)并且看到多态行为,所以你会得到预期的1 2 2


考虑较短的例子:

class Test {

    private static class Test3 {
        private void print1() {
            System.out.println("non-polymorphic 1");
        }

        void polymorphic() {
            System.out.println("polymorphic 1");
        }
    }

    private static class Test4 extends Test3 {
        private void print1() {
            System.out.println("non-polymorphic 2");
        }

        void polymorphic() {
            System.out.println("polymorphic 2");
        }
    }

    public static void main(String[] args) {
        Test4 t4 = new Test4();
        t4.print1();
        t4.polymorphic();

        System.out.println("======");

        Test3 t34 = new Test4();
        t34.print1();
        t34.polymorphic();
    }
}

CLARIFICATION ...对我的评论这个答案:多态性不适用于访问数据字段,仅适用于方法。 考虑:

private static class Test3 {
    int i = 1;
}

private static class Test4 extends Test3 {
    int i = 2;
}

public static void main(String[] args) {
    Test4 t4 = new Test4();
    System.out.println(t4.i);

    System.out.println("======");

    Test3 t34 = new Test4();
    System.out.println(t34.i);
}

尽管i宣布非私有,但t34.i值为1


私有方法只适用于声明它们的类,而不适用于该类的子类。

如果你想要一个父级的方法在一个孩子中使用,你必须protected它。

在你最后一个例子中,你选择了Test3,所以为了所有的目的和意图,这个班级认为它是Test3并且调用了Test3的打印方法。 静态实例不会被强制转换(您总是用它们的限定名称来调用它们),所以它们总是调用它们自己的私有方法。


就像你说的,你不能重写一个private方法,使它protected

链接地址: http://www.djcxy.com/p/76505.html

上一篇: Overriding private methods in (non

下一篇: Check if a class is derived from a generic class