我以前使用的课程可以简化为:
class Whatever {
var someArray = [Int]()
func unchangingFunction {
print("test")
}
func functionForOverride() {}
}
我在想办法改善这一点,并且我被告知赞成合成而不是继承,使用如下内容:
protocol Implementation {
func functionForOverride()
}
final class Whatever {
var someArray = [Int]() // How can I access this?
let implementation: Implementation
init(implementation: Implementation) {
self.implementation = implementation
}
func unchangingFunction() {
print("test")
}
func functionForOverride() {
implementation.functionForOverride()
}
}
但是,有了这个,我找不到使用someArray数组做任何事情的方法:
struct Something: Implementation {
func functionForOverride() {
print(someArray) // This cannot work
}
}
使用原始代码,我可以访问和更改someArray但是我想要,但是用这种新方法,我想不出一个简单的解决方案。
答案 0 :(得分:2)
我认为我们应该使用"真实"例子,以使事情更清楚。
我们有以下课程
class Robot {
var battery = 0
func charge() {
print("⚡️")
battery += 1
}
}
class Human {
func eat() {
print("")
}
}
class RobotCleaner: Robot {
func clean() {
print("")
}
}
class HumanCleaner: Human {
func clean() {
print("")
}
}
代码重复!!!
正如您所见,clean()
和RobotCleaner
中的HumanCleaner
方法重复。你能找到一种方法(使用继承)来删除代码重复吗?
好的想一想,我等下一段...:)
...
哦,你来了!没有办法通过继承来解决这个问题吗?好吧,让我们看看我们可以用组合做些什么。
让我们定义以下3个协议和相关组件
protocol Robot {
mutating func charge()
}
struct RobotComponent: Robot {
var battery = 0
mutating func charge() {
print("⚡️")
battery += 1
}
}
protocol Human {
func eat()
}
struct HumanComponent: Human {
func eat() {
print("")
}
}
protocol Cleaner {
func clean()
}
struct CleanerComponent: Cleaner {
func clean() {
print("")
}
}
现在我们可以构建前3个元素的任意组合
struct RobotCleaner: Robot, Cleaner {
var robotComponent = RobotComponent()
let cleanerComponent = CleanerComponent()
mutating func charge() {
robotComponent.charge()
}
func clean() {
cleanerComponent.clean()
}
}
struct HumanCleaner: Human, Cleaner {
let humanComponent = HumanComponent()
let cleanerComponent = CleanerComponent()
func eat() {
humanComponent.eat()
}
func clean() {
cleanerComponent.clean()
}
}
首先,让我们定义以下3个协议(及相关扩展)。
protocol Robot {
var battery: Int { get set }
}
extension Robot {
mutating func charge() {
print("⚡️")
battery += 1
}
}
protocol Human { }
extension Human {
func eat() {
print("")
}
}
protocol Cleaner { }
extension Cleaner {
func clean() {
print("")
}
}
现在我们可以创建一个包含前3个实体的任意组合的Type。让我们看看如何。
struct HumanCleaner: Human, Cleaner { }
struct RobotCleaner: Robot, Cleaner {
var battery: Int = 0
}
答案 1 :(得分:1)
如果'Implementation'需要'someArray'来做它想要做的事情,那么你应该让'Implementation'要求任何符合它的对象也声明'someArray'
像这样:
protocol Implementation {
var someArray: [Int]
}
如果你知道你想用'someFunction'做什么,那么你可以用这样的协议扩展来给它一个默认的实现:
extension Implementation {
func someFunction() {
//you can do some stuff with someArray here
}
}
然后,当你遵守'Implementation'时,你需要声明'someArray'而不是'someFunction',除非你想要覆盖默认函数。
E.g。
class MyClass: Implementation {
var someArray: [Int]!
init() {}
}
请注意,MyClass现在可以访问'someFunction',它可以在您的类中自由覆盖,并且您可以添加任意数量的函数来实现'实现的扩展。