Swift子类调用超类初始化器因private权限报错的解决方法
子类化SwiftySound的Sound类时的访问权限问题
问题说明
基于SwiftySound框架的Sound类创建子类SoundWrapper,要求添加imageName字符串属性并实现Hashable协议。编写初始化器时调用super.init(url: url)出现错误:'url' is inaccessible due to 'private' protection level,同时初始化器的设计与实际调用需求不匹配。
现有代码
子类代码
class SoundWrapper:Sound, Hashable{ let id = UUID() let imageName : String init(imageName: String) { self.imageName = imageName super.init(url: url) // Error: 'url' is inaccessible due to 'private' protection level } public func hash(into hasher: inout Hasher) { hasher.combine(0) } static func == (lhs: SoundWrapper, rhs: SoundWrapper) -> Bool { return lhs.id == rhs.id } }
计划初始化方式
let backgroundAudio1 = SoundWrapper(imageName: "image1", url: getFileUrl(name: "backgroundAudio1"))
获取URL的方法
func getFileUrl (name: String) -> URL { let filePath = Bundle.main.path(forResource: name, ofType: "wav")! return URL(fileURLWithPath: filePath) }
SwiftySound框架的Sound类核心初始化逻辑
open class Sound { // ... 其他代码省略 ... /// Create a sound object. /// /// - Parameter url: Sound file URL. public init?(url: URL) { // ... 初始化逻辑 ... } // ... 其他代码省略 ... }
解决方案
修改后的子类代码
class SoundWrapper: Sound, Hashable { let id = UUID() let imageName: String // 可选:自行存储URL,因为Sound类未暴露该属性 private let soundUrl: URL // 声明为可失败初始化器,匹配超类的init?(url:) init?(imageName: String, url: URL) { self.imageName = imageName self.soundUrl = url // 传入外部传入的URL调用超类初始化器 super.init(url: url) } public func hash(into hasher: inout Hasher) { // 使用id生成哈希值,保证唯一性 hasher.combine(id) } static func == (lhs: SoundWrapper, rhs: SoundWrapper) -> Bool { return lhs.id == rhs.id } }
正确初始化调用
if let backgroundAudio1 = SoundWrapper(imageName: "image1", url: getFileUrl(name: "backgroundAudio1")) { // 初始化成功,使用SoundWrapper实例 }
错误原因与解释
- 初始化器参数不匹配:原子类初始化器仅接收
imageName,但实际调用需要传入url,导致代码中super.init(url: url)的url未定义,直接引发错误。 - 超类初始化器特性:
Sound类的初始化器是可失败初始化器(init?),子类必须使用相同的可失败语义,否则无法编译通过。 - 属性访问权限:
Sound类未将初始化时传入的url作为公共属性存储,因此子类无法直接访问超类内部的url变量,必须从外部传入该参数。 - Hashable实现优化:原代码中
hasher.combine(0)会导致所有实例的哈希值相同,不符合Hashable协议的预期,改为结合id可保证哈希值的唯一性。
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

