2015-03-15 9 views
7

Ich habe eine Klasse mit einem Delegaten. Ich erstelle eine Unterklasse, die auch einen Delegaten hat. Ich wollte das Protokoll für den zweiten Delegaten erweitert das Protokoll für die ersten Delegaten verwendet lassen:Protokollvererbung + Delegierte in Swift

protocol MySuperClassProtocol { 
    func foo() 
} 

class MySuperClass { 
    var delegate:MySuperClassProtocol? 
} 

protocol MySubClassProtocol:MySuperClassProtocol { 
    func bar() 
} 

class MySubClass: MySuperClass { 
    override var delegate:MySubClassProtocol? // compiler error - "cannot override..." 

    func test() { 
     delegate?.foo() 
     delegate?.bar() 
    } 
} 

class UserClass:MySubClassProtocol { 
    func foo() { 
     println("foo!") 
    } 
    func bar() { 
     println("bar") 
    } 
} 

Gibt es eine Möglichkeit, dies zu lösen? Die einzige mögliche Lösung, die ich sehe, ist, die 2 Protokolle unabhängig voneinander zu machen und verschiedene Namen zu verwenden. Gefällt mir:

protocol MySuperClassProtocol { 
    func foo() 
} 

class MySuperClass { 
    var mySuperClassDelegate:MySuperClassProtocol? 
} 

protocol MySubClassProtocol { 
    func bar() 
} 

class MySubClass: MySuperClass { 
    var mySubClassDelegate:MySubClassProtocol? 

    func test() { 
     mySuperClassDelegate?.foo() 
     mySubClassDelegate?.bar() 
    } 
} 

class UserClass:MySuperClassProtocol, MySubClassProtocol { 
    func foo() { 
     println("foo!") 
    } 
    func bar() { 
     println("bar") 
    } 
} 

Aber das sieht ein bisschen komisch aus + werde ich nicht zulassen, Namenskonvention für Delegate- "Delegate" zu verwenden.

+0

Warum brauchen Sie ein Super Class und Super Class Protocol? –

+1

Weil ich die allgemeine Funktionalität von vielen Klassen in der Super-Klasse und es gibt auch einen "gemeinsamen Delegierten". – Ixx

Antwort

0

Sie können es auf eine andere Weise tun, können Sie die delegate Variable in Subclass hinzufügen und es verwenden, um auf die SuperClassProtocol auch unter Verwendung delegate?.foo() zuzugreifen.

protocol MySuperClassProtocol { 
    func foo() 
} 

class MySuperClass { 
    //var delegate:MySuperClassProtocol? 
} 

protocol MySubClassProtocol:MySuperClassProtocol { 
    func bar() 
} 

class MySubClass: MySuperClass { 
    var delegate:MySubClassProtocol? 

    func test() { 
     delegate?.foo() 
     delegate?.bar() 
    } 
} 

class UserClass:MySubClassProtocol { 
    func foo() { 
     println("foo!") 
    } 
    func bar() { 
     println("bar") 
    } 
} 

Aber das Problem mit diesem Ansatz ist, dass Sie nie MySuperClassProtocol unabhängig nutzen können, wenn Sie eine neue Unterklasse von MySuperClass nur schaffen für die Deklaration delegate Variable.

+0

Nicht, was ich brauche ... die Idee, den Delegierten der Superklasse zu haben ist, dass jede Unterklasse es haben wird. Damit müsste ich den Delegaten in jeder Unterklasse deklarieren. – Ixx

+0

@ixx: Was dann? Sie können eine Unterklassenmethode nicht mit dem Basisklassenzeiger aufrufen, es sei denn, Sie fügen dies in die Basisklasse ein (deklarieren Sie sie in der baseclass- oder baseclass-Eigenschaft). Es ist ein reines OOP-Konzept. Es gibt keinen anderen Weg als 1, den du in deiner Frage definiert hast und 1, den ich hier erwähnt habe. Es kann auch nicht in Ziel c getan werden. Sie suchen nach etwas, das nicht einmal möglich ist. –

+0

Nun, das ist, was ich suche, eine Möglichkeit, den Basisdelegaten in der Basisklasse zu haben, damit ich ihn von überall aus anrufen kann. Ich habe auch Angst, dass der einzige Weg ist, was ich in meine Frage stelle. "Sie suchen etwas, das nicht einmal möglich ist", das wissen Sie nicht, wenn Sie eine Frage stellen;) – Ixx

5

Ich habe versucht, eine ideale Lösung für dieses Problem für einige Zeit zu finden, kann aber nicht mit etwas besser, dass dies kommen:

protocol BaseDelegateProtocol: class { } 

class BaseDelegate: BaseDelegateProtocol { } 

class BaseActor { 
    weak var delegate: BaseDelegate? = nil 
} 

// MARK: - 

protocol ConcreteDelegateProtocol: class { 
    func doSomething() 
} 

class ConcreteDelegate: BaseDelegate, ConcreteDelegateProtocol { 
    func doSomething() { 
     // Do something 
    } 
} 

class ConcreteActor: BaseActor { 
    private weak var concreteDelegate: ConcreteDelegateProtocol? = nil 

    override var delegate: BaseDelegate? { 
     didSet { 
      concreteDelegate = delegate as? ConcreteDelegateProtocol 
     } 
    } 
} 

Above arbeitet in XCode 7/Swift 2.

  • Dieses Muster ermöglicht die Übernahme von immer mehr Protokollen auf dem Weg nach unten von BaseDelegate erben.
  • Es ist nicht notwendig, Protokolle voneinander zu erben, was hilft, die Dinge isoliert zu halten.
  • didSet Beobachter auf delegate Eigenschaft wird automatisch für Super genannt, daher keine Notwendigkeit super.<blah> ausdrücklich zu nennen, und keine Gefahr für die ‚vergessen‘ Dabei
  • Beton Delegat Eigenschaften können auf jeder Ebene der Vererbung privat gehalten werden, wodurch das Reduktions Unordnung.
1

Sorry für necroposting, die einzige Lösung, die ich gefunden ist:

protocol SuperClassDelegate { 
    func first_method() 
} 

class SuperClass { 
    var delegate: SuperClassDelegate? 

    func do_something() { 
     delegate?.first_method() 
    } 
} 

protocol SubClassDelegate: SuperClassDelegate { 
    func second_method() 
} 

class SubClass: SuperClass { 
    private var subDelegate: SubClassDelegate? 
    override var delegate: SuperClassDelegate? { 
     get { return self.subDelegate } 
     set { self.subDelegate = newValue as! SubClassDelegate? } 
    } 

    //override func do_something() { 
    // super.do_something() 
    // subDelegate?.second_method() 
    //} 

    func do_something_other() { 
     //subDelegate?.first_method() 
     self.do_something() 
     subDelegate?.second_method() 
    } 
} 

class InheritanceAndDelegation: SubClassDelegate { 
    let obj = SubClass() 

    init() { 
     obj.delegate = self 
    } 

    internal func first_method() { 
     print("Hello from SuperClass") 
    } 

    internal func second_method() { 
     print("Hello from SubClass") 
    } 

    func check() { 
     obj.do_something_other() 
    } 
} 

let inheritanceAndDelegation = InheritanceAndDelegation() 
inheritanceAndDelegation.check() 
//prints: 
//Hello from SuperClass 
//Hello from SubClass 

kommentiert Code funktioniert auch. Hoffe, dass es für jemanden nützlich sein wird.