2015-12-04 89 views
0

使用繼承的對象我有一個對象,可能是這個樣子......方式迅速

class User { 
    var username: String? 
} 

我想有網友認爲可能是某個學生或教師。目前,我在性能和用戶類像這樣已經加入...

class User { 
    var username: String? 
    // student properties 
    var year: Int? 
    // teacher properties 
    var department: String? 
} 

我敢肯定,我應該在這裏用繼承,但我很擔心,將會使控制流有點複雜。例如,作爲登錄功能的一部分,我這樣做...

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
appDelegate.user = User(delegate: self) 
appDelegate.user!.load_from_user_defaults() 

或獲得當前用戶的東西,我會做到這一點...

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
var username = appDelegate.user.username 

我將如何使用繼承,在這種情況下,鑑於我不知道這是一名教師還是一名學生登錄?堅持我這樣做的方式更容易嗎?

+0

既然你對學生和老師不同的屬性,我認爲你必須決定哪些你與在某些時候處理的方式。 –

+1

提示1:永遠不要使用'UIApplication.sharedApplication()。delegate as! AppDelegate'在您的應用程序中,但將引用傳遞給視圖控制器,從AppDelegate開始。提示2:使用工廠模式 - 只是谷歌它。例如,您可以通過超類的靜態方法實例化任何這些類的實例。然後您可以隨時訪問用戶名。檢查是否有人是學生:'myVariable是學生'。訪問一個學生的變量:'(myVariable as?Student)?year'將年份作爲可選項返回(如果不是學生,則爲零,否則爲數值) – borchero

+0

感謝Oliver,我很欣賞這個建議。看起來我還有很多的閱讀要做!當你說永遠不要使用UIApp ...系列時,有沒有好的理由不?我想了解_why_我正在寫點什麼,而不僅僅是要改變它。我可以看到你如何使用prepareForSegue來做到這一點。 [鏈接](http://jamesleist.com/ios-swift-passing-data-between-viewcontrollers/),但這是否創建對象的副本,或保留原來的? – Ben

回答

1

一些選項:

  • 超/子類模式(繼承),您使用downcast來檢查它是否是學生或教師。

  • 協議的工作一樣的超/子模式,但一個type可以符合很多protocols但只能從一個super繼承。

  • 如果學生和老師具有相同的屬性,您也可以只添加一個屬性(boolenum)以確定哪個屬於哪個屬性。

  • 創建的enum而不是或super classUserrawValue和對教師和學生的情況。 (這很複雜)

  • 使用帶有關聯值的enum

每種方法都有它自己的優點和缺點。 如果您希望能夠將User對象傳遞給應用程序中的不同功能,您希望具有一定的一致性/繼承性。


如果你有一定的一致性/繼承,您可以與您選擇的方法加載用戶,然後垂頭喪氣這樣:

if let student = user as? Student { 
    // do student stuffs 
} else if let teacher = user as? Teacher { 
    // do teacher stuffs 
} 

選項1,定期繼承:

class User { 
    var username: String? 
} 

class Student : User { 
    // student properties 
    var year: Int? 
} 

class Teacher : User { 
    // teacher properties 
    var department: String? 
} 

選項2,符合,而不是從,AKA Protcols繼承:

protocol User : class { 
    var username: String? { get set } 
} 

class Student : User { 

    var username: String? 
    // student properties 
    var year: Int? 
} 

class Teacher : User { 

    var username: String? 
    // teacher properties 
    var department: String? 
} 

選項3,UserType屬性:

enum UserType { 
    case Student 
    case Teacher 
} 

class User { 
    var username: String? 
    // student properties, if it is a teacher we leave this blank 
    var year: Int? 
    // teacher properties,, if it is a student we leave this blank 
    var department: String? 

    var type : UserType? 
} 

選項4,enumUserrawValue

class User: Equatable,StringLiteralConvertible { 

    var username: String? 
    // student properties 
    var year: Int? 
    // teacher properties 
    var department: String? 

    var type : String? 

    init(withType type:String) { 
     self.type = type 
    } 

    required convenience init(stringLiteral value: String) { 

     self.init(withType: value) 
    } 

    required convenience init(extendedGraphemeClusterLiteral value: String) { 
     self.init(withType: value) 
    } 

    required convenience init(unicodeScalarLiteral value: String) { 
     self.init(withType: value) 
    } 
} 

func ==(lhs:User,rhs:User) -> Bool { 
    if lhs.username == rhs.username && lhs.department == rhs.department && lhs.year == rhs.year && lhs.type == rhs.type { 
     return true 
    } else { 
     return false 
    } 
} 


enum UserType : User { 

    case Student = "Student" 
    case Teacher = "Teacher" 

} 

let user = UserType.Teacher 

選5,enum有關聯的值:

class User { 

    var username: String? 

} 

class Student { 
    // student properties 
    var year: Int? 
} 

class Teacher { 
    // teacher properties 
    var department: String? 
} 


enum UserType { 
    case student(Student) 
    case teacher(Teacher) 
} 
+0

坦率地說......這是常見於所有OOP語言 爪哇 - 接口 斯威夫特 - 協議 C++,C#.......酷 – GvSharma

+0

@gvsharma更好? –

+0

haa ...是它的智能足以捕捉關於OOP繼承的觀點 – GvSharma

0

「可能是這個或那個」:在Swift中,您使用枚舉。一門課爲學生,一門爲老師,一門爲「學生或老師」。