C#和Java是否支持静态类型?

3

我一直使用单例类和静态方法,但总是想过如果有一个独立的类型是静态类型且不能实例化,只有静态方法该多好啊!

这样做可以提高可读性和易于维护。

例如:

public UtilType MyUtility
{
  public void Calculate(int x,int y)
  {
    return x+y;
  }
}

MyUtility 不应该允许被实例化,只能以静态方式访问它的方法。


不要依赖单例!它们仅在类加载器内部唯一,当然也只有一个JVM。 - CurtainDog
@CurtainDog:对于一个只是一组没有状态的静态方法的实用程序类来说,这似乎不是问题。 - Thilo
8个回答

9

在C#中,您可以使用static关键字来实现:

public static class MyUtility
{
    public static void Calculate(int x,int y)
    {
        return x+y;
    }
}

这将使您能够编写

var result = MyUtility.Calculate(1, 2);

在你的代码中到处都是它。

然而,它并不是非常面向对象,因此应该始终考虑是否有更好的替代方案。面向对象设计关注的是数据和行为,而这样的静态类则是纯行为。这几乎与纯数据类一样糟糕,但通常二者会同时出现。

我个人认为过度使用静态类型是一种代码异味


2
我不同意这个。 你难道不经常有一段代码,仅仅进行纯计算而不改变非静态对象的值吗? 总是需要静态方法。或者至少我发现很多次这样的情况。 - Ravisha
3
你是否认为 LINQ 整体都是代码异味?那纯函数式编程语言呢? - yfeldblum
2
@Justice:不,我不认为LINQ是代码异味,但从更大的角度来看,它们实际上可能是,因为它们充当了mixin的替代品。当涉及到函数式语言时,这是一个不同的讨论 - static在OOD中是一种代码异味。静态(或共享)状态的概念在FP中或多或少是无意义的,因为一切都是不可变的 - 没有状态。 - Mark Seemann
@Mark,我已经提到这是关于纯计算的问题,需要将方法设置为静态。我认为在良好的设计中,不会在静态方法中进行对象更改,因此代码味道在这里似乎不相关。 - Ravisha
2
请记住,“代码异味”一词表示某个特定的代码段需要进一步调查。该代码可能最终表现良好,但平均而言通常不是这样。纯计算往往证明是例外,证明了规则,但就我个人而言,我非常少需要实现实现纯计算的类,因为我的类库已经提供了我所需的功能。当然,如果您处理高级数学,则您的情况可能完全不同于我,这种情况下,可能需要使用静态类。 - Mark Seemann
显示剩余2条评论

5

你试过使用静态类型吗?

public static class MyUtility
{
    public static void Calculate(int x,int y)
    {
        return x+y;
    }
}

并且...

public class AnyOtherClass
{
     public void AnyOtherMethod()
     {
          MyUtility.Calculate(4,5);
     }
}

2

优化 masher 的回答:

public final class Utilities
{
 // private constructor
 private Utilities(){ }

 public static int add(int x, int y)
 {
  return x+y;
 }

 public static int subtract(int x, int y)
 {
  return x-y;
 }
}

1
为什么C#和Java不支持util类型?
回答你的问题,我们无法读取C#和Java设计者的想法,所以我们只能推断他们不支持“utility”类的原因。但这些原因可能包括:
- Utility类不是面向对象的,在良好设计的OO应用程序中很少使用。 - 它们在语义上是冗余的。您可以编写一个普通类,使其无法实例化,这是一个utility类唯一本质上不同的事情。 - 将常规类转换为“utility”类的编码工作微不足道。例如,在Java中,它只需要一行代码,即一个私有的无参构造函数。
由于utility类在语义上是冗余的,在当前指定的Java / C#中很少使用,并且在编码方面也很容易,因此没有真正的理由添加语法糖来支持它们。
即使这是个好主意,进行这样的更改的缺点也包括:
  • 修改语言规范、编译器及相关工具、教程和教材等的巨大成本。

  • 添加新关键字对现有Java/C#客户应用程序代码库的影响。

  • 添加新类别变量会增加学习该语言的难度。


0

不必创建私有构造函数,您可以使用枚举类型(默认情况下具有私有构造函数)。

public enum Utilities {
   ; 

   public static int add(int x, int y) { 
      return x+y; 
   } 

   public static int subtract(int x, int y) { 
      return x-y; 
   } 
} 

注意:需要一个单独的分号来表示枚举没有任何值。

@Peter 这个比有私有构造函数的类好吗?(除了默认构造函数) - Ravisha

0

为什么这个不起作用?(使用Java)

public class Utilities
{
   private Utilities() {} //added in an edit after reading comments

   public static int add(int x, int y)
   {
      return x+y;
   }

   public static int subtract(int x, int y)
   {
      return x-y;
   }
}

现在你不能实例化它,它只有静态方法...


实际上,您可以使用默认构造函数对其进行实例化。防止实例化的正常方法是声明一个无参数的私有构造函数。 - Stephen C
为什么这不起作用?我猜它会起作用。除了上面的代码,尝试再加一个私有构造函数。 - Rakesh Juyal
好的,你可以实例化它(因为有默认构造函数)。但我不明白为什么这会成为一个问题。 - Thilo
@Stephen:http://lh3.ggpht.com/_2VEaTPMR9yw/So75itBGUSI/AAAAAAAAAUQ/5c2iup4N3EM/funny_cow_picture_moo%5B2%5D.jpg - Rakesh Juyal
@Rakesh 这更像是一个修辞问题。我假设 OP 已经尝试过这个了。 - masher

0

如何声明一个私有构造函数?

public class MyUtility
{
    private MyUtility ( )
    {
    }

    public static int calculate(int x,int y)
    {
        return x+y;
    }
}

使用Java 5+,甚至可以使用静态导入。

...
import static MyUtility.calculate

...
void myMethod ( )
{
  int sum = calculate( 1, 2 );
}

1
我同意这是可能的。我的问题是关于拥有一个新类型。我并不排除使用现有方法来实现这一点的可能性。 - Ravisha
在C# 3.0+中,使用私有构造函数本质上与声明静态类是相同的。 - Ian P

-1

我认为对于原始问题的答案是,两种语言都是面向对象的。因此,对象是一等公民,即一切都是对象。

这就是语言的设计方式,它的预期使用方式以及编译器如何将代码部分链接起来创建程序的方式。

static有助于使我们的生活更轻松,但有时我们必须为此付出代价。例如,当您希望覆盖静态方法时。


这个解释与问题有什么关联?这似乎更像是一般性的观点。 - Ravisha
最初的问题大致是:为什么Java/C#不支持实用方法?即在类外定义并静态调用的方法。后来进行了编辑。 - Ahmed Abdelkader
已回滚问题标签。感谢通知。 - Ravisha
@ahmadabdolkader 但我仍然在谈论拥有一个单独的类型(一种既不是静态的也不是可实例化的新类型)。 - Ravisha
我明白了。我之前以为你在寻找对你问题的答案。我猜这更像是一个新功能的请求。 - Ahmed Abdelkader
有关投反对票的论据?至少这与所选答案相似。 - Ahmed Abdelkader

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接