美文网首页iOS Developer
swift面向对象基础<三>

swift面向对象基础<三>

作者: shineDeveloper | 来源:发表于2016-11-28 14:51 被阅读72次

    接下来就讨论一下可选链,类型属性和类型方法,构造器

    1.可选链是用于处理可选类型的属性,方法和下标
    2.使用可选链代替强制解析
    3.调用方法
    4.调用下标

    //创建3个关联类
    class customer{
        var name = ""
        var emp: employee?
        init(name: String){
            self.name = name
        }
    }
    
    class company {
        var name = ""
        var addr = ""
        init(name: String , addr: String){
            self.name = name
            self.addr = addr
        }
    }
    
    class employee{
        var name = ""
        var title = "行政"
        var company: company!
        init(name: String, title: String){
            self.name = name
            self.title = title
        }
        func info() {
            print("本员工名为\(self.name),职位为\(self.title)")
        }
    }
    
    var c = customer(name: "tom")
    var emp = employee(name: "jack", title: "student")
    //设置customer关联的employee实例
    c.emp = emp
    //设置empoyee关联的compony实例
    emp.company = company(name: "swift", addr:"shanghai")
    print("为\(c.name)服务的公司是:\(c.emp!.company.name)")
    
    //第二种情况
    var c2 = customer(name: "lucky")
    //设置customer关联的employee实例
    c2.emp = employee(name:"helly", title: "客服")
    //print(c2.emp!.company.name)//此时是没有为company赋值的,它的值为nil.为此使用可选链访问属性
    //使用可选链访问属性
    /*
     可选链的访问方式:将强制解析的!换成?,即是是隐式解析后面也要添加?
     
     */
    print(c2.emp?.company?.name)//输出为nil
    //可选链会自动防伪关联属性的可选情况,自动判别是否为nil
    

    通过可选链来访问方法和下标

    首先做可选链访问方法

    //创建3个关联类
    class customer{
        var name = ""
        var emp: employee?
        init(name: String){
            self.name = name
        }
        
        //定义一个常量类型的employee数组,用于模拟系统中所有的员工
        let employees = [employee(name: "张三" , title: "销售"),
                         employee(name: "小明" , title: "售后"),
                         employee(name: "han" , title: "普通员工"),
                         employee(name: "better" , title: "销售主管")
                         ]
        //定义一个方法,该方法可根据员工名返回对应的员工,返回值为可选类型
        func findemp(empname: String) -> employee!{
            for emp in employees{
                if emp.name == empname {
                    return emp
                }
            }
            return nil
        }
    }
    
    class company {
        var name = ""
        var addr = ""
        init(name: String , addr: String){
            self.name = name
            self.addr = addr
        }
    }
    
    class employee{
        var name = ""
        var title = "行政"
        var company: company!
        init(name: String, title: String){
            self.name = name
            self.title = title
        }
        func info() {
            print("本员工名为\(self.name),职位为\(self.title)")
        }
    }
    //通过可选链来调用方法
    var c3 = customer(name: "paul")
    c3.findemp(empname: "张三")?.info()
    c3.findemp(empname: "小明")?.info()
    

    可选链访问下标

    //可选链访问下标
    var dict = [Int : customer]()
    dict[1] = customer(name: "han")
    dict[2] = customer(name: "angle")
    
    dict[1]?.findemp(empname: "better")?.info()
    dict[4]?.findemp(empname: "better")?.info()
    

    类型属性和类型方法

    值类型的类型属性

    //1.值类型的类型属性
    enum season {
        //为枚举定义类型存储属性,使用可选类型,系统将其初始化为nil
        static var desc : String?
        //为枚举定义类型存储属性,且声明为常量
        static let name = "季节"
        static var info: String{
            get{
                return "代表季节的枚举,其desc为:\(desc)"
            }
            set{
                print("程序尝试对info计算属性进行赋值:\(newValue)")
            }
            
        }
    }
    //对season枚举的类型属性赋值
    season.desc = "季节类"
    print(season.name)
    season.info = "新的info"
    print(season.info)
    //结构体可以包含实例计算属性,不能包含实例存储属性
    
    struct fkrange{
        //为结构体定义类型存储属性,使用可选类型,系统将其初始化为nil
        static var desc : String?
        //为结构体定义类型存储属性,且声明为常量
        static let maxwidth = 10000
        static let maxheight = 40000
        //定义类型计算属性,该属性只有get部分,是一个只读属性
        static var maxarea: Int{
            return maxwidth * maxheight
        }
        
    }
    fkrange.desc = "描述范围的结构体"
    print(fkrange.desc)
    print(fkrange.maxwidth)
    print(fkrange.maxheight)
    print(fkrange.maxarea)
    
    

    class在类中修饰属性和方法

    类的属性:

    //类的类型属性
    class user{
        //为类定义类型计算属性
        class var namemaxlength: Int {
            get{
                return 24
            }
            set{
                print(newValue)
            }
        }
    }
    print(user.namemaxlength)
    user.namemaxlength = 20
    //类中不可以定义类型存储属性,只能包含类型存储属性
    

    值类型的类型方法

    //值类型的类型方法
    enum season2{
        //为枚举定义类型存储属性,使用可选类型,系统将其初始化为nil
        static var desc : String?
        //为枚举定义类型存储属性,且声明为常量
        static let name = "季节"
        //定义无参数的类型方法
        static func info(){
            print("季节类的info方法")
        }
        //定义一个带参数的类型方法
        static func setdesc(desc : String){
            self.desc = desc
        }
    }
    season2.info()
    season2.setdesc(desc: "季节变化的枚举")
    print(season2.desc)
    

    类的类型方法:

    //类的类型方法
    class math{
        //类中不允许定义类型存储属性,使用类型计算属性代替
        class var pi: Double{
            return 3.1415
        }
        class func abs(value: Double) -> Double{
            return value < 0 ? -value : value
        }
        //定义类型方法,取消第二个形参的外部形参名
        class func pow(base: Double, _ exponet: Int) -> Double{
            var result = 1.0
            for idx in 1...exponet{
                result *= base
            }
            return result
        }
        //定义类型方法,类型方法可以直接访问类型属性
        class func radian2degree(radian: Double) -> Double{
            return radian*180 / pi
        }
        //定义类型方法,类型方法可通过self应用类型属性
        class func degree2radian(degree: Double) -> Double{
            return degree * self.pi / 180
        }
        
    }
    print(math.pi)
    print(math.pow(base: 2, 5))
    print(math.radian2degree(radian: 1.3))
    print(math.degree2radian(degree: 1.2))
    

    构造器

    1.swift构造器构造出来的实例有系统隐式返回
    2.构造器的作用完成结构体和类实例存储属性的初始化
    3.为实例存储属性赋初值的时机:
    1>定义实例存储属性时赋初始值
    2>在构造器中为实例存储属性赋初始值

    实例存储属性的初始化分类:
    1>定义实例存储属性时,显示指定了初始值
    2>实例存储属性的类型为可选类型
    3>系统提供的默认构造器为实例存储属性提供初始值
    4>显示提供的构造器为实例存储属性提供初始值

    类和结构体的构造器

    swift只为类提供一个无参数的构造器
    swift为结构体提供2个构造器:无参数的构造器和初始化所有实例存储属性的构造器

    可能失败的构造器

    结构体,枚举或者是类不能成功返回这个类型的实例。如:用户传入的参数不对,会让构造器的创建失败,而此时就需要可能失败的构造器

    1.使用init?或者init!来进行定义
    2.在构造器执行体中return nil 标示构造器失败
    3.swift不允许构造2个形参列表的构造器,即是一个是可能失败的构造器,一个是普通的构造器也不行。

    构造器的外部形参名

    //构造器的外部形参名
    struct fkpoint{
        var left: Int = 0
        var top: Int = 0
        //定义带两个参数的构造器,并为第二个参数显示指定外部形参名
        init(left: Int , y top: Int){
            self.left = left
            self.top = top
        }
        
    }
    
    var p1 = fkpoint(left: 20, y: 12)
    

    取消构造器的外部形参名

    //取消构造器的外部形参名
    class person {
        var name: String?
        var gender: String?
        var age = 0
        //由于该类中前2个实例存储属性使用了可选类型,后一个存储属性指定了初始值
        //因此该结构体对构造器没有要求,故此处可以随便定义构造器
        //取消构造器参数的外部形参名
        init(_ name: String, _ gender: String){
            self.name = name
            self.gender = gender
        }
    }
    //调用构造器时无需要使用外部形参名
    
    var p = person("虽无空", "南")
    print(p.name)
    

    在构造过程中,使用闭包初始化存储属性

    //使用闭包或函数为属性设置初始值
    struct closureinit {
        //使用闭包对test实例属性执行初始化
        var test: Int = {
            var dt = NSDate()
            var gregorian = NSCalendar.current
            //定义一个时间字段的旗标,指定将会获取指定月日的信息
            var unitflags = NSCalendar.Unit.month | NSCalendar.Unit.day
            var comp = gregorian.component(unitflags, from: dt)
            //获取当前的月份
            var month = Int(comp.month)
            return month
        }()
    }
    

    值类型的构造器重载

    //值类型的构造器重载
    struct constructoroverload {
        var name: String?
        var amount: Int?
        //提供无参数的构造器
        init(){}
        //提供带两个参数的构造器来完成构造过程
        init(name: String, amount: Int){
            self.name = name
            self.amount = amount
        }
    }
    //通过无参数构造器创建constructoroverload实例
    var oc1 = constructoroverload()
    //通过有参数构造器创建constructoroverload
    var oc2 = constructoroverload(name: "swift", amount: 8000)
    print(oc1.name)
    print(oc2.name)
    

    构造器代理

    在定义构造器时,通过self,init(实参)来调用其它构造器,来完成实例的部分构造过程

    //构造器代理
    struct apple{
        
        var name: String
        var color: String
        var weight: Double!
        
        init(_ name: String , _ color: String)
        {
            self.name = name
            self.color = color
        }
        
        //两个参数的构造器
        init(name: String, color: String){
            self.init( name, color)
        }
        
        //为构造器显示指定外部形参名
        init(applename n: String, applecolor c: String){
            self.init(n, c)
            
        }
    }
    

    //可能失败的构造器

    //可能失败的构造器
    struct cat {
        let name: String
        init?(name: String){
            //如果传入的name参数为空字符串,构造器失败,返回nil
            if name.isEmpty {
                return nil
            }
            self.name = name
        }
        
    }
    
    enum season {
        case spring, summer, autumn, winter
        //使用init!定义可能失败的构造器,则改构造器创建的实例可以进行隐式解析
        init!(name: Character){
            switch name {
                case "s":
                self = .spring
                case "u":
                self = .summer
                case "a":
                self = .summer
                case "w":
                self = .winter
            default:
                return nil
            }
            
        }
    }
    

    相关文章

      网友评论

        本文标题:swift面向对象基础<三>

        本文链接:https://www.haomeiwen.com/subject/ozvgpttx.html