本文介绍了覆盖(非)静态类中的私有方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个测试代码示例:

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

然后,如果我调用了未实现的父方法,则继承的类的私有方法就会消失.可以将其解释为所有私有方法都是最终的,并且对派生类隐藏",因此 invokeNotOverriden()对Test2类中的方法一无所知:

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

我希望在这里 1 2 2 .我为什么错了?

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

推荐答案

您已经在一些魔术部分中获得了 1 2 1 ,因为私有方法是使用w/o多态性,编译器会创建对包含在使用 Test3 声明的类型变量中的方法的调用.在 Test3 中将 print1 声明为非私有(因此,在 Test4 中声明,因为它被禁止加强方法的访问修饰符),并在动作,这样您就可以得到预期的 1 2 2 .

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.

考虑以下示例:

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

尽管 i 声明为非私有,但 t34.i 的值为 1 .

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

这篇关于覆盖(非)静态类中的私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 07:19