kev*_*kev 118 inheritance abstract-class swift
我想用快速语言创建一个抽象函数.可能吗?
class BaseClass {
func abstractFunction() {
// How do I force this function to be overridden?
}
}
class SubClass : BaseClass {
override func abstractFunction() {
// Override
}
}
Run Code Online (Sandbox Code Playgroud)
jau*_*ard 186
Swift中没有抽象概念(如Objective-C),但你可以这样做:
class BaseClass {
func abstractFunction() {
preconditionFailure("This method must be overridden")
}
}
class SubClass : BaseClass {
override func abstractFunction() {
// Override
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*cor 33
你想要的不是基类,而是协议.
protocol MyProtocol {
func abstractFunction()
}
class MyClass : MyProtocol {
func abstractFunction() {
}
}
Run Code Online (Sandbox Code Playgroud)
如果你不在类中提供abstractFunction,那就是错误.
如果您还需要基类用于其他行为,则可以执行以下操作:
class MyClass : BaseClass, MyProtocol {
func abstractFunction() {
}
}
Run Code Online (Sandbox Code Playgroud)
Bob*_*son 29
我将一个支持抽象基类的平台的相当大量的代码移植到Swift并运行到很多.如果你真正想要的是抽象基类的功能,那么这意味着这个类既作为基于共享的类功能的实现(否则它只是一个接口/协议)并且它定义了必须由派生类.
要在Swift中执行此操作,您需要一个协议和一个基类.
protocol Thing
{
func sharedFunction()
func abstractFunction()
}
class BaseThing
{
func sharedFunction()
{
println("All classes share this implementation")
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,基类实现了共享方法,但没有实现协议(因为它没有实现所有方法).
然后在派生类中:
class DerivedThing : BaseThing, Thing
{
func abstractFunction()
{
println("Derived classes implement this");
}
}
Run Code Online (Sandbox Code Playgroud)
派生类从基类继承sharedFunction,帮助它满足协议的这一部分,协议仍然要求派生类实现abstractFunction.
这种方法唯一真正的缺点是,由于基类没有实现协议,如果你有一个需要访问协议属性/方法的基类方法,你必须在派生类中重写它,并从那里调用基类(通过超级)传递,self以便基类具有用于执行其工作的协议的实例.
例如,假设需要调用abstractFunction的sharedFunction.协议将保持不变,类现在看起来像:
class BaseThing
{
func sharedFunction(thing: Thing)
{
println("All classes share this implementation")
thing.abstractFunction()
}
}
class DerivedThing : BaseThing, Thing
{
func sharedFunction()
{
super.sharedFunction(self)
}
func abstractFunction()
{
println("Derived classes implement this");
}
}
Run Code Online (Sandbox Code Playgroud)
现在派生类的sharedFunction满足协议的那部分,但派生类仍然能够以一种相当简单的方式共享基类逻辑.
jbo*_*boi 22
这个似乎是Apple在UIKit中处理抽象方法的"官方"方式.看看UITableViewController它和它的工作方式UITableViewDelegate.你要做的第一件事就是增加一条线:delegate = self.嗯,这正是诀窍.
protocol AbstractMethodsForClassX {
func abstractMethod() -> String
}
Run Code Online (Sandbox Code Playgroud)
2.写你的基类
/// It takes an implementation of the protocol as property (same like the delegate in UITableViewController does)
/// And does not implement the protocol as it does not implement the abstract methods. It has the abstract methods available in the `delegate`
class BaseClassX {
var delegate: AbstractMethodsForClassX!
func doSomethingWithAbstractMethod() -> String {
return delegate.abstractMethod() + " - And I believe it"
}
}
Run Code Online (Sandbox Code Playgroud)
3.编写子类.
/// First and only additional thing you have to do, you must set the "delegate" property
class ClassX: BaseClassX, AbstractMethodsForClassX {
override init() {
super.init()
delegate = self
}
func abstractMethod() -> String {return "Yes, this works!"}
}
Run Code Online (Sandbox Code Playgroud)
这是,你如何使用这一切
let x = ClassX()
x.doSomethingWithAbstractMethod()
Run Code Online (Sandbox Code Playgroud)
检查Playground以查看输出.
UITableViewController实现UITableViewDelegate但仍需要通过明确设置delegate属性来注册为委托.这样做的一种方法是使用在基类中定义的可选闭包,子窗口可以选择是否实现它.
class BaseClass {
var abstractClosure?:(()->())?
func someFunc()
{
if let abstractClosure=abstractClosure
{
abstractClosure()
}
}
}
class SubClass : BaseClass {
init()
{
super.init()
abstractClosure={ ..... }
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,我知道我迟到了比赛,并且我可能会利用已经发生的更改。对于那个很抱歉。
无论如何,我想贡献我的答案,因为我喜欢进行测试,而使用fatalError()isAFAIK 的解决方案是不可测试的,而带有例外的解决方案则很难进行测试。
我建议使用更快捷的方法。您的目标是定义一个具有一些通用细节但尚未完全定义的抽象,即抽象方法。使用协议定义抽象中所有预期的方法,既定义的方法,也定义未定义的方法。然后创建一个协议扩展,以实现您所定义的方法。最后,任何派生类都必须实现协议,这意味着所有方法,但是作为协议扩展一部分的方法已经实现了。
用一个具体功能扩展示例:
protocol BaseAbstraction {
func abstractFunction() {
// How do I force this function to be overridden?
}
}
extension BaseAbstraction {
func definedFunction() {
print("Hello")
}
class SubClass : BaseAbstraction {
func abstractFunction() {
// No need to "Override". Just implement.
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,通过这样做,编译器再次成为您的朋友。如果该方法未“覆盖”,则您将在编译时收到错误,而不是fatalError()在运行时会收到的错误或异常。
我理解你现在在做什么,我认为你最好使用协议
protocol BaseProtocol {
func abstractFunction()
}
Run Code Online (Sandbox Code Playgroud)
然后,您只需符合协议:
class SubClass : BaseProtocol {
func abstractFunction() {
// Override
println("Override")
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的类也是子类,则协议遵循超类:
class SubClass: SuperClass, ProtocolOne, ProtocolTwo {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45096 次 |
| 最近记录: |