2015-08-21 22 views
9

Also dachte ich über ein benutzerdefiniertes Muster in meinem Projekt nach, aber ich kann es nicht zum Laufen bringen. Die Grundidee ist, die typealias für jede Unterklasse zu ändern, um Zugriff auf die Unterklasse spezifische Schnittstelle zu erhalten.Swift: Überschreiben von Typalias innerhalb der Unterklasse

protocol InstanceInterface: class { 

    typealias Interface 

    var interface: Interface { get } 
} 

// Baseclass 
protocol FirstClassInterface: class { /* nothing here for the example */ } 

class FirstClass: InstanceInterface, FirstClassInterface { 

    typealias Interface = FirstClassInterface 

    var interface: Interface { return self } 
} 

// Subclass 
protocol SecondClassInterface: FirstClassInterface { 

    func foo() 
} 

class SecondClass: FirstClass, SecondClassInterface { 

    typealias Interface = SecondClassInterface // <--- This does nothing :(

    func foo() { print("hello world") } // Swift 2.0 here 
} 

// Lets say I want to call foo trough the interface 
let test = SecondClass() 

test.interface.foo() // 'Interface' does not have a member named 'foo' 

Gibt es etwas, was ich falsch mache oder versteh ich einige Swift Konzepte hier ?! Ich muss hier Unterklassen erstellen, um nicht immer alles aus Protokollen der Superklasse zu implementieren. Ist mein kleines Muster überhaupt möglich? Ich würde mich über jede Hilfe freuen. :)

Antwort

6

Leider gibt es keine gute Problemumgehung für dieses Problem.

Die Hauptidee der typealias funktionieren würde in diesem Fall aber ist folgendes beachten außer Kraft zu setzen:

protocol TakeAndGet { 
    typealias T 
    func take(value: T) 
    func get() -> T 
} 

class FirstClass: TakeAndGet { 
    typealias T = FirstClass 

    var property = 0 

    func take(value: T) { 
     value.property = 4 
    } 

    func get() -> T { 
     return FirstClass() 
    } 
} 

class SecondClass: FirstClass { 

    typealias T = SecondClass 

    var property2 = "hello" 
} 

Wenn die typealias der SecondClass überschreibt das andere die take Methode funktionieren würde, da es dauert eine Unterklasse kann, die als die Oberklasse behandelt werden. Aber die get Methode kann nicht FirstClass zu SecondClass implizit konvertieren. Daher ist es nicht möglich, eine typealias zu überschreiben.

Jetzt, wenn wir die get Funktion mit get() -> SecondClass überschreiben möchten, würde es nicht funktionieren, da es nicht die gleiche Signatur wie die in der Oberklasse hat. Darüber hinaus erben wir die get Methode, die in einer zweideutigen Verwendung ergibt:

SecondClass().get() // which type gets returned? SecondClass or FirstClass 

Also muss man einen anderen Ansatz versuchen.

+1

Ich sehe den Punkt jetzt. Aber immer noch sollte es einen Fehler oder eine Warnung geben, wenn Sie die Typalias in der Unterklasse außer Kraft setzen !? Ich meine, es tut nichts, sogar für dein Beispiel würde es immer noch bei FirstClass in SecondClass bleiben oder liege ich wieder falsch? Was ist der Zweck der Überschreibung von Typalien? – DevAndArtist

+1

@DevAndArtist Der Punkt ist, dass eine 'typealias' nicht überschrieben werden kann und wenn Sie eine neue mit dem gleichen Namen wie in' SecondClass' deklarieren, schattiert sie die andere. Dies bedeutet, dass "T" im Bereich von "SecondClass" einen anderen Typ hat, aber nicht das "T" von "FirstClass" ändert. – Qbyte

5

Würde so etwas für Ihre Zwecke funktionieren?

class MyClass<T> { 

} 

class MySubclass1: MyClass<String> { 

} 

class MySubclass2: MyClass<Int> { 

} 
Verwandte Themen