Swift 2.0协议扩展和Java/C#抽象类之间有区别吗? [英] Is there a difference between Swift 2.0 protocol extensions and Java/C# abstract classes?

查看:92
本文介绍了Swift 2.0协议扩展和Java/C#抽象类之间有区别吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Swift 2.0中增加了协议扩展,看来协议基本上已经成为Java/C#抽象类.我能看到的唯一区别是抽象类仅限于单一继承,而Swift类型可以符合任何数量的协议.

With the addition of protocol extensions in Swift 2.0, it seems like protocols have basically become Java/C# abstract classes. The only difference that I can see is that abstract classes limit to single inheritance, whereas a Swift type can conform to any number of protocols.

这是对Swift 2.0中协议的正确理解,还是有其他区别?

Is this a correct understanding of protocols in Swift 2.0, or are there other differences?

推荐答案

有几个重要的区别...

There are several important differences...

值类型是结构和枚举.例如,您可以扩展 IntegerArithmeticType isPrime属性添加到所有整数类型(UInt8Int32等).或者,您可以将协议扩展与结构扩展结合使用,以向多个现有类型添加相同的功能-例如,对CGPointCGVector都添加向量算术支持.

Value types are structs and enums. For example, you could extend IntegerArithmeticType to add an isPrime property to all integer types (UInt8, Int32, etc). Or you can combine protocol extensions with struct extensions to add the same functionality to multiple existing types — say, adding vector arithmetic support to both CGPoint and CGVector.

在语言级别上,Java和C#确实没有用户可创建/可扩展的普通数据"类型,因此这里并没有真正的类似物. Swift大量使用值类型-与ObjC,C#和Java不同,在Swift中,甚至集合都是写时复制值类型.这有助于解决有关可变性和线程安全性的许多问题,因此,使自己的值类型而不是始终使用类可以帮助您编写更好的代码. (请参阅WWDC15中的在Swift中使用值类型构建更好的应用.)

Java and C# don't really have user-creatable/extensible "plain old data" types at a language level, so there's not really an analogue here. Swift uses value types a lot — unlike ObjC, C#, and Java, in Swift even collections are copy-on-write value types. This helps to solve a lot of problems about mutability and thread-safety, so making your own value types instead of always using classes can help you write better code. (See Building Better Apps with Value Types in Swift from WWDC15.)

例如,您可以具有一个扩展,该扩展将方法添加到 Comparable ),此属性不会不存在.

For example, you can have an extension that adds methods to CollectionType only when the collection's underlying element type meets some criteria. Here's one that finds the maximum element of a collection — on a collection of numbers or strings, this property shows up, but on a collection of, say, UIViews (which aren't Comparable), this property doesn't exist.

extension CollectionType where Self.Generator.Element: Comparable {
    var max: Self.Generator.Element {
        var best = self[self.startIndex]
        for elt in self {
            if elt > best {
                best = elt
            }
        }
        return best
    }
}

(帽子提示:此示例显示在出色的在这些WWDC15演讲中,有一些受约束的协议扩展的更好的例子(也许还有更多,但我还没有赶上视频):

There's some more good examples of constrained protocol extensions in these WWDC15 talks (and probably more, too, but I'm not caught up on videos yet):

  • Protocol-Oriented Programming in Swift
  • Swift in Practice

抽象类(包括ObjC或Swift,它们是编码约定,而不是语言功能)在类继承方面起作用,因此所有子类都继承抽象类功能,无论它是否有意义.

Abstract classes—in whatever language, including ObjC or Swift where they're a coding convention rather than a language feature—work along class inheritance lines, so all subclasses inherit the abstract class functionality whether it makes sense or not.

这更像是一头挠头,但如果使用得当,它的确会非常强大.这是一个基本示例(同样来自 NSBlog ):

This one's more of a head-scratcher, but can be really powerful if used well. Here's a basic example (again from NSBlog):

protocol P {
    func a()
}
extension P {
    func a() { print("default implementation of A") }
    func b() { print("default implementation of B") }
}
struct S: P {
    func a() { print("specialized implementation of A") }
    func b() { print("specialized implementation of B") }
}

let p: P = S()
p.a() // -> "specialized implementation of A"
p.b() // -> "default implementation of B"

如Apple在 Swift中基于协议的编程中所述,您可以使用它来选择哪些功能应该是可以由采用协议的客户端自定义的替代点,哪些功能应该始终是该协议提供的标准功能.

As Apple notes in Protocol-Oriented Programming in Swift, you can use this to choose which functions should be override points that can be customized by clients that adopt a protocol, and which functions should always be standard functionality provided by the protocol.

您已经注意到,协议一致性是多重继承的一种形式.如果您的类型符合多种协议,并且这些协议具有扩展名,则您的类型将获得其约束满足的所有扩展的功能.

As you've noted already, protocol conformance is a form of multiple inheritance. If your type conforms to multiple protocols, and those protocols have extensions, your type gains the features of all extensions whose constraints it meets.

您可能已经知道其他为类提供多重继承的语言,这会打开一堆丑陋的蠕虫,因为您不知道如果您从具有相同成员或函数的多个类中继承会发生什么情况. Swift 2在这方面要好一些:

You might be aware of other languages that offer multiple inheritance for classes, where that opens an ugly can of worms because you don't know what can happen if you inherit from multiple classes that have the same members or functions. Swift 2 is a bit better in this regard:

  • 协议扩展之间的冲突为

  • Conflicts between protocol extensions are always resolved in favor of the most constrained extension. So, for example, a method on collections of views always wins over the same-named method on arbitrary collections (which in turn wins over the same-named methods on arbitrary sequences, because CollectionType is a subtype of SequenceType).

调用否则会冲突的API是编译错误,而不是运行时歧义.

Calling an API that's otherwise conflicting is a compile error, not a runtime ambiguity.

协议定义可以要求采用该协议的类型必须实现一个属性:

A protocol definition can require that types adopting the protocol must implement a property:

protocol Named {
    var name: String { get } // or { get set } for readwrite 
}

采用协议的类型可以选择将其实现为存储属性还是计算属性,但是无论哪种方式,采用类型都必须声明其实现为属性.

A type adopting the protocol can choose whether to implement that as a stored property or a computed property, but either way, the adopting type must declare its implementation the property.

扩展名可以实施 computing 属性,但是扩展名不能添加 stored 属性.无论是协议扩展还是特定类型(类,结构或枚举)的扩展,都是如此.

An extension can implement a computed property, but an extension cannot add a stored property. This is true whether it's a protocol extension or an extension of a specific type (class, struct, or enum).

相反,一个类可以添加存储的属性以供子类使用.而且,尽管Swift中没有语言功能强制将超类抽象化(也就是说,您不能使编译器禁止实例创建),但如果您始终可以非正式地创建抽象"超类想利用这种能力.

By contrast, a class can add stored properties to be used by a subclass. And while there are no language features in Swift to enforce that a superclass be abstract (that is, you can't make the compiler forbid instance creation), you can always create "abstract" superclasses informally if you want to make use of this ability.

这篇关于Swift 2.0协议扩展和Java/C#抽象类之间有区别吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆