静态方法的受保护修饰符的目的是啥

Posted

技术标签:

【中文标题】静态方法的受保护修饰符的目的是啥【英文标题】:What is the purpose of protected modifier for static methods静态方法的受保护修饰符的目的是什么 【发布时间】:2015-06-28 15:28:20 【问题描述】:

在为我的另一个问题寻找解决方案时,我发现了 protected 修饰符的这种用法:Ignoring case in strings with unitils ReflectionComparator

org.unitils.reflectionassert.ReflectionComparatorFactory 类中有一个带有签名的方法:

protected static List<Comparator> getComparatorChain(Set<ReflectionComparatorMode> modes)

但这只是特例。

毕竟我们总是可以扩展这样的任何非最终类并使用新的public 修饰符“覆盖”它的静态protected 方法。说,我们有一个班级A

public class A 
    protected static void test() 
        // do some stuff
    

并想在另一个包中使用它:

public class UseA 
    private static class MyA extends A 
        public static void test() 
            A.test();
        
    

    void useA() 
        // A.test(); compile error, sure
        MyA.test();
    

当一些static 方法被声明为protected 时,我将我的问题集中在一般情况上。我不是在询问非静态字段或方法,因为在某些情况下,类可以有一个私有构造函数或一个非常复杂的构造函数,带有很多特殊参数。但是,如果整个类不是final,那么这种“隐藏”静态方法的目的是什么?这种用法是 OOP 错误还是只是一个非常弱的“保护”?

【问题讨论】:

您不能覆盖静态方法。只能在子类中重新定义。 @bot 当然,这就是为什么我将“覆盖”这个词放在引号中以强调我对这个词的寓言用法 ***.com/questions/24289070/… 这真的是复制品吗?另一个问题是指受保护的静态变量,这个问题是指受保护的静态方法。 @bot 我相信编程语言中的任何结构都必须具有可理解的使用感。在protected static 方法的情况下,我无法理解这样的想法。 【参考方案1】:

但是,如果整个类都不是最终的,那么这种“隐藏”静态方法的目的是什么?

protected static 方法允许您为派生类提供“实用程序”类型的功能,而不会将它们暴露在公共 API 中,因为它们本身可能没有意义。

我不知道你引用的getComparatorChain方法的实现,但我想是这样的方法。如果它不绑定到任何特定实例,它将被标记为static,并标记为protected,以便不成为公共 API 的一部分,但也允许派生类在其自己的实现中重用实用程序方法.

【讨论】:

【参考方案2】:

覆盖静态方法引用意味着隐藏它的实现。请参阅:Java 文档的Overriding and Hiding Methods

静态方法

如果子类定义了与父类中的静态方法具有相同签名的静态方法,则子类中的方法会隐藏超类中的方法。

隐藏静态方法和覆盖实例方法之间的区别具有重要意义:

被调用的重写实例方法的版本是子类中的版本。 被调用的隐藏静态方法的版本取决于它是从超类调用还是从子类调用。

【讨论】:

以上是关于静态方法的受保护修饰符的目的是啥的主要内容,如果未能解决你的问题,请参考以下文章

PHPUnit测试使用pdo的受保护静态方法

如何在同一个类的静态方法中访问类的受保护变量?

为啥 Java 反射 API 允许我们访问私有和受保护的字段和方法?这不会破坏访问修饰符的目的吗? [复制]

事件上的 extern 修饰符的目的是啥? [复制]

Java 方法(变量)修饰符的使用顺序

Resharper:为类/方法修饰符设置排序顺序“静态”/“密封”vS“公共”/“内部”/“保护”