2015-12-04 59 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中,您使用枚举。一门课为学生,一门为老师,一门为“学生或老师”。