/*******************************************************************************/
// 协议
protocol Description{

func description() -> String
mutating func aMutatingMethod()
class func aTypeMethod()
// func anOptionalMethod()
}

// 假设要声明可选择实现的方法,须要在func前加@optional声明,并且协议的前面须要加@objc声明,这种协议结构体不能遵守,所以也不同意mutating方法的存在
//@objc protocol Description{
//
// func description() -> String
//// mutating func aMutatingMethod()
// class func aTypeMethod()
// @optional func anOptionalMethod()
//}

// 结构体
struct Point{
var x = 0.0
var y = 0.0
}

struct Size{
var width = 0.0
var height = 0.0
}

var point = Point()
var size = Size()

var array = Array<String>()

struct Rect{
var origin = Point()
var size = Size()
var center: Point{
get{
let centerX = origin.x + size.width / 2
let centerY = origin.y + size.height / 2
return Point(x:centerX , y:centerY)
}
set{
// set方法会提供一个默认的新值:newValue
let originX = newValue.x - size.width / 2
let originY = newValue.y - size.height / 2
origin = Point(x:originX, y:originY)
}
}

mutating func moveBy(deltaX:Double, deltaY:Double){
let newX = origin.x + deltaX
let newY = origin.y + deltaY
origin = Point(x:newX, y:newY)
}

func description() -> String{
return "(\(origin.x),\(origin.y),\(size.width),\(size.height))"
}

mutating func aMutatingMethod(){

}

func anOptionalMethod(){

}

// 假设是实现协议中得类方法,尽管在协议中使用了classkeyword,可是在结构体或者枚举实现的时候依旧须要使用statickeyword
static func aTypeMethod(){

}

}
var frame = Rect()
frame.origin.x = 10
frame.origin.y = 10
frame.size = Size(width:100,height:100)

println("frame.center = (\(frame.center.x), \(frame.center.y))")

frame.center = Point(x:100,y:100)
println("frame.center = (\(frame.center.x), \(frame.center.y))")
println("frame.origin = (\(frame.origin.x), \(frame.origin.y))")

// 枚举
enum PersonIdentify:String{
case Teacher = "teacher"
case Student = "student"
}

// 类
class Person{
var name: String?
var sex: String?

var identify: PersonIdentify?
// 构造器中,第一个參数依旧会创建一个和局部參数名称同样的外部參数名称
init(name: String, sex: String, identify: PersonIdentify){

self.name = name;
self.sex = sex;
self.identify = identify
}

func description() -> String{
// 调用枚举值的toRaw()方法能够获取到枚举值的初值
return "name = \(name) sex = \(sex) course = \(identify!.toRaw())"
}

// 在类中假设实现协议中定义的mutating方法,那么不须要加"mutating"keyword
func aMutatingMethod(){

}

class func aTypeMethod(){

}
}

var person1 = Person(name:"humingtao",sex:"m",identify:.Student)
var person2 = Person(name:"kebi",sex:"m",identify:.Teacher)
switch(person1.identify!){
case .Teacher:
println("I am a teacher")
case .Student:
println("student")
}

class Student:Person{
var number: String?
// 在类中,类型属性仅仅能够是计算属性,可是在枚举和结构体中,既能够是计算属性,也能够是存值属性
// 在类中,声明一个类型属性的keyword是class,在结构体和枚举中是static
class var attendClassTime: String{
return "9:30"
}
init(name: String, sex: String, number: String){

super.init(name: name, sex: sex, identify: .Student)
self.number = number
}
}
var student1 = Student(name: "hmt",sex: "m",number: "12345678")

class Teacher:Person{
var course: String?
init(name: String, sex: String, course: String){

super.init(name: name, sex: sex, identify: .Teacher)
self.course = course
}
override func description() -> String{

return super.description() + "" + "course = \(course)"
}
}

// 思考为什么加"?"
class course{
var name: String?
init(name: String){

self.name = name
}
}