为什么我们不需要动态语言的接口?

发布于 2024-09-06 04:59:17 字数 57 浏览 8 评论 0原文

仅仅是因为动态类型,我们在 python 中不需要接口的概念(如 Java 和 C# 中的接口)吗?

Is it just because of dynamic typing we don't require a concept of interfaces(like in Java and C#) in python?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

转身以后 2024-09-13 04:59:17

interface 作为关键字和工件是由 Java1 引入的(C# 从那里继承了它)来描述对象必须遵守的契约。

但是,接口一直是面向对象范式的关键部分,基本上它代表了对象必须响应的方法。 Java 只是强制执行此机制来提供静态类型检查。

因此,动态 (OO) 编程语言确实使用接口,即使它们不静态地检查它们。就像其他数据类型一样,例如在 Ruby 中:

 @i = 1;

您不必声明 FixNum 类型的 i,您只需使用它即可。界面也是如此,它们只是流动。权衡是,您无法对此进行静态检查,并且故障仅在运行时显示。

另一方面,结构类型(或我称之为静态鸭子类型:P)使用Go 或 Scala 等语言可以两全其美。

<子>
1. 请参阅 Daniel Earwicker 关于 CORBA interface 关键字的评论

The interface as a keyword and artifact was introduced by Java1 ( and C# took it from there ) to describe what the contract an object must adhere was.

But, interface has always been a key part of Object Oriented Paradigm and basically it represents the methods an object has to respond. Java just enforces this mechanism to provide statically type checking.

So, dynamic ( OO ) programming languages do use interfaces, even thought they don't statically check them. Just like other data types, for instance in Ruby:

 @i = 1;

You don't have to declare i of type FixNum you just use it. Same goes for interfaces, they just flow. The trade-off is, you can't have a static check on that and failures are only show at runtime.

In the other hand Structural type ( or static duck type as I call it :P ) used by languages as Go or Scala, gives the best of both worlds.


1. See Daniel Earwicker comment about CORBA interface keyword

各自安好 2024-09-13 04:59:17

我们不要求它们,但我们支持它们。查看 Zope 接口(可以在 Zope 外部使用)。

We don't require them, but we do support them. Check out Zope Interfaces (which can be and are used outside of Zope).

早乙女 2024-09-13 04:59:17

值得注意的是,与许多人的第一反应相反,接口可以用来做更多的事情,而不仅仅是记录“类支持哪些方法”。格泽尼奥用“实施相同行为”的措辞谈到了这一点。作为一个具体示例,请查看 Java 接口 Serialized。它不实现任何方法;相反,它被用作“标记”来指示该类可以安全地序列化。

从这个角度考虑,拥有一种使用接口的动态语言可能是合理的。话虽这么说,类似于注释的东西可能是一种更合理的方法。

It's worth noting that, contrary to what many people will say as a first response, interfaces can be used to do more than document "what methods a class supports". Grzenio touches on this with his wording on "implement the same behaviour". As a specific example of this, look at the Java interface Serializable. It doesn't implement any methods; rather it's used as a "marker" to indicate that the class can be serialized safely.

When considered this way, it could be reasonable to have a dynamic language that uses interfaces. That being said, something akin to annotations might be a more reasonable approach.

冰火雁神 2024-09-13 04:59:17

接口在静态类型语言中用于描述两个独立的对象“实现相同的行为”。在动态类型语言中,人们隐式地假设当两个对象具有相同名称/参数的方法时,它会执行相同的操作,因此接口没有用处。

Interfaces are used in statically typed languages to describe that two otherwise independent objects "implement the same behaviour". In dynamically typed languages one implicitly assumes that when two objects have a method with the same name/params it does the same thing, so interfaces are of no use.

站稳脚跟 2024-09-13 04:59:17

至少对于某些使显式接口变得有点尴尬的动态语言来说,一个关键的事情是动态语言通常可以响应它们事先不知道的消息(错误,“方法调用”),甚至可以执行创建方法之类的操作在飞行中。了解对象是否正确响应消息的唯一真正方法是向其发送消息。没关系,因为动态语言认为能够支持此类事情比静态类型检查更好;一个对象被认为可在特定协议中使用,因为它“已知”能够参与该协议(例如,通过另一条消息给出)。

One key thing about at least some dynamic languages that makes explicit interfaces more than a little awkward is that dynamic languages can often respond to messages (err, “method calls”) that they don't know about beforehand, even doing things like creating methods on the fly. The only real way to know whether an object will respond to a message correctly is by sending it the message. That's OK, because dynamic languages consider it better to be able to support that sort of thing rather than static type checking; an object is considered to be usable in a particular protocol because it is “known” to be able to participate in that protocol (e.g., by virtue of being given by another message).

黎歌 2024-09-13 04:59:17

接口构造用于静态类型语言中,以告知类型系统哪些对象在特定的方法调用上下文中可以相互替换。如果两个对象实现相同的方法,但不通过从公共基类继承或公共接口的实现来关联,则如果您用一个对象替换另一个对象,类型系统将在编译时引发错误。

动态语言使用“鸭子类型”,这意味着该方法只是在运行时查找,如果它存在且具有正确的签名,则使用该方法;否则会产生运行时错误。如果两个对象都通过实现相同的方法“像鸭子一样嘎嘎叫”,那么它们是可替换的。因此,语言没有明确需要通过基类或接口将它们关联起来。

话虽这么说,接口作为一个概念在动态世界中仍然非常重要,但它们通常只是在文档中定义,而不是由语言强制执行。有时,我看到程序员实际上也为此目的创建了一个基类来勾勒出接口;这有助于规范文档,并且如果接口的一部分可以根据接口的其余部分来实现,则特别有用。

Interface constructs are used in statically typed languages to teach the type system which objects are substitutable for each other in a particular method-calling context. If two objects implement the same method but aren't related through inheritance from a common base class or implementation of a common interface, the type system will raise an error at compile time if you substitute one for the other.

Dynamic languages use "duck typing", which means the method is simply looked up at runtime and if it exists with the right signature, it's used; otherwise a runtime error results. If two objects both "quack like a duck" by implementing the same method, they are substitutable. Thus, there's no explicit need for the language to relate them via base class or interface.

That being said, interfaces as a concept are still very important in the dynamic world, but they're often just defined in documentation and not enforced by the language. Occasionally, I see programmers actually make a base class that sketches out the interface for this purpose as well; this helps formalize the documentation, and is of particular use if part of the interface can be implemented in terms of the rest of the interface.

做个ˇ局外人 2024-09-13 04:59:17

Perl 有角色(或特征),它不仅仅是接口,与 java perl 角色不同,我们可以有一个实现,查看这些链接以获取有关 perl 角色的更多信息

Perl has Roles (or traits ), It is more than interfaces unlike java perl roles we can have a implementation check out these links for more on perl roles

简单爱 2024-09-13 04:59:17

在 C# 和 Java 中,接口只是具有所有抽象方法的抽象类。它们的存在是为了允许伪多重继承,但实际上并不支持成熟的多重继承以及多重继承造成的歧义。

Python 支持多重继承,并有自己的方式来确定哪个父方法当一个方法存在于多个父方法中时应该调用。

In C# and Java, interfaces are just abstract classes with all abstract methods. They exist to allow pseudo multiple-inheritance without actually supporting full-blown multiple inheritance and the ambiguity multiple inheritance creates.

Python supports multiple inheritance and has its own way of determining which parent's method should be called when a method exists in multiple parents.

小帐篷 2024-09-13 04:59:17

动态语言是鸭子类型的

如果它走路像鸭子并且嘎嘎叫
像鸭子,它一定是鸭子

http://en.wikipedia.org/wiki/Duck_typing

换句话说,如果您期望一个对象支持Delete() 方法,那么您可以只使用该

obj.Delete()

方法,但如果该对象不支持Delete(),您会收到运行时错误。静态类型语言不允许这样做并引发编译时错误。因此,您基本上可以用类型安全来换取更快的开发时间和灵活性。

如果没有接口,您可以在静态语言中执行类似的操作:

void Save(MyBaseClass item)
{
    if (item.HasChanges)
        item.Save()
}

但这需要您传递给此方法的每个对象都从 MyBaseClass 继承。由于 Java 或 C# 不支持多重继承,这不是很灵活,因为如果您的类已经继承了另一个类,它也不能从 MyBaseClass 继承。因此,更好的选择是创建一个 ISavable 接口并接受它作为输入参数以确保可以保存该项目。那么您就可以兼得两者的优点:类型安全性和灵活性。

public interface ISavable
{
    bool HasChanges {get;set;}
    void Save();
}

void Save(ISavable item)
{
    if (item.HasChanges)
        item.Save()
}

如果您不能期望每个项目都将使用您的 save 方法来实现接口,那么最后一个后门是使用对象作为参数。

void Save(object item)
{
    if (item.HasChanges)
        item.Save()
}

但话又说回来,您没有编译时检查,如果有人将您的方法与不兼容的类一起使用,则可能会出现运行时错误。

Dynamic languages are Duck Typed

If it walks like a duck and quacks
like a duck, it must be a duck

http://en.wikipedia.org/wiki/Duck_typing

In other words, If you exect an object to suport the Delete() method, than you can just use the

obj.Delete()

method but if the object doesn't support Delete() you get a Runtime error. Statically typed languages wouldn't allow that and throw a compile time error. So you basically trade type safty against faster developement time and flexibility.

Without interfaces you can do something like that in static languages:

void Save(MyBaseClass item)
{
    if (item.HasChanges)
        item.Save()
}

but that would require every object that you pass to this method to inherit from MyBaseClass. Since Java or C# don't support muliinheritance that isn't very flexible because if your class already inherits another class it cannot inherit from MyBaseClass, too. So the better choise would be to create a ISavable interface and accept that as a input parameter to ensure that item can be saved. Then you have best of both: type safety and flexibility.

public interface ISavable
{
    bool HasChanges {get;set;}
    void Save();
}

void Save(ISavable item)
{
    if (item.HasChanges)
        item.Save()
}

The last backdoor is to use object as a parameter if you cannot expect every item that will use your save method to implement the interface.

void Save(object item)
{
    if (item.HasChanges)
        item.Save()
}

But than again, you don't have compile time checking and probably get a runtime error if someone uses your method with an incompatible class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文