Swift 自类型的存储变量(特别是子类化时) 类链接节点{ var值:T 下一个:自我? 必需的初始值(u值:T){ 自我价值=价值 } } 类DoublyNode:LinkedNode{ 弱var前一个:双连节点? 下一步:自我{ didSet{next.previous=self} } }

Swift 自类型的存储变量(特别是子类化时) 类链接节点{ var值:T 下一个:自我? 必需的初始值(u值:T){ 自我价值=价值 } } 类DoublyNode:LinkedNode{ 弱var前一个:双连节点? 下一步:自我{ didSet{next.previous=self} } },swift,inheritance,self,Swift,Inheritance,Self,我希望它能像这样编译。但事实并非如此 存储的属性不能具有协变“Self”类型 我必须重写代码以使其编译和工作: class LinkedNode<T> { var value: T var next: Self? required init(_ value: T) { self.value = value } } class DoublyNode<T>: LinkedNode<T> { wea

我希望它能像这样编译。但事实并非如此

存储的属性不能具有协变“Self”类型

我必须重写代码以使其编译和工作:

class LinkedNode<T> {
    var value: T
    var next: Self?
    
    required init(_ value: T) {
        self.value = value
    }
}

class DoublyNode<T>: LinkedNode<T> {
    weak var previous: DoublyNode?
    override var next: Self? {
        didSet { next.previous = self }
    }
}
类链接节点{
var值:T
下一个变量:LinkedNode?
必需的初始值(u值:T){
自我价值=价值
}
}
类DoublyNode:LinkedNode{
弱var前一个:双连节点?
覆盖变量next:LinkedNode{
didSet{(下一个为!Self).previous=Self}
}
}
在后面的代码中,每次引用
next
属性后,我都必须手动将其强制转换为DoublyNode(当我使用DoublyNode时),因为它始终具有LinkedNode类型。

它是可管理的,但令人讨厌且丑陋。

斯威夫特的子类不允许对属性进行共同重写(也就是说,对于该属性,有一个类型是
super
类型的子类型)

下面是一个没有泛型的简单示例:

class LinkedNode<T> {
    var value: T
    var next: LinkedNode?
    
    required init(_ value: T) {
        self.value = value
    }
}

class DoublyNode<T>: LinkedNode<T> {
    weak var previous: DoublyNode?
    override var next: LinkedNode<T>? {
        didSet { (next as! Self).previous = self }
    }
}
您几乎看到了示例,除了在这个类比中,Self同时扮演动物和动物喂食者的角色

这个数据模型从根本上被打破了 它遭受着巨大的压力。除非
next
prev
指针被紧密封装,并且仅通过受控函数公开,否则此类将破坏LSP

如果要将
DoublyNode
传递给需要
LinkedNode
的算法,则该算法可以对链表的结构进行操作,只将其视为单独链接,并忽略
prev
引用。这样做,从根本上打破了双链表的不变量,使其无效

didSet
observer会有所帮助,但初始化时不会触发(因此对象从一开始就可能出错)。我认为这一切都可以通过添加更多的封装来解决,并使这些对象对其属性更具权威性,从而确保它们保持有效。但我认为这是一个没有实际意义的问题,因为还有一个更深层次的问题:


“这两个类共享3个字段中的2个”并不是继承的好动机。事实上,你从这份遗产中还能得到什么?我认为如果有两个独立的链接节点类,您将获得更多的价值,每个类分别属于
struct singlelinkedlist
struct DoublyLinkedList
,这两个类分别符合
Collection
BidirectionalCollection
(定义向前和向后迭代)让我来说明为什么Swift不允许这样做。如果它允许你像那样使用
Self
,理论上你可以:

class Animal {}
class Bird: Animal {}

class AnimalFeeder {
    var animalToFeed: Animal
    
    init() { fatalError("not relevant to the example") }
}

class BirdFeeder: AnimalFeeder {
    override var animalToFeed: Bird // error: cannot override mutable property 'animalToFeed' of type 'Animal' with covariant type 'Bird'
}

这正是我要提出的:)顺便说一句,我只是命名了泛型类型值,而不是数据
协议LinkedProtocol{associatedtype值var值:值{get}var下一步:Self?{get}
let doublyNode = DoublyNode(1)
let linkedNode: LinkedNode<Int> = doublyNode // this assignment should work, right?
linkedNode.next = LinkedNode(2) // "linkedNode" is of type LinkedNode, so Self is LinkedNode, so I can do this assignment, right?
protocol LinkedNodeProtocol {
    associatedtype Data
    
    var value: Data { get set }
    var next: Self? { get set }
    
    init(_ value: Data)
}

final class LinkedNode<Data>: LinkedNodeProtocol {
    var value: Data
    var next: LinkedNode?
    
    init(_ value: Data) {
        self.value = value
    }
}

final class DoublyNode<Data>: LinkedNodeProtocol {
    var value: Data
    weak var previous: DoublyNode?
    var next: DoublyNode? {
        didSet { next?.previous = self }
    }
    
    init(_ value: Data) {
        self.value = value
    }
}