我有一个Child类,其中包含我定义的方法以及从其Parent类继承的方法。我希望用户无法使用Parent的某些方法,或者至少使用 会产生编译错误/警告。示例:
class Parent {
public func secretMethod() { // Don't want anyone to use
}
}
class Child: Parent {
public func overtMethod() { // Fine with people using
}
}
Child.init().overtMethod() // Fine
Child.init().secretMethod() // Not Fine. Should not be viewable/useable/accessible
我无法更改父班。我多么渴望能够将secretMethod
设置为private
。 Swift不允许在覆盖函数时限制访问级别,因此我也无法在Child类中将secretMethod
设置为private
。
到目前为止,我一直在使用@available
用编译警告和消息标记该方法,但是我希望有更好的方法吗?我考虑了覆盖并引发错误,但是如果原始方法未标记为throws
,则无法做到这一点。
谢谢。
编辑:我也不能覆盖secretMethod使其不可用。 Child类需要访问它。
答案 0 :(得分:2)
如果您不想公开父类的公共方法,请不要使用继承。您可以将“父”类隐藏为“子”类中的私有实例,并且仅转发要公开的方法。
如果由于子类继承父类而依赖于子类的继承,那么您也不能将任何父方法设为私有。如果您传递子类(这会隐藏以前的公共父方法),则会破坏使用父类的API之间的契约。那行不通。
答案 1 :(得分:2)
重新考虑您的设计。
我认为您可能只考虑“用户”(另一位开发人员?我想您正在编写库?),而不是 现有资源 。子类的基本思想是,可以在使用父类的任何地方使用子类。
class A: UIView {
func availableMethod() {
}
// func layoutSubviews() ----- let's say you want to hide this method
}
这里出现问题是因为您不知道layoutSubviews
可能有其他内部类在做什么,并且如果您以某种方式在A
的实例上对其进行了阻止,那么任何期望能够使用的东西该实例就好像是UIView
的实例一样,现在将失败。
答案 2 :(得分:1)
看起来,您正在寻找的是protected
访问修饰符,该修饰符使您可以在其后代中看到方法和变量。
但是,在Swift中没有任何东西。主要访问修饰符为private
或internal
。
它们之间的某个位置是fileprivate
。它使您可以在一个文件中包含可见的方法和变量。即使这对您来说是解决方案,也可能不是正确的设计模式。
如果您正在编写库,并且不想允许其他程序员从 parent 调用方法,但是想让他们看到 subclasses'方法,您可以在 subclass
中将internal
函数从 parent 覆盖为public
或open
函数
答案 3 :(得分:1)
我想增强@nikwest的答案。您应该尝试使用合成而不是继承。因此,Parent
和Child
根本不需要共享任何代码,但是两种方法都可以使用。您还可以创建一个共同的祖先,以便某个var
将始终存在。
class Parent: Overt {
}
class Child: Overt, Secret {
}
protocol Overt {
func overtMethod()
}
protocol Secret {
func secretMethod()
}
extension Overt {
public func overtMethod() { // stuff }
}
extension Secret {
public func secretMethod() { // stuff }
}
当您要共享一个公用var
或某些东西(例如使用合成模式的UIViewController
)时,可以使用具有变体的CommonParent
然后是{{ 1}}和Child1
将添加实现所需功能所需的协议。如果您没有在Child2
中使用默认实现,则仍然可以覆盖。