Why was C# designed this way?
为什么C#这样设计?
As I understand it, an interface only describes behaviour, and serves the purpose of describing a contractual obligation for classes implementing the interface that certain behaviour is implemented.
据我所知,接口只描述行为,并且用于描述实现某些行为的接口的类的合同义务。
If classes wish to implement that behavour in a shared method, why shouldn't they?
如果类希望在共享方法中实现该行为,为什么不应该这样做呢?
Here is an example of what I have in mind:
这是我想到的一个例子:
// These items will be displayed in a list on the screen.
public interface IListItem {
string ScreenName();
...
}
public class Animal: IListItem {
// All animals will be called "Animal".
public static string ScreenName() {
return "Animal";
}
....
}
public class Person: IListItem {
private string name;
// All persons will be called by their individual names.
public string ScreenName() {
return name;
}
....
}
24 个解决方案
#1
206
Assuming you are asking why you can't do this:
假设你问为什么你不能这样做:
public interface IFoo {
void Bar();
}
public class Foo: IFoo {
public static void Bar() {}
}
This doesn't make sense to me, semantically. Methods specified on an interface should be there to specify the contract for interacting with an object. Static methods do not allow you to interact with an object - if you find yourself in the position where your implementation could be made static, you may need to ask yourself if that method really belongs in the interface.
从语义上讲,这对我来说没有意义。接口上指定的方法应该用于指定与对象交互的契约。静态方法不允许您与对象进行交互 - 如果您发现自己处于静态实现的位置,您可能需要问自己该方法是否真的属于接口。
To implement your example, I would give Animal a const property, which would still allow it to be accessed from a static context, and return that value in the implementation.
public class Animal: IListItem {
/* Can be tough to come up with a different, yet meaningful name!
* A different casing convention, like Java has, would help here.
*/
public const string AnimalScreenName = "Animal";
public string ScreenName(){ return AnimalScreenName; }
}
For a more complicated situation, you could always declare another static method and delegate to that. In trying come up with an example, I couldn't think of any reason you would do something non-trivial in both a static and instance context, so I'll spare you a FooBar blob, and take it as an indication that it might not be a good idea.
对于更复杂的情况,您可以始终声明另一个静态方法并委托给它。在尝试提出一个例子的时候,我想不出有什么理由你会在静态和实例上下文中做一些非平凡的事情,所以我会给你一个FooBar blob,并把它作为一个迹象表明它可能不是个好主意。
#2
155
My (simplified) technical reason is that static methods are not in the vtable, and the call site is chosen at compile time. It's the same reason you can't have override or virtual static members. For more details, you'd need a CS grad or compiler wonk - of which I'm neither.
我(简化)的技术原因是静态方法不在vtable中,并且在编译时选择了调用站点。这与您不能拥有覆盖或虚拟静态成员的原因相同。有关更多详细信息,您需要一个CS毕业或编译器 - 我不是。
For the political reason, I'll quote Eric Lippert (who is a compiler wonk, and holds a Bachelor of Mathematics, Computer science and Applied Mathematics from University of Waterloo (source: LinkedIn):
出于政治原因,我引用Eric Lippert(他是一名编译器,并拥有滑铁卢大学的数学,计算机科学和应用数学学士学位(来源:LinkedIn):
...the core design principle of static methods, the principle that gives them their name...[is]...it can always be determined exactly, at compile time, what method will be called. That is, the method can be resolved solely by static analysis of the code.
...静态方法的核心设计原则,给它们起名字的原则...... [是] ......总是可以在编译时确切地确定将调用什么方法。也就是说,该方法可以仅通过代码的静态分析来解决。
Note that Lippert does leave room for a so-called type method:
请注意,Lippert确实为所谓的类型方法留出了空间:
That is, a method associated with a type (like a static), which does not take a non-nullable “this” argument (unlike an instance or virtual), but one where the method called would depend on the constructed type of T (unlike a static, which must be determinable at compile time).
也就是说,一个与类型(如静态)相关联的方法,它不采用不可为空的“this”参数(与实例或虚拟不同),但调用的方法取决于构造的T类型(不像静态,它必须在编译时可以确定)。
but is yet to be convinced of its usefulness.
但尚未确信其有用性。
#3
86
Most answers here seem to miss the whole point. Polymorphism can be used not only between instances, but also between types. This is often needed, when we use generics.
这里的大多数答案似乎都错过了重点。多态性不仅可以在实例之间使用,也可以在类型之间使用。当我们使用泛型时,通常需要这样做。
Suppose we have type parameter in generic method and we need to do some operation with it. We dont want to instantinate, because we are unaware of the constructors.
假设我们在泛型方法中有类型参数,我们需要用它做一些操作。我们不想立即,因为我们不知道构造函数。
For example:
Repository GetRepository<T>()
{
//need to call T.IsQueryable, but can't!!!
//need to call T.RowCount
//need to call T.DoSomeStaticMath(int param)
}
...
var r = GetRepository<Customer>()
Unfortunately, I can come up only with "ugly" alternatives:
不幸的是,我只能提出“丑陋”的选择:
-
Use reflection Ugly and beats the idea of interfaces and polymorphism.
使用反射Ugly并击败接口和多态的想法。
-
Create completely separate factory class
创建完全独立的工厂类
This might greatly increase the complexity of the code. For example, if we are trying to model domain objects, each object would need another repository class.
这可能会大大增加代码的复杂性。例如,如果我们尝试为域对象建模,则每个对象都需要另一个存储库类。
-
Instantiate and then call the desired interface method
实例化然后调用所需的接口方法
This can be hard to implement even if we control the source for the classes, used as generic parameters. The reason is that, for example we might need the instances to be only in well-known, "connected to DB" state.
即使我们控制用作通用参数的类的源,这也很难实现。原因是,例如,我们可能需要实例仅在众所周知的“连接到DB”状态。
Example:
public class Customer
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
void SomeOtherMethod()
{
//do work...
}
}
in order to use instantination for solving the static interface problem we need to do the following thing:
为了使用即时解决方案解决静态接口问题,我们需要做以下事情:
public class Customer: IDoSomeStaticMath
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
//dummy instance
public Customer() { IsDummy = true; }
int DoSomeStaticMath(int a) { }
void SomeOtherMethod()
{
if(!IsDummy)
{
//do work...
}
}
}
This is obviously ugly and also unnecessary complicates the code for all other methods. Obviously, not an elegant solution either!
这显然是丑陋的,并且不必要使所有其他方法的代码复杂化。显然,也不是一个优雅的解决方案!
#4
18
I know it's an old question, but it's interesting. The example isn't the best. I think it would be much clearer if you showed a usage case:
我知道这是一个老问题,但它很有趣。这个例子不是最好的。如果你展示一个用例,我认为会更清楚:
string DoSomething<T>() where T:ISomeFunction { if (T.someFunction()) ... }
Merely being able to have static methods implement an interface would not achieve what you want; what would be needed would be to have static members as part of an interface. I can certainly imagine many usage cases for that, especially when it comes to being able to create things. Two approaches I could offer which might be helpful:
仅仅能够使用静态方法实现接口将无法达到您想要的效果;我们需要的是将静态成员作为接口的一部分。我当然可以想象许多用例,特别是在能够创建东西时。我可以提供的两种方法可能会有所帮助:
- Create a static generic class whose type parameter will be the type you'd be passing to DoSomething above. Each variation of this class will have one or more static members holding stuff related to that type. This information could supplied either by having each class of interest call a "register information" routine, or by using Reflection to get the information when the class variation's static constructor is run. I believe the latter approach is used by things like Comparer<T>.Default().
- For each class T of interest, define a class or struct which implements IGetWhateverClassInfo<T> and satisfies a "new" constraint. The class won't actually contain any fields, but will have a static property which returns a static field with the type information. Pass the type of that class or struct to the generic routine in question, which will be able to create an instance and use it to get information about the other class. If you use a class for this purpose, you should probably define a static generic class as indicated above, to avoid having to construct a new descriptor-object instance each time. If you use a struct, instantiation cost should be nil, but every different struct type would require a different expansion of the DoSomething routine.
创建一个静态泛型类,其类型参数将是您要传递给上面的DoSomething的类型。此类的每个变体都有一个或多个静态成员,其中包含与该类型相关的内容。可以通过让每个兴趣类调用“寄存器信息”例程,或者通过使用Reflection在运行类变体的静态构造函数时获取信息来提供此信息。我相信后者的方法被Comparer
对于每个感兴趣的类T,定义实现IGetWhateverClassInfo
None of these approaches is really appealing. On the other hand, I would expect that if the mechanisms existed in CLR to provide this sort of functionality cleanly, .net would allow one to specify parameterized "new" constraints (since knowing if a class has a constructor with a particular signature would seem to be comparable in difficulty to knowing if it has a static method with a particular signature).
这些方法都没有真正吸引人。另一方面,我希望如果CLR中存在的机制能够干净地提供这种功能,.net将允许指定参数化的“新”约束(因为知道类是否具有带特定签名的构造函数)难以比较知道它是否具有带特定签名的静态方法)。
#5
14
Interfaces specify behavior of an object.
接口指定对象的行为。
Static methods do not specify a behavior of an object, but behavior that affects an object in some way.
静态方法不指定对象的行为,而是指定以某种方式影响对象的行为。
#6
13
Short-sightedness, I'd guess.
我猜是近视。
When originally designed, interfaces were intended only to be used with instances of class
最初设计时,接口仅用于类的实例
IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();
It was only with the introduction of interfaces as constraints for generics did adding a static method to an interface have a practical use.
只有在引入接口作为泛型的约束时,向接口添加静态方法才具有实际用途。
(responding to comment:) I believe changing it now would require a change to the CLR, which would lead to incompatibilities with existing assemblies.
(回复评论:)我认为现在更改它需要更改CLR,这将导致与现有程序集不兼容。
#7
12
To the extent that interfaces represent "contracts", it seems quiet reasonable for static classes to implement interfaces.
在接口表示“契约”的范围内,静态类实现接口似乎安静合理。
The above arguments all seem to miss this point about contracts.
上述论点似乎都错过了关于合同的这一点。
#8
8
Because the purpose of an interface is to allow polymorphism, being able to pass an instance of any number of defined classes that have all been defined to implement the defined interface... guaranteeing that within your polymorphic call, the code will be able to find the method you are calling. it makes no sense to allow a static method to implement the interface,
因为接口的目的是允许多态,能够传递任何已定义的定义的类的实例以实现定义的接口...保证在您的多态调用中,代码将能够找到你打电话的方法。允许静态方法实现接口是没有意义的,
How would you call it??
你怎么称呼它?
public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
public static void MyMethod() { //Do Something; }
}
// inside of some other class ...
// How would you call the method on the interface ???
MyClass.MyMethod(); // this calls the method normally
// not through the interface...
// This next fails you can't cast a classname to a different type...
// Only instances can be Cast to a different type...
MyInterface myItf = MyClass as MyInterface;
#9
4
Regarding static methods used in non-generic contexts I agree that it doesn't make much sense to allow them in interfaces, since you wouldn't be able to call them if you had a reference to the interface anyway. However there is a fundamental hole in the language design created by using interfaces NOT in a polymorphic context, but in a generic one. In this case the interface is not an interface at all but rather a constraint. Because C# has no concept of a constraint outside of an interface it is missing substantial functionality. Case in point:
关于在非泛型上下文中使用的静态方法,我同意在接口中允许它们没有多大意义,因为如果你有对接口的引用,你将无法调用它们。然而,在多态上下文中使用接口而不是通用接口创建的语言设计中存在一个基本漏洞。在这种情况下,接口根本不是接口,而是约束。因为C#在接口之外没有约束的概念,所以缺少实质的功能。例证:
T SumElements<T>(T initVal, T[] values)
{
foreach (var v in values)
{
initVal += v;
}
}
Here there is no polymorphism, the generic uses the actual type of the object and calls the += operator, but this fails since it can't say for sure that that operator exists. The simple solution is to specify it in the constraint; the simple solution is impossible because operators are static and static methods can't be in an interface and (here is the problem) constraints are represented as interfaces.
这里没有多态,泛型使用对象的实际类型并调用+ =运算符,但由于无法确定该运算符是否存在而失败。简单的解决方案是在约束中指定它;简单的解决方案是不可能的,因为运算符是静态的,静态方法不能在接口中,并且(这里是问题)约束被表示为接口。
What C# needs is a real constraint type, all interfaces would also be constraints, but not all constraints would be interfaces then you could do this:
C#需要的是一个真正的约束类型,所有接口也都是约束,但并非所有约束都是接口,那么你可以这样做:
constraint CHasPlusEquals
{
static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}
T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
foreach (var v in values)
{
initVal += v;
}
}
There has been lots of talk already about making an IArithmetic for all numeric types to implement, but there is concern about efficiency, since a constraint is not a polymorphic construct, making a CArithmetic constraint would solve that problem.
已经有很多关于为所有数值类型实现IA算术的讨论,但是关注效率,因为约束不是多态构造,使得CA算术约束可以解决该问题。
#10
3
Because interfaces are in inheritance structure, and static methods don't inherit well.
因为接口是继承结构,静态方法不能很好地继承。
#11
3
What you seem to want would allow for a static method to be called via both the Type or any instance of that type. This would at very least result in ambiguity which is not a desirable trait.
您似乎想要的是允许通过Type或该类型的任何实例调用静态方法。这至少会导致歧义,这不是一个理想的特征。
There would be endless debates about whether it mattered, which is best practice and whether there are performance issues doing it one way or another. By simply not supporting it C# saves us having to worry about it.
关于它是否重要,这将是无休止的争论,这是最佳实践以及是否存在以这种或那种方式表现的性能问题。通过简单地不支持C#,我们不必担心它。
Its also likely that a compilier that conformed to this desire would lose some optimisations that may come with a more strict separation between instance and static methods.
它也可能是符合这种愿望的编译器会失去一些优化,可能会在实例和静态方法之间进行更严格的分离。
#12
3
You can think of the static methods and non-static methods of a class as being different interfaces. When called, static methods resolve to the singleton static class object, and non-static methods resolve to the instance of the class you deal with. So, if you use static and non-static methods in an interface, you'd effectively be declaring two interfaces when really we want interfaces to be used to access one cohesive thing.
您可以将类的静态方法和非静态方法视为不同的接口。调用时,静态方法将解析为单例静态类对象,而非静态方法将解析为您处理的类的实例。因此,如果在接口中使用静态和非静态方法,那么当我们真正希望使用接口来访问一个有凝聚力的东西时,您实际上会声明两个接口。
#13
3
To give an example where I am missing either static implementation of interface methods or what Mark Brackett introduced as the "so-called type method":
举一个例子,我缺少接口方法的静态实现或Mark Brackett引入的“所谓的类型方法”:
When reading from a database storage, we have a generic DataTable class that handles reading from a table of any structure. All table specific information is put in one class per table that also holds data for one row from the DB and which must implement an IDataRow interface. Included in the IDataRow is a description of the structure of the table to read from the database. The DataTable must ask for the datastructure from the IDataRow before reading from the DB. Currently this looks like:
从数据库存储中读取时,我们有一个通用的DataTable类,它处理从任何结构的表中读取。所有特定于表的信息都放在每个表的一个类中,该类还包含来自DB的一行的数据,并且必须实现IDataRow接口。 IDataRow中包含要从数据库中读取的表结构的描述。在从DB读取之前,DataTable必须从IDataRow请求数据结构。目前看起来像:
interface IDataRow {
string GetDataSTructre(); // How to read data from the DB
void Read(IDBDataRow); // How to populate this datarow from DB data
}
public class DataTable<T> : List<T> where T : IDataRow {
public string GetDataStructure()
// Desired: Static or Type method:
// return (T.GetDataStructure());
// Required: Instantiate a new class:
return (new T().GetDataStructure());
}
}
The GetDataStructure is only required once for each table to read, the overhead for instantiating one more instance is minimal. However, it would be nice in this case here.
GetDataStructure只需要每个表读取一次,实例化一个或多个实例的开销很小。但是,在这种情况下,这将是很好的。
#14
1
FYI: You could get a similar behavior to what you want by creating extension methods for the interface. The extension method would be a shared, non overridable static behavior. However, unfortunately, this static method would not be part of the contract.
仅供参考:您可以通过为界面创建扩展方法来获得与您想要的类似的行为。扩展方法将是共享的,不可覆盖的静态行为。然而,遗憾的是,这种静态方法不会成为合同的一部分。
#15
1
Interfaces are abstract sets of defined available functionality.
接口是定义的可用功能的抽象集。
Whether or not a method in that interface behaves as static or not is an implementation detail that should be hidden behind the interface. It would be wrong to define an interface method as static because you would be unnecessarily forcing the method to be implemented in a certain way.
该接口中的方法是否表现为静态是应该隐藏在接口后面的实现细节。将接口方法定义为静态是错误的,因为您会不必要地强制以某种方式实现该方法。
If methods were defined as static, the class implementing the interface wouldn't be as encapsulated as it could be. Encapsulation is a good thing to strive for in object oriented design (I won't go into why, you can read that here: http://en.wikipedia.org/wiki/Object-oriented). For this reason, static methods aren't permitted in interfaces.
如果将方法定义为static,则实现接口的类将不会像它那样封装。在面向对象的设计中,封装是一件好事(我不会理解为什么,你可以在这里阅读:http://en.wikipedia.org/wiki/Object-oriented)。因此,接口中不允许使用静态方法。
#16
1
Static classes should be able to do this so they can be used generically. I had to instead implement a Singleton to achieve the desired results.
静态类应该能够这样做,因此可以一般地使用它们。我不得不实现Singleton来实现预期的结果。
I had a bunch of Static Business Layer classes that implemented CRUD methods like "Create", "Read", "Update", "Delete" for each entity type like "User", "Team", ect.. Then I created a base control that had an abstract property for the Business Layer class that implemented the CRUD methods. This allowed me to automate the "Create", "Read", "Update", "Delete" operations from the base class. I had to use a Singleton because of the Static limitation.
我有一堆静态业务层类,为每个实体类型(如“用户”,“团队”等)实现CRUD方法,如“创建”,“读取”,“更新”,“删除”等。然后我创建了一个基础具有实现CRUD方法的Business Layer类的抽象属性的控件。这使我能够从基类自动化“创建”,“读取”,“更新”,“删除”操作。由于静态限制,我不得不使用Singleton。
#17
1
Most people seem to forget that in OOP Classes are objects too, and so they have messages, which for some reason c# calls "static method". The fact that differences exist between instance objects and class objects only shows flaws or shortcomings in the language. Optimist about c# though...
大多数人似乎忘记了在OOP中类也是对象,因此它们有消息,由于某种原因c#调用“静态方法”。实例对象和类对象之间存在差异的事实只显示语言中的缺陷或缺点。关于c#的乐观主义者虽然......
#18
1
The fact that a static class is implemented in C# by Microsoft creating a special instance of a class with the static elements is just an oddity of how static functionality is achieved. It is isn't a theoretical point.
事实上,在C#中通过Microsoft使用静态元素创建类的特殊实例来实现静态类,这实际上是如何实现静态功能的一个奇怪之处。这不是一个理论观点。
An interface SHOULD be a descriptor of the class interface - or how it is interacted with, and that should include interactions that are static. The general definition of interface (from Meriam-Webster): the place or area at which different things meet and communicate with or affect each other. When you omit static components of a class or static classes entirely, we are ignoring large sections of how these bad boys interact.
接口应该是类接口的描述符 - 或者它如何与之交互,并且应该包括静态的交互。界面的一般定义(来自Meriam-Webster):不同事物相遇或相互沟通或相互影响的地方或区域。当你完全忽略类的静态组件或静态类时,我们忽略了这些坏男孩如何交互的大部分内容。
Here is a very clear example of where being able to use interfaces with static classes would be quite useful:
这是一个非常明确的例子,说明在哪里使用静态类的接口会非常有用:
public interface ICrudModel<T, Tk>
{
Boolean Create(T obj);
T Retrieve(Tk key);
Boolean Update(T obj);
Boolean Delete(T obj);
}
Currently, I write the static classes that contain these methods without any kind of checking to make sure that I haven't forgotten anything. Is like the bad old days of programming before OOP.
目前,我编写包含这些方法的静态类,没有任何检查,以确保我没有忘记任何东西。就像在OOP之前编程的糟糕时光。
#19
1
C# and the CLR should support static methods in interfaces as Java does. The static modifier is part of a contract definition and does have meaning, specifically that the behavior and return value do not vary base on instance although it may still vary from call to call.
C#和CLR应该像Java那样支持接口中的静态方法。 static修饰符是契约定义的一部分,并且具有含义,特别是行为和返回值不会根据实例而变化,尽管它可能因呼叫而异。
That said, I recommend that when you want to use a static method in an interface and cannot, use an annotation instead. You will get the functionality you are looking for.
也就是说,我建议当你想在界面中使用静态方法而不能使用静态方法时,请使用注释。您将获得所需的功能。
#20
0
I think the short answer is "because it is of zero usefulness". To call an interface method, you need an instance of the type. From instance methods you can call any static methods you want to.
我认为简短的回答是“因为它没有用处”。要调用接口方法,您需要一个类型的实例。从实例方法中,您可以调用任何您想要的静态方法。
#21
0
OK here is an example of needing a 'type method'. I am creating one of a set of classes based on some source XML. So I have a
好的,这是一个需要'类型方法'的例子。我正在基于一些源XML创建一组类中的一个。所以我有一个
static public bool IsHandled(XElement xml)
function which is called in turn on each class.
在每个班级依次调用的函数。
The function should be static as otherwise we waste time creating inappropriate objects. As @Ian Boyde points out it could be done in a factory class, but this just adds complexity.
该函数应该是静态的,否则我们会浪费时间创建不适当的对象。至于@Ian Boyde指出它可以在工厂类中完成,但这只会增加复杂性。
It would be nice to add it to the interface to force class implementors to implement it. This would not cause significant overhead - it is only a compile/link time check and does not affect the vtable.
将它添加到接口以强制类实现者实现它会很好。这不会导致显着的开销 - 它只是一个编译/链接时间检查,不会影响vtable。
However, it would also be a fairly minor improvement. As the method is static, I as the caller, must call it explicitly and so get an immediate compile error if it is not implemented. Allowing it to be specified on the interface would mean this error comes marginally earlier in the development cycle, but this is trivial compared to other broken-interface issues.
但是,这也是一个相当小的改进。由于该方法是静态的,因此我作为调用者必须显式调用它,因此如果未实现则立即获得编译错误。允许在接口上指定它将意味着此错误在开发周期中稍早出现,但与其他破坏接口问题相比,这是微不足道的。
So it is a minor potential feature which on balance is probably best left out.
所以这是一个次要的潜在特征,总的来说可能是最好的遗漏。
#22
0
I think the question is getting at the fact that C# needs another keyword, for precisely this sort of situation. You want a method whose return value depends only on the type on which it is called. You can't call it "static" if said type is unknown. But once the type becomes known, it will become static. "Unresolved static" is the idea -- it's not static yet, but once we know the receiving type, it will be. This is a perfectly good concept, which is why programmers keep asking for it. But it didn't quite fit into the way the designers thought about the language.
我认为问题在于C#需要另一个关键字,正是因为这种情况。您需要一个方法,其返回值仅取决于调用它的类型。如果所述类型未知,则不能将其称为“静态”。但是一旦知道这种类型,它就会变得静止。 “未解决的静态”是这个想法 - 它还不是静态的,但是一旦我们知道接收类型,它就会是。这是一个非常好的概念,这就是程序员不断要求它的原因。但它并不完全符合设计师对语言的看法。
Since it's not available, I have taken to using non-static methods in the way shown below. Not exactly ideal, but I can't see any approach that makes more sense, at least not for me.
由于它不可用,我已采用下面显示的方式使用非静态方法。不完全理想,但我看不出任何更有意义的方法,至少不适合我。
public interface IZeroWrapper<TNumber> {
TNumber Zero {get;}
}
public class DoubleWrapper: IZeroWrapper<double> {
public double Zero { get { return 0; } }
}
#23
0
As per Object oriented concept Interface implemented by classes and have contract to access these implemented function(or methods) using object.
根据面向对象的概念由类实现的接口,并具有使用对象访问这些实现的函数(或方法)的契约。
So if you want to access Interface Contract methods you have to create object. It is always must that is not allowed in case of Static methods. Static classes ,method and variables never require objects and load in memory without creating object of that area(or class) or you can say do not require Object Creation.
因此,如果要访问Interface Contract方法,则必须创建对象。在静态方法的情况下,始终必须不允许这样做。静态类,方法和变量从不需要对象并在内存中加载而不创建该区域(或类)的对象,或者您可以说不需要对象创建。
#24
0
When a class implements an interface,it is creating instance for the interface members. While a static type doesnt have an instance,there is no point in having static signatures in an interface.
当类实现接口时,它正在为接口成员创建实例。虽然静态类型没有实例,但在接口中使用静态签名没有意义。
#1
206
Assuming you are asking why you can't do this:
假设你问为什么你不能这样做:
public interface IFoo {
void Bar();
}
public class Foo: IFoo {
public static void Bar() {}
}
This doesn't make sense to me, semantically. Methods specified on an interface should be there to specify the contract for interacting with an object. Static methods do not allow you to interact with an object - if you find yourself in the position where your implementation could be made static, you may need to ask yourself if that method really belongs in the interface.
从语义上讲,这对我来说没有意义。接口上指定的方法应该用于指定与对象交互的契约。静态方法不允许您与对象进行交互 - 如果您发现自己处于静态实现的位置,您可能需要问自己该方法是否真的属于接口。
To implement your example, I would give Animal a const property, which would still allow it to be accessed from a static context, and return that value in the implementation.
public class Animal: IListItem {
/* Can be tough to come up with a different, yet meaningful name!
* A different casing convention, like Java has, would help here.
*/
public const string AnimalScreenName = "Animal";
public string ScreenName(){ return AnimalScreenName; }
}
For a more complicated situation, you could always declare another static method and delegate to that. In trying come up with an example, I couldn't think of any reason you would do something non-trivial in both a static and instance context, so I'll spare you a FooBar blob, and take it as an indication that it might not be a good idea.
对于更复杂的情况,您可以始终声明另一个静态方法并委托给它。在尝试提出一个例子的时候,我想不出有什么理由你会在静态和实例上下文中做一些非平凡的事情,所以我会给你一个FooBar blob,并把它作为一个迹象表明它可能不是个好主意。
#2
155
My (simplified) technical reason is that static methods are not in the vtable, and the call site is chosen at compile time. It's the same reason you can't have override or virtual static members. For more details, you'd need a CS grad or compiler wonk - of which I'm neither.
我(简化)的技术原因是静态方法不在vtable中,并且在编译时选择了调用站点。这与您不能拥有覆盖或虚拟静态成员的原因相同。有关更多详细信息,您需要一个CS毕业或编译器 - 我不是。
For the political reason, I'll quote Eric Lippert (who is a compiler wonk, and holds a Bachelor of Mathematics, Computer science and Applied Mathematics from University of Waterloo (source: LinkedIn):
出于政治原因,我引用Eric Lippert(他是一名编译器,并拥有滑铁卢大学的数学,计算机科学和应用数学学士学位(来源:LinkedIn):
...the core design principle of static methods, the principle that gives them their name...[is]...it can always be determined exactly, at compile time, what method will be called. That is, the method can be resolved solely by static analysis of the code.
...静态方法的核心设计原则,给它们起名字的原则...... [是] ......总是可以在编译时确切地确定将调用什么方法。也就是说,该方法可以仅通过代码的静态分析来解决。
Note that Lippert does leave room for a so-called type method:
请注意,Lippert确实为所谓的类型方法留出了空间:
That is, a method associated with a type (like a static), which does not take a non-nullable “this” argument (unlike an instance or virtual), but one where the method called would depend on the constructed type of T (unlike a static, which must be determinable at compile time).
也就是说,一个与类型(如静态)相关联的方法,它不采用不可为空的“this”参数(与实例或虚拟不同),但调用的方法取决于构造的T类型(不像静态,它必须在编译时可以确定)。
but is yet to be convinced of its usefulness.
但尚未确信其有用性。
#3
86
Most answers here seem to miss the whole point. Polymorphism can be used not only between instances, but also between types. This is often needed, when we use generics.
这里的大多数答案似乎都错过了重点。多态性不仅可以在实例之间使用,也可以在类型之间使用。当我们使用泛型时,通常需要这样做。
Suppose we have type parameter in generic method and we need to do some operation with it. We dont want to instantinate, because we are unaware of the constructors.
假设我们在泛型方法中有类型参数,我们需要用它做一些操作。我们不想立即,因为我们不知道构造函数。
For example:
Repository GetRepository<T>()
{
//need to call T.IsQueryable, but can't!!!
//need to call T.RowCount
//need to call T.DoSomeStaticMath(int param)
}
...
var r = GetRepository<Customer>()
Unfortunately, I can come up only with "ugly" alternatives:
不幸的是,我只能提出“丑陋”的选择:
-
Use reflection Ugly and beats the idea of interfaces and polymorphism.
使用反射Ugly并击败接口和多态的想法。
-
Create completely separate factory class
创建完全独立的工厂类
This might greatly increase the complexity of the code. For example, if we are trying to model domain objects, each object would need another repository class.
这可能会大大增加代码的复杂性。例如,如果我们尝试为域对象建模,则每个对象都需要另一个存储库类。
-
Instantiate and then call the desired interface method
实例化然后调用所需的接口方法
This can be hard to implement even if we control the source for the classes, used as generic parameters. The reason is that, for example we might need the instances to be only in well-known, "connected to DB" state.
即使我们控制用作通用参数的类的源,这也很难实现。原因是,例如,我们可能需要实例仅在众所周知的“连接到DB”状态。
Example:
public class Customer
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
void SomeOtherMethod()
{
//do work...
}
}
in order to use instantination for solving the static interface problem we need to do the following thing:
为了使用即时解决方案解决静态接口问题,我们需要做以下事情:
public class Customer: IDoSomeStaticMath
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
//dummy instance
public Customer() { IsDummy = true; }
int DoSomeStaticMath(int a) { }
void SomeOtherMethod()
{
if(!IsDummy)
{
//do work...
}
}
}
This is obviously ugly and also unnecessary complicates the code for all other methods. Obviously, not an elegant solution either!
这显然是丑陋的,并且不必要使所有其他方法的代码复杂化。显然,也不是一个优雅的解决方案!
#4
18
I know it's an old question, but it's interesting. The example isn't the best. I think it would be much clearer if you showed a usage case:
我知道这是一个老问题,但它很有趣。这个例子不是最好的。如果你展示一个用例,我认为会更清楚:
string DoSomething<T>() where T:ISomeFunction { if (T.someFunction()) ... }
Merely being able to have static methods implement an interface would not achieve what you want; what would be needed would be to have static members as part of an interface. I can certainly imagine many usage cases for that, especially when it comes to being able to create things. Two approaches I could offer which might be helpful:
仅仅能够使用静态方法实现接口将无法达到您想要的效果;我们需要的是将静态成员作为接口的一部分。我当然可以想象许多用例,特别是在能够创建东西时。我可以提供的两种方法可能会有所帮助:
- Create a static generic class whose type parameter will be the type you'd be passing to DoSomething above. Each variation of this class will have one or more static members holding stuff related to that type. This information could supplied either by having each class of interest call a "register information" routine, or by using Reflection to get the information when the class variation's static constructor is run. I believe the latter approach is used by things like Comparer<T>.Default().
- For each class T of interest, define a class or struct which implements IGetWhateverClassInfo<T> and satisfies a "new" constraint. The class won't actually contain any fields, but will have a static property which returns a static field with the type information. Pass the type of that class or struct to the generic routine in question, which will be able to create an instance and use it to get information about the other class. If you use a class for this purpose, you should probably define a static generic class as indicated above, to avoid having to construct a new descriptor-object instance each time. If you use a struct, instantiation cost should be nil, but every different struct type would require a different expansion of the DoSomething routine.
创建一个静态泛型类,其类型参数将是您要传递给上面的DoSomething的类型。此类的每个变体都有一个或多个静态成员,其中包含与该类型相关的内容。可以通过让每个兴趣类调用“寄存器信息”例程,或者通过使用Reflection在运行类变体的静态构造函数时获取信息来提供此信息。我相信后者的方法被Comparer
对于每个感兴趣的类T,定义实现IGetWhateverClassInfo
None of these approaches is really appealing. On the other hand, I would expect that if the mechanisms existed in CLR to provide this sort of functionality cleanly, .net would allow one to specify parameterized "new" constraints (since knowing if a class has a constructor with a particular signature would seem to be comparable in difficulty to knowing if it has a static method with a particular signature).
这些方法都没有真正吸引人。另一方面,我希望如果CLR中存在的机制能够干净地提供这种功能,.net将允许指定参数化的“新”约束(因为知道类是否具有带特定签名的构造函数)难以比较知道它是否具有带特定签名的静态方法)。
#5
14
Interfaces specify behavior of an object.
接口指定对象的行为。
Static methods do not specify a behavior of an object, but behavior that affects an object in some way.
静态方法不指定对象的行为,而是指定以某种方式影响对象的行为。
#6
13
Short-sightedness, I'd guess.
我猜是近视。
When originally designed, interfaces were intended only to be used with instances of class
最初设计时,接口仅用于类的实例
IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();
It was only with the introduction of interfaces as constraints for generics did adding a static method to an interface have a practical use.
只有在引入接口作为泛型的约束时,向接口添加静态方法才具有实际用途。
(responding to comment:) I believe changing it now would require a change to the CLR, which would lead to incompatibilities with existing assemblies.
(回复评论:)我认为现在更改它需要更改CLR,这将导致与现有程序集不兼容。
#7
12
To the extent that interfaces represent "contracts", it seems quiet reasonable for static classes to implement interfaces.
在接口表示“契约”的范围内,静态类实现接口似乎安静合理。
The above arguments all seem to miss this point about contracts.
上述论点似乎都错过了关于合同的这一点。
#8
8
Because the purpose of an interface is to allow polymorphism, being able to pass an instance of any number of defined classes that have all been defined to implement the defined interface... guaranteeing that within your polymorphic call, the code will be able to find the method you are calling. it makes no sense to allow a static method to implement the interface,
因为接口的目的是允许多态,能够传递任何已定义的定义的类的实例以实现定义的接口...保证在您的多态调用中,代码将能够找到你打电话的方法。允许静态方法实现接口是没有意义的,
How would you call it??
你怎么称呼它?
public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
public static void MyMethod() { //Do Something; }
}
// inside of some other class ...
// How would you call the method on the interface ???
MyClass.MyMethod(); // this calls the method normally
// not through the interface...
// This next fails you can't cast a classname to a different type...
// Only instances can be Cast to a different type...
MyInterface myItf = MyClass as MyInterface;
#9
4
Regarding static methods used in non-generic contexts I agree that it doesn't make much sense to allow them in interfaces, since you wouldn't be able to call them if you had a reference to the interface anyway. However there is a fundamental hole in the language design created by using interfaces NOT in a polymorphic context, but in a generic one. In this case the interface is not an interface at all but rather a constraint. Because C# has no concept of a constraint outside of an interface it is missing substantial functionality. Case in point:
关于在非泛型上下文中使用的静态方法,我同意在接口中允许它们没有多大意义,因为如果你有对接口的引用,你将无法调用它们。然而,在多态上下文中使用接口而不是通用接口创建的语言设计中存在一个基本漏洞。在这种情况下,接口根本不是接口,而是约束。因为C#在接口之外没有约束的概念,所以缺少实质的功能。例证:
T SumElements<T>(T initVal, T[] values)
{
foreach (var v in values)
{
initVal += v;
}
}
Here there is no polymorphism, the generic uses the actual type of the object and calls the += operator, but this fails since it can't say for sure that that operator exists. The simple solution is to specify it in the constraint; the simple solution is impossible because operators are static and static methods can't be in an interface and (here is the problem) constraints are represented as interfaces.
这里没有多态,泛型使用对象的实际类型并调用+ =运算符,但由于无法确定该运算符是否存在而失败。简单的解决方案是在约束中指定它;简单的解决方案是不可能的,因为运算符是静态的,静态方法不能在接口中,并且(这里是问题)约束被表示为接口。
What C# needs is a real constraint type, all interfaces would also be constraints, but not all constraints would be interfaces then you could do this:
C#需要的是一个真正的约束类型,所有接口也都是约束,但并非所有约束都是接口,那么你可以这样做:
constraint CHasPlusEquals
{
static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}
T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
foreach (var v in values)
{
initVal += v;
}
}
There has been lots of talk already about making an IArithmetic for all numeric types to implement, but there is concern about efficiency, since a constraint is not a polymorphic construct, making a CArithmetic constraint would solve that problem.
已经有很多关于为所有数值类型实现IA算术的讨论,但是关注效率,因为约束不是多态构造,使得CA算术约束可以解决该问题。
#10
3
Because interfaces are in inheritance structure, and static methods don't inherit well.
因为接口是继承结构,静态方法不能很好地继承。
#11
3
What you seem to want would allow for a static method to be called via both the Type or any instance of that type. This would at very least result in ambiguity which is not a desirable trait.
您似乎想要的是允许通过Type或该类型的任何实例调用静态方法。这至少会导致歧义,这不是一个理想的特征。
There would be endless debates about whether it mattered, which is best practice and whether there are performance issues doing it one way or another. By simply not supporting it C# saves us having to worry about it.
关于它是否重要,这将是无休止的争论,这是最佳实践以及是否存在以这种或那种方式表现的性能问题。通过简单地不支持C#,我们不必担心它。
Its also likely that a compilier that conformed to this desire would lose some optimisations that may come with a more strict separation between instance and static methods.
它也可能是符合这种愿望的编译器会失去一些优化,可能会在实例和静态方法之间进行更严格的分离。
#12
3
You can think of the static methods and non-static methods of a class as being different interfaces. When called, static methods resolve to the singleton static class object, and non-static methods resolve to the instance of the class you deal with. So, if you use static and non-static methods in an interface, you'd effectively be declaring two interfaces when really we want interfaces to be used to access one cohesive thing.
您可以将类的静态方法和非静态方法视为不同的接口。调用时,静态方法将解析为单例静态类对象,而非静态方法将解析为您处理的类的实例。因此,如果在接口中使用静态和非静态方法,那么当我们真正希望使用接口来访问一个有凝聚力的东西时,您实际上会声明两个接口。
#13
3
To give an example where I am missing either static implementation of interface methods or what Mark Brackett introduced as the "so-called type method":
举一个例子,我缺少接口方法的静态实现或Mark Brackett引入的“所谓的类型方法”:
When reading from a database storage, we have a generic DataTable class that handles reading from a table of any structure. All table specific information is put in one class per table that also holds data for one row from the DB and which must implement an IDataRow interface. Included in the IDataRow is a description of the structure of the table to read from the database. The DataTable must ask for the datastructure from the IDataRow before reading from the DB. Currently this looks like:
从数据库存储中读取时,我们有一个通用的DataTable类,它处理从任何结构的表中读取。所有特定于表的信息都放在每个表的一个类中,该类还包含来自DB的一行的数据,并且必须实现IDataRow接口。 IDataRow中包含要从数据库中读取的表结构的描述。在从DB读取之前,DataTable必须从IDataRow请求数据结构。目前看起来像:
interface IDataRow {
string GetDataSTructre(); // How to read data from the DB
void Read(IDBDataRow); // How to populate this datarow from DB data
}
public class DataTable<T> : List<T> where T : IDataRow {
public string GetDataStructure()
// Desired: Static or Type method:
// return (T.GetDataStructure());
// Required: Instantiate a new class:
return (new T().GetDataStructure());
}
}
The GetDataStructure is only required once for each table to read, the overhead for instantiating one more instance is minimal. However, it would be nice in this case here.
GetDataStructure只需要每个表读取一次,实例化一个或多个实例的开销很小。但是,在这种情况下,这将是很好的。
#14
1
FYI: You could get a similar behavior to what you want by creating extension methods for the interface. The extension method would be a shared, non overridable static behavior. However, unfortunately, this static method would not be part of the contract.
仅供参考:您可以通过为界面创建扩展方法来获得与您想要的类似的行为。扩展方法将是共享的,不可覆盖的静态行为。然而,遗憾的是,这种静态方法不会成为合同的一部分。
#15
1
Interfaces are abstract sets of defined available functionality.
接口是定义的可用功能的抽象集。
Whether or not a method in that interface behaves as static or not is an implementation detail that should be hidden behind the interface. It would be wrong to define an interface method as static because you would be unnecessarily forcing the method to be implemented in a certain way.
该接口中的方法是否表现为静态是应该隐藏在接口后面的实现细节。将接口方法定义为静态是错误的,因为您会不必要地强制以某种方式实现该方法。
If methods were defined as static, the class implementing the interface wouldn't be as encapsulated as it could be. Encapsulation is a good thing to strive for in object oriented design (I won't go into why, you can read that here: http://en.wikipedia.org/wiki/Object-oriented). For this reason, static methods aren't permitted in interfaces.
如果将方法定义为static,则实现接口的类将不会像它那样封装。在面向对象的设计中,封装是一件好事(我不会理解为什么,你可以在这里阅读:http://en.wikipedia.org/wiki/Object-oriented)。因此,接口中不允许使用静态方法。
#16
1
Static classes should be able to do this so they can be used generically. I had to instead implement a Singleton to achieve the desired results.
静态类应该能够这样做,因此可以一般地使用它们。我不得不实现Singleton来实现预期的结果。
I had a bunch of Static Business Layer classes that implemented CRUD methods like "Create", "Read", "Update", "Delete" for each entity type like "User", "Team", ect.. Then I created a base control that had an abstract property for the Business Layer class that implemented the CRUD methods. This allowed me to automate the "Create", "Read", "Update", "Delete" operations from the base class. I had to use a Singleton because of the Static limitation.
我有一堆静态业务层类,为每个实体类型(如“用户”,“团队”等)实现CRUD方法,如“创建”,“读取”,“更新”,“删除”等。然后我创建了一个基础具有实现CRUD方法的Business Layer类的抽象属性的控件。这使我能够从基类自动化“创建”,“读取”,“更新”,“删除”操作。由于静态限制,我不得不使用Singleton。
#17
1
Most people seem to forget that in OOP Classes are objects too, and so they have messages, which for some reason c# calls "static method". The fact that differences exist between instance objects and class objects only shows flaws or shortcomings in the language. Optimist about c# though...
大多数人似乎忘记了在OOP中类也是对象,因此它们有消息,由于某种原因c#调用“静态方法”。实例对象和类对象之间存在差异的事实只显示语言中的缺陷或缺点。关于c#的乐观主义者虽然......
#18
1
The fact that a static class is implemented in C# by Microsoft creating a special instance of a class with the static elements is just an oddity of how static functionality is achieved. It is isn't a theoretical point.
事实上,在C#中通过Microsoft使用静态元素创建类的特殊实例来实现静态类,这实际上是如何实现静态功能的一个奇怪之处。这不是一个理论观点。
An interface SHOULD be a descriptor of the class interface - or how it is interacted with, and that should include interactions that are static. The general definition of interface (from Meriam-Webster): the place or area at which different things meet and communicate with or affect each other. When you omit static components of a class or static classes entirely, we are ignoring large sections of how these bad boys interact.
接口应该是类接口的描述符 - 或者它如何与之交互,并且应该包括静态的交互。界面的一般定义(来自Meriam-Webster):不同事物相遇或相互沟通或相互影响的地方或区域。当你完全忽略类的静态组件或静态类时,我们忽略了这些坏男孩如何交互的大部分内容。
Here is a very clear example of where being able to use interfaces with static classes would be quite useful:
这是一个非常明确的例子,说明在哪里使用静态类的接口会非常有用:
public interface ICrudModel<T, Tk>
{
Boolean Create(T obj);
T Retrieve(Tk key);
Boolean Update(T obj);
Boolean Delete(T obj);
}
Currently, I write the static classes that contain these methods without any kind of checking to make sure that I haven't forgotten anything. Is like the bad old days of programming before OOP.
目前,我编写包含这些方法的静态类,没有任何检查,以确保我没有忘记任何东西。就像在OOP之前编程的糟糕时光。
#19
1
C# and the CLR should support static methods in interfaces as Java does. The static modifier is part of a contract definition and does have meaning, specifically that the behavior and return value do not vary base on instance although it may still vary from call to call.
C#和CLR应该像Java那样支持接口中的静态方法。 static修饰符是契约定义的一部分,并且具有含义,特别是行为和返回值不会根据实例而变化,尽管它可能因呼叫而异。
That said, I recommend that when you want to use a static method in an interface and cannot, use an annotation instead. You will get the functionality you are looking for.
也就是说,我建议当你想在界面中使用静态方法而不能使用静态方法时,请使用注释。您将获得所需的功能。
#20
0
I think the short answer is "because it is of zero usefulness". To call an interface method, you need an instance of the type. From instance methods you can call any static methods you want to.
我认为简短的回答是“因为它没有用处”。要调用接口方法,您需要一个类型的实例。从实例方法中,您可以调用任何您想要的静态方法。
#21
0
OK here is an example of needing a 'type method'. I am creating one of a set of classes based on some source XML. So I have a
好的,这是一个需要'类型方法'的例子。我正在基于一些源XML创建一组类中的一个。所以我有一个
static public bool IsHandled(XElement xml)
function which is called in turn on each class.
在每个班级依次调用的函数。
The function should be static as otherwise we waste time creating inappropriate objects. As @Ian Boyde points out it could be done in a factory class, but this just adds complexity.
该函数应该是静态的,否则我们会浪费时间创建不适当的对象。至于@Ian Boyde指出它可以在工厂类中完成,但这只会增加复杂性。
It would be nice to add it to the interface to force class implementors to implement it. This would not cause significant overhead - it is only a compile/link time check and does not affect the vtable.
将它添加到接口以强制类实现者实现它会很好。这不会导致显着的开销 - 它只是一个编译/链接时间检查,不会影响vtable。
However, it would also be a fairly minor improvement. As the method is static, I as the caller, must call it explicitly and so get an immediate compile error if it is not implemented. Allowing it to be specified on the interface would mean this error comes marginally earlier in the development cycle, but this is trivial compared to other broken-interface issues.
但是,这也是一个相当小的改进。由于该方法是静态的,因此我作为调用者必须显式调用它,因此如果未实现则立即获得编译错误。允许在接口上指定它将意味着此错误在开发周期中稍早出现,但与其他破坏接口问题相比,这是微不足道的。
So it is a minor potential feature which on balance is probably best left out.
所以这是一个次要的潜在特征,总的来说可能是最好的遗漏。
#22
0
I think the question is getting at the fact that C# needs another keyword, for precisely this sort of situation. You want a method whose return value depends only on the type on which it is called. You can't call it "static" if said type is unknown. But once the type becomes known, it will become static. "Unresolved static" is the idea -- it's not static yet, but once we know the receiving type, it will be. This is a perfectly good concept, which is why programmers keep asking for it. But it didn't quite fit into the way the designers thought about the language.
我认为问题在于C#需要另一个关键字,正是因为这种情况。您需要一个方法,其返回值仅取决于调用它的类型。如果所述类型未知,则不能将其称为“静态”。但是一旦知道这种类型,它就会变得静止。 “未解决的静态”是这个想法 - 它还不是静态的,但是一旦我们知道接收类型,它就会是。这是一个非常好的概念,这就是程序员不断要求它的原因。但它并不完全符合设计师对语言的看法。
Since it's not available, I have taken to using non-static methods in the way shown below. Not exactly ideal, but I can't see any approach that makes more sense, at least not for me.
由于它不可用,我已采用下面显示的方式使用非静态方法。不完全理想,但我看不出任何更有意义的方法,至少不适合我。
public interface IZeroWrapper<TNumber> {
TNumber Zero {get;}
}
public class DoubleWrapper: IZeroWrapper<double> {
public double Zero { get { return 0; } }
}
#23
0
As per Object oriented concept Interface implemented by classes and have contract to access these implemented function(or methods) using object.
根据面向对象的概念由类实现的接口,并具有使用对象访问这些实现的函数(或方法)的契约。
So if you want to access Interface Contract methods you have to create object. It is always must that is not allowed in case of Static methods. Static classes ,method and variables never require objects and load in memory without creating object of that area(or class) or you can say do not require Object Creation.
因此,如果要访问Interface Contract方法,则必须创建对象。在静态方法的情况下,始终必须不允许这样做。静态类,方法和变量从不需要对象并在内存中加载而不创建该区域(或类)的对象,或者您可以说不需要对象创建。
#24
0
When a class implements an interface,it is creating instance for the interface members. While a static type doesnt have an instance,there is no point in having static signatures in an interface.
当类实现接口时,它正在为接口成员创建实例。虽然静态类型没有实例,但在接口中使用静态签名没有意义。