作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我脑子里有一个抽象类,我无法快速实现它的几个特性,所以我用C++来表达我的想法:
template <class T>
class Swapping {
public:
void swap() { _foregroundIndex = backgroundIndex() }
virtual void cleanup() = 0;
T* foreground() { return _buffer[foregroundIndex()]; }
T* background() { return _buffer[backgroundIndex()]; }
void setForeground(T* foreground) { _buffer[foregroundIndex()] = foreground; }
void setBackground(T* background) { _buffer[backgroundIndex()] = background; }
private:
short foregroundIndex() { return _foregroundIndex; }
short backgroundIndex() { return _foregroundIndex ^ 1; }
short _foregroundIndex = 0;
T* _buffer[2] = {NULL, NULL};
}
主要矛盾在于
cleanup()
需要所有子类显式实现(可以通过protocol
在swift中实现)_foregroundIndex
有初始值(不能使用协议(protocol)
实现)_foregroundIndex
被限制为私有(private)
(不能使用协议(protocol)
实现)另一方面,如果我使用 class
而不是 protocol
,那么我不能保证 cleanup()
方法被覆盖.
有人可能会建议将虚方法放在协议(protocol)
中,将实例变量放在类
中。这可能有效,但不是一种令人着迷的方法。
附言Objective-C 不是 Swift。不推荐任何与 objc_runtime
相关的解决方法。
最佳答案
有一个明显的解决方案,我经常看到但肯定不会让您满意:
func cleanup() {
fatalError("You must override cleanup()")
}
然后您可以尝试使用 extension
来使用默认实现来扩展协议(protocol),但是扩展不允许存储属性,因此您很可能需要一些外部对象或其他您当然也不喜欢的魔法.
正如我在上面的评论中指出的,您可能需要重新考虑您的设计。我不知道你真正打算做什么,但也许这样的事情对你有用:
class Swapper<T> {
private var foregroundIndex = 0
private var backgroundIndex: Int {
return foregroundIndex ^ 1
}
private var buffer: [T?] = [nil, nil]
private let cleanupHandler: () -> ()
init(cleanupHandler: @escaping () -> ()) {
self.cleanupHandler = cleanupHandler
}
func cleanup() {
cleanupHandler()
}
var foreground: T? {
get {
return buffer[foregroundIndex]
}
set {
buffer[foregroundIndex] = newValue
}
}
var background: T? {
get {
return buffer[backgroundIndex]
}
set {
buffer[backgroundIndex] = newValue
}
}
func swap() {
foregroundIndex = backgroundIndex
}
}
这对我来说更有意义,因为这允许任何类型与任何清理处理程序交换,而不必每次都对类进行子类化。
关于swift - 如何将一个复杂的抽象类移植到swift?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41327177/
我是一名优秀的程序员,十分优秀!