当前位置: 首页 > 面试题库 >

Swift 2.0协议扩展和Java / C#抽象类之间有区别吗?

苏季同
2023-03-14
问题内容

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

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


问题答案:

有几个重要的区别…

协议扩展可以与值类型以及类一起使用。

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

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

协议扩展可能受到限制。

例如,您可以具有一个扩展,该扩展CollectionType仅在集合的基础元素类型满足某些条件时才向其中添加方法。这是找到集合最大元素的方法-
在数字或字符串的集合上显示此属性,但是在UIViews(不是Comparable)的集合上,此属性不存在。

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
    }
}

(提示:此示例仅在今天才出现在出色的NSBlog中。)

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

  • Swift中面向协议的编程
  • 快速实践

抽象类(使用包括ObjC或Swift在内的任何语言,它们都是编码约定而不是语言功能)沿着类继承行工作,因此所有子类都继承抽象类功能,无论它是否有意义。

协议可以选择静态或动态调度。

这更像是一头挠头,但如果使用得当,它确实可以强大。这是一个基本示例(同样来自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 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.

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).

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

Protocols (and extensions) can’t create storage.

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.

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).

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.



 类似资料:
  • 问题内容: 我知道Java,现在正在学习Objective-C。Java接口和Objective-C协议之间到底有什么区别? 问题答案: 首先,从Java的一位创建者那里对该主题进行了一些历史性的展望。接下来,维基百科在Objective- C协议中 提供了适度有用的部分。特别要了解的是,Objective- C支持 正式协议 (使用关键字明确声明,相当于Java接口)和 非正式协议 (仅一个或多

  • 本文向大家介绍C#扩展抽象基类,包括了C#扩展抽象基类的使用技巧和注意事项,需要的朋友参考一下 示例 与接口(可以描述为实现合同)不同,抽象类充当扩展的合同。 抽象类无法实例化,必须对其进行扩展,然后可以实例化生成的类(或派生类)。 抽象类用于提供通用实现 上面的示例显示了实现Car的任何扩展类如何自动接收HonkHorn方法。这意味着任何开发新汽车的开发人员都无需担心它将如何鸣笛。

  • 问题内容: 我不清楚两者之间的区别。 谢谢 问题答案: 它们非常相似,但是存在一些重要的技术差异: 抽象类允许您为某些方法提供默认的实现,但是接口不允许您提供任何实现。 您可以实现多个接口,但只能从一个抽象类继承。 这些差异影响应使用两种技术的方式: 您应该使用接口来 定义合同 。 抽象类对于 重用代码 很有 用 ……但是请注意,它不是重用代码的唯一方法。您还应该考虑其他方法,例如遏制。

  • 协议和扩展 你可以扩展一个已经存在的类型来采纳和遵循一个新协议, 就算是你无法访问现有类型的源代码也行. 扩展可以添加新的属性、方法和下标到已经存在的类型, 并且因此允许你添加协议需要的任何需要. protocol TextRepresentable { var textualDescription: String { get } } // 此处并无Dice这个类, 以及其sides属性

  • 本文向大家介绍1G和2G协议之间的区别,包括了1G和2G协议之间的区别的使用技巧和注意事项,需要的朋友参考一下 1G和2G是两代手机。1G代表第一代,2G代表第二代。 以下是1G和2G之间的重要区别。 序号 键 1G 2G 1 定义 1G代表第一代。它在美国带来了无线通信。 2G代表第二代,在美国带来了语音和数字通信。 2 交换 1G使用电路交换。 2G同时使用电路交换和分组交换。 3 互联网 在

  • 问题内容: 封装和抽象之间的确切区别是什么? 问题答案: 这里的大多数答案都集中在OOP上,但封装要早得多: 每个函数都是一个封装 ; 用伪代码: 这里,封装了平面中两点之间的(欧几里得)距离的计算:隐藏了实现细节。这是封装,纯净而简单。 抽象是泛化的过程:采取具体的实现方式并将其应用于不同的(尽管有些相关)数据类型。抽象的经典示例是C的qsort数据排序功能: 关于的事情是,它不关心排序的数据-