代码之家  ›  专栏  ›  技术社区  ›  Mike

为什么静态方法不被视为良好的OO实践?[关闭]

  •  34
  • Mike  · 技术社区  · 14 年前

    我在读书 Programming Scala . 在第4章的开头,作者认为Java支持静态方法,它们不是“纯OO概念”,为什么会这样呢?

    7 回复  |  直到 6 年前
        1
  •  25
  •   Eddie    14 年前

    静态方法不是很oo的一个原因是接口和抽象类只定义了非静态方法。因此静态方法不太适合继承。

    还要注意,静态方法不能访问“ super “,这意味着不能从任何实际意义上重写静态方法。实际上,它们根本不能被覆盖,只能隐藏。试试这个:

    public class Test {
        public static int returnValue() {
            return 0;
        }
    
        public static void main(String[] arg) {
            System.out.println(Test.returnValue());
            System.out.println(Test2.returnValue());
            Test x = new Test2();
            System.out.println(x.returnValue());
        }
    }
    
    
    public class Test2 extends Test {
        public static int returnValue() {
            return 1;
        }
    }
    

    当你运行这个时,你不会得到你期望的。 Test.returnValue() 给出你所期望的。 Test2.returnValue() 兽皮 超类中同名的方法(它不会重写它),它给出了您期望的结果。

    人们可能天真地期望“非静态”调用静态方法使用多态性。它没有。变量声明为用于查找方法的类。这是一种糟糕的形式,因为有人可能会期望代码执行与实际执行不同的操作。

    这并不意味着“不要使用静态方法!”这确实意味着您应该为那些您真正希望类对象拥有该方法的实例保留静态方法的使用,而不仅仅是一种懒惰的生成单例方法。

        2
  •  59
  •   Jörg W Mittag    14 年前

    对象方向大约有三件事:

    • 消息传递,
    • 本地保留、保护和隐藏状态过程,以及
    • 所有事物的极端后期约束。

    其中最重要的是 消息传递 .

    静态方法至少违反了消息传递和后期绑定。

    理念 消息传递 这意味着在OO中,计算是由相互发送消息的独立对象网络执行的。发送消息是 只有 通信/计算方式。

    静态方法不会这样做。它们与任何对象都没有关联。他们真的不是方法 完全 根据通常的定义。它们真的只是程序。Java静态方法之间几乎没有差别。 Foo.bar 和一个基本子程序 FOO_BAR .

    关于后期装订:一个更现代的名字是 动态调度 . 静态方法也违反了这一点,事实上,它甚至以它们的名字命名: 静止的 方法。

    静态方法会破坏对象方向的一些非常好的属性。例如,面向对象的系统是自动功能安全的,对象充当功能。静态方法(或真的 任何 静态,即静态状态或静态方法)会破坏该属性。

    您还可以在自己的进程中并行地执行每个对象,因为它们只通过消息传递进行通信,从而提供一些微不足道的并发性。(像 演员 基本上,这不应该太令人惊讶,因为卡尔·休伊特根据smalltalk-71创建了演员模型,艾伦·凯根据planner部分创建了smalltalk-71,而planner又由卡尔·休伊特创建。演员和对象之间的密切关系远非巧合,事实上,他们本质上是一个相同的。)同样,静态(两种静态方法,和 尤其地 静态状态)打破这种美好的属性。

        3
  •  30
  •   Gabe Timothy Khouri    13 年前

    不要把“不那么纯粹的OO概念”和“糟糕的实践”混为一谈。“纯粹的OO”并不是你应该尝试实现的灵丹妙药。仅仅因为静态方法不将实例变量作为参数,并不意味着它们是无用的。有些东西只是不借给自己的对象,他们不应该被迫进入模具,只是为了“纯度”。

    有些人认为事情应该是“纯洁的”,因此任何“不纯洁的”都是不好的做法。实际上,糟糕的实践只是做一些令人困惑、难以维护、难以使用等的事情。创建一个实例的静态方法 不良行为 因为采用实例的任何方法都可能是实例方法。另一方面,像实用程序和工厂函数之类的东西通常不以实例为例,因此它们 应该 静止不动。

    如果你想知道为什么它们不是“纯OO”,那是因为它们不是实例方法。一个“纯”的OO语言将所有东西都作为一个对象,所有函数都是实例方法。当然,这并不是一直都非常有用。例如,考虑 Math.atan2 方法。它需要两个数字,不需要任何状态。你能把它变成一个方法吗? 属于 ?在“纯”的OO语言中, Math 可能本身就是一个对象(可能是单例),并且 atan2 将是一个实例方法,但由于函数实际上不使用 数学 对象,它也不是一个“纯OO”的概念。

        4
  •  7
  •   Ilia Anastassov    7 年前

    静态方法会导致紧密耦合,这违反了良好的面向对象设计。由于静态方法本身不支持面向对象的设计技术,如继承和多态性,因此无法通过依赖倒置避免调用代码与静态方法中的代码之间的紧密耦合。

    此外,由于这些紧密耦合的依赖关系,静态方法很难测试,这通常会导致代码所依赖的第三方基础设施(如数据库),这使得在不实际进入和更改代码的情况下更改行为非常困难。

        5
  •  3
  •   Gul Ershad    7 年前

    静态方法不被视为良好的OO实践,原因如下:

    1)防止重复使用:

    静态方法不能被重写。在接口中不能使用它。

    2)对象寿命很长:

    静态方法在内存中保留一段日志时间,它的垃圾收集需要很长时间。开发人员无法控制静态变量的销毁或创建。 静态变量的过度使用可能导致内存溢出。

    3)还有其他几点:

    它不尊重封装,因为对象不在其状态的完全控制中。它不遵循控制反转、松耦合、依赖注入等概念。

        6
  •  1
  •   Luis Miguel Serrano    14 年前

    静态方法不是那么纯粹的OO概念,因为它们可以在没有实际关联对象的情况下被调用。您使用类本身。你这样调用它们 Classname.method(...);

        7
  •  0
  •   Koteswara sarma    14 年前

    OO的概念是关于从对象控制/访问数据,但是静态方法不需要使用对象来调用,它们属于类而不是对象。

    ——欢呼