Swift基础语法(三) 面向对象语法高级特性

来源:互联网 发布:近邻算法 编辑:程序博客网 时间:2024/05/16 10:39

import Foundation

//1.继承

struct Position{

    var longtitue:Double =0

    var latitue:Double =0

}

struct Leave {

    var color:String!

    init(color:String){

        self.color = color

        println("\(color)叶子")

    }

}

class Living { //生物类

    //有什么办法能防止父类中的某个方法被重写呢?

    func grow(){

        println("生长中")

    }

}

class Plant:Living{//植物类

    var leaves:Array<Leave>!//叶子属性

    var position:Position//生长位置属性

    func photosynthesis(){

        println("光合作用中")

    }

}

class Fruit:Plant{

    func fruct(){

        println("结果中")

    }

}

class Peach: Fruit {

    override init() {

        super.init()

        self.leaves =Array(count: 10, repeatedValue:Leave(color: "绿"))

        self.position =Position(longtitue: 138, latitue: 28)

    }

    func graft(){

        println("嫁接中")

    }

    //在子类中,写上同名,同样参数和返回值的方法,以重写父类中的相应方法.参数一定要相同,否则就是重载,而不是重写或者覆盖

    override func grow() {//重写方法grow

        println("桃子以自己的方式生长着")

    }

    func grow(speed:Int){//此时不是重写,而是方法重载

        println("生长速度\(speed)")

    }

    //那么属性如何重写呢?比如想在Peach中重写position属性

    override var position:Position!{

        get{

            return super.position

        }

        set{

            super.position = newValue

        }

    }

    func life(){

        self.grow()

        println("生长在(\(self.position.longtitue),\(self.position.latitue)),长出了\(self.leaves.count)片叶子)")

        self.photosynthesis()

        self.graft()

        self.fruct()

    }

}

var peach = Peach()

peach.life()

/*绿叶子

生长中

生长在(138.0, 28.0),长出了10片叶子)

光合作用中

嫁接中

结果中*/



//2.多态(同样的操作或者方法,不同的对象在执行时会出现完全不同的行为,这就叫多态)

//多态是针对不同对象调用同一个方法,能产生不一样的结果.

//运算符重载,例如重载"><"这个符号,实现两个对象的数据交换


//3.封装


//4.类扩展  extension

extension String{//String类进行扩展

    subscript(start:Int, length:Int) ->String{

        get{

            return (selfas NSString).substringWithRange(NSMakeRange(start, length))

        }

        set{

            var s = ""

            var e = ""

            var tmp = Array(self)

            

            for (idx,item) in enumerate(tmp){

                if(idx < start){

                    s += "\(item)"

                }

                if(idx > start + length){

                    e += "\(item)"

                }

            }

            self = s + newValue + e

        }

    }

    subscript(Index:Int) ->String{

        get{

            return String(Array(self)[Index])

        }

        set{

            var tmp = Array(self)

            tmp[Index] = Array(newValue)[0]

            self = ""

            for (idx, item) in enumerate(tmp){

                self += "\(item)"

            }

        }

    }

}

//不仅仅是字符串,int double这样的类型,也可以对齐进行方便扩展

extension Double{

    func mm() -> String{

        return "\(self/1)mm"

    }

    var cm:String{

        return "\(self/10)cm"

    }

    func dm() -> String{

        return "\(self/100)dm"

    }

    var m:String{

        return "\(self/1000)m"

    }

    var km:String{

        return "\(self/(1000*1000))km"

    }

}

var value = 2000000000.0

println(value.mm())

println(value.cm)

println(value.dm())

println(value.m)

println(value.km)


//5.协议(协议只做了方法的声明,包括方法名,返回值,参数等这些信息,而没有具体的实现方法)

//协议本身也可以继承自另一个协议

protocol Animal{

    func move()

}

protocol Bird : Animal{

    func song()

}

class Chiken:Bird {

    func song() {

        println("母鸡咯咯")

    }

    func move(){

        println("母鸡走")

    }

}

class Pegion:Bird{

    func song() {

        println("鸽子咕咕")

    }

    func move(){

        println("鸽子飞")

    }

}

//6.类组合

protocol vehicle{

    func drive()

}

class Motor:vehicle {

    var brand = ""

    init(brand:String){

        self.brand = brand

    }

    func start(){

        println("\(self.brand)启动")

    }

    func drive() {

        println("\(self.brand)驾驶")

    }

}

class Maker {

    var name:String =""

    var from:String =""

    func printMaker(){

        println("制造商来自\(self.from)\(self.name)")

    }

}

class Audi: Motor {

    var maker:Maker//类组合

    init(){

        self.maker =Maker()

        self.maker.name ="奥迪"

        self.maker.from ="德国"

        super.init(brand:"Audi")

    }

}

var audi = Audi()

audi.start()//Audi启动

audi.drive()//Audi驾驶

audi.maker.printMaker()//制造商来自德国的奥迪


//7.可选链(可选链就是将可选的调用链接在一起形成一个链,如果任何一个节点为空(nil),将导致整个链失效)

//举例

class Student{

    var country:Country?

}

class Country {

    var name:String ="China"

}

var xiaoli = Student()

xiaoli.country = Country()

println(xiaoli.country?.name)//Optional("China")

println(xiaoli.country!.name)//China


//8.泛型(<>符号来声明泛型)例如在字典的实现中,我们看到了对字典的键和值都应用了泛型,并且可以分别应用不同的类型.在字典中key要遵循Hashable协议

struct Student1:Hashable{

    var no:Int?

    var name:String?

    

    //实现Hashable协议,返回hashValue的值

    var hashValue: Int {

        return self.no!

    }

    //由于Hashable协议是Equatable协议的子协议,所以还要实现equatable协议,即实现 func ==(lhs: Self, rhs: Self) -> Bool  方法

    //但是!!!这个方法并不能放在结构体内部实现,而是移动到结构体外部.这样就能顺利声明,Student结构体来当键值了

}

func == (lhs: Student1, rhs:Student1) -> Bool{

    return lhs.no == rhs.no

}

struct School {

    var name:String?

    var addr:String?

}

var studentsDic:Dictionary<Student1,School> = Dictionary(minimumCapacity:2)//如果Student1没有遵从Hashable协议,是编译不通过的: Type 'Student1' does not conform to protocol 'Hashable'


//泛型的应用,一种是上面所说的这种数据结构的定义,比如上面字典的定义,比如我们定义一个堆栈,或者是队列还有一个更重要的就是,独立的函数和操作也能使用泛型

//例子,写一个比较常见的交换数据的操作,来看一下泛型的应用

func swapInts(inout a:Int,inout b:Int){

    var tmp = a

    a = b

    b = tmp

}

func swapStrs(inout a:String,inout b:String){

    var tmp = a

    a = b

    b = tmp

}

//泛型的出现,可以让我们无视数据类型,一个方法,包打天下

func swapT<T>(inout a:T,inout b:T){

    var tmp = a

    a = b

    b = tmp

}

var a:Double =2.0

var b:Double =3.0

swap(&a, &b)

var sa = Student1(no:100, name: "a")

var sb = Student1(no:101, name: "b")

swap(&sa, &sb)

println(sa.no)//Optional(101)


0 0