我有一个基类,它在一些数据结构中存储了很多其他数据对象,这个类通过一组 add
/remove来管理我集合中的这些数据对象
使我的数据结构保持同步的函数。
现在我去创建这个基类的子类,子类就像基类一样,除了它对接受什么样的数据对象有特殊的规则(它查看数据对象的值,然后拒绝它们如果值不正确)。由于这种“有效性”检查,我为名为 change
的子类创建了一个新函数。在 change
函数中,它检查所有传入的数据对象并验证它们是否正常,然后用这些数据对象替换数据结构中的所有数据对象。
问题是我不希望有人能够创建一个子类对象并允许他们调用基类的add
/remove
函数,因为我只希望子类能够通过子类的change
函数改变。
我还没有找到一个好的方法来“禁止”在子类中使用那些基类函数。我可以重写
函数并实现空的实现,但是没有向调用者反馈该函数没有执行任何操作。如果我使用类似 fatalError
的东西,那不是编译时间,而是运行时间。
我的其他想法是将基类的功能分解为多个协议(protocol),并将基类更改为仅具有所有数据结构,但不符合任何协议(protocol),然后有多个子类,其中一个需要add
功能可以从基础继承并另外符合 add
协议(protocol),但不需要 add
或 remove
可以从基础继承,并且不符合任何协议(protocol),而是创建自己的 change
函数来修改数据结构。
这里有一个更简单的层次结构来解释:
class Parent {
func doThis() { print("Parent Did This") }
func doThat() { print("Parent Did That") }
}
class Child: Parent {
override func doThis() {
print("Child Did This")
}
// I want this to be a compile time error
override func doThat() {
print("Not Supported")
return
}
}
有没有更简单的方法来“隐藏”子类中的函数?
编辑 1
为了更好地解释我提出的解决方案,以及是否有更简单的方法来使用我当前的层次结构来实现它,下面是使用某些协议(protocol)的层次结构必须看起来的样子:
protocol CanDoThis {
func doThis()
}
protocol CanDoThat {
func doThat()
}
class Parent {
// Important properties that all children should have
var property1: Int = 0
var property2: String = ""
}
class Child1: Parent, CanDoThis {
func doThis() { print("Child1 Can Do This") }
}
class Child2: Parent, CanDoThat {
func doThat() { print("Child2 Can Do That") }
}
class Child3: Parent, CanDoThis, CanDoThat {
func doThis() { print("Child3 Can Do This") }
func doThat() { print("Child3 Can Do That") }
}
最佳答案
免责声明
协议(protocol)版本可能会设计得更好 - 请参阅 Liskov Substitution Principle加上你提到的其他事情。
回答问题
您可以使用属性 @available()
(参见 Swift -> Language Reference -> Attributes)。
class Parent {
func doThis() { print("Parent Did This") }
func doThat() { print("Parent Did That") }
}
class Child: Parent {
override func doThis() {
print("Child Did This")
}
@available(*, unavailable, message:"Child can't doThat")
override func doThat() {
print("Not Supported")
}
}
let parent = Parent()
parent.doThis()
parent.doThat()
let child = Child()
child.doThis()
child.doThat()
您在 child.doThat()
上收到以下错误消息:
'doThat()' is unavailable: Child can't doThat
不过,您可以通过执行以下操作来解决这个问题(再次参见 Liskov 替换原则):
let maybeChild: Parent = Child()
maybeChild.doThis()
maybeChild.doThat()
关于ios - 在 Swift 中,如何防止函数在子类上被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34802374/