Overriding private methods in (non

I have this test code example:

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");
        }
    }
}

First, all works as I think it should:

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

Then, inherited class's private method dissapears, if I called non-implemented parent method. It could be explained as "All private methods are final and hidden from derived classes", so invokeNotOverriden() doesn't know anything about methods in Test2 class:

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

Finally, in static class some magic suddenly appears when I call non-static private method:

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

I expected 1 2 2 here. Why am I wrong?


You've got 1 2 1 in some magic section, because private methods are resolved w/o polymorphism, compiler creates call to method contained in type variable declared with, in your case Test3 . Declare print1 as non-private in Test3 (and, consequently, in Test4 as it's prohibited to tighten access modifiers of methods) and see polymorphism in action, so you'll get expected 1 2 2 .


Consider shorter example:

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 ... to my comment to this answer: polymorphism isn't effective for access to data fields, only for methods. Consider:

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);
}

Despite i declared non-private, t34.i value is 1 .


Private methods are only available to the class which declares them, not the children of that class.

If you want a method from a parent-class to be used in a child, you have to make it protected .

In your last case, you casted to Test3, so for all intents and purposes, that class thinks it's Test3 and calls Test3's print method. Static instances are not cast (you always call them with their qualified name), so they always call their own private methods.


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

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

上一篇: 对java中的泛型和反射的限制

下一篇: 重写私有方法(非