Swift学习笔记 ——(二)

前言

    上一篇是Swift的一些简单语法,这篇也继续写基本的语法,正所谓,“磨刀不误砍材工”,有兴趣的可以看一下上一篇文章:Swift学习笔记——(一)
    这里主要写一下在Swift中如何定义类和对类的一些操作,另外还有观察属性、可选性以及枚举类型进行了简单的整理。

  1. 类和对象

    首先,声明一个类:

    class MyClass {
        var className = "hello";
        var classAge = 18;
        func classStart() -> String {
            return "This class has created!";
        }
    }

    接着,创建一个类的实例并使用:

    // 创建实例
    var myClass = MyClass();
    print(myClass.className); // "hello"
    // 修改变量
    myClass.className = "world";
    print(myClass.className); // "world"
    // 调用方法
    myClass.classStart();
  2. 类的init方法
    在类中可以定义一个初始化方法init,在被实例化的时候调用,如果想现在开始的时候做一些事,在这里好似最合适不过的了。

    class MyClass {
        var className = "swift-1";
        init() {
            className = "init";
            // 也可以使用self
            // self.className = "init";
            print("hello \(className)");
        }
    }
    
    var myClass = MyClass(); // "hello init"
  3. 子类可以继承父类

    swift中继承使用class a: A表示a继承A,重写方法使用override

    // 父类People
    class People {
        func say() -> String {
            return "I am parent's say";
        }
        func read() -> String {
            return "I am parent's read";
        }
    }
    
    // 子类Child继承父类People
    class Child: People {
        // 重写父类的方法
        override func say() -> String {
            return "I am child's say";
        }
    }
    
    var child = Child();
    var sayMsg = child.say();
    var readMsg = child.read();
    print("say:" + sayMsg); // "say:I am child's say"
    print("read:" + readMsg); // "read:I am parent's read"
  4. 每一个属性都有一个getset方法用来获取属性和设置属性的值:

    class People {
        var firstName = "Tom";
    }
    
    class Child: People {
        var name: String {
            // name属性的get方法
            get {
                return firstName;
            }
            // name属性的set方法
            set {
                firstName = newValue + " James"; // newValue:表示给name属性赋的值
            }
        }
    }
    
    var child = Child();
    var childName = child.name; // 这时候调用用了get方法获取到name
    print(childName); // "Tom"
    child.name = "Jack"; // 这时候调用了set方法,即newValue的值为"Jack"
    childName = child.name; // 这时候由于上一步的set方法改变了name,所以每次获取属性值时重新调用get方法
    print(childName); // "Jack James"

    当然,可能觉得newValue直接使用不是很舒服,可以显示的传如一个参数,上面的例子可以写成这样:

    // ...
    set(value) {
        firstName = value + " James";
    }
    // ...
  5. 属性观察
    我们可能有时候想要知道属性的变化,并且在变化之前或者之后做一些事,这时候就要使用willSetdidSet,分别是在属性改变之前改变之后执行的方法。

    class Child {
        init() {
            name = "Tom";
        }
        var name: String {
            willSet(value) {
                print("当先的值为:" + name); // "Tom"
                print("即将变成的值为:" + value); // "James"
            }
            didSet(value) {
                print("当先的值为:" + name); // "James"
                print("改变之前的值为:" + value); // "Tom"
            }
        }
    }
    
    var child = Child();
    child.name = "James";

    当然,跟getset一样,可以显示的传递参数,如果不显示传递的,默认为newValueoldValue

    // ...
    willSet {
        print("即将变成的值为:" + newValue);
    }
    didSet {
        print("改变之前的值为:" + oldValue);
    }
    // ...
  6. 可选型
    在Swift中有一种特殊的类型,叫做可选型。在其他语言中在声明一个变量的时候可以赋为空值,比如说null,但是在Swift中叫做nil,使用也是有区别的,在Swift中如果要设置为nil要这样写:

    var name: String? = nil;
    var age: Int = nil; // "报错"

    上面的String?表示name既可以是字符串类型也可以是nil,所以叫做可选型。

    StringString?是两种不同的类型。

    可选型是不能直接使用的,使用的时候要先进行unwrapped,否则会报错,例如:

    var name1: String? = "Tom";
    var name2 = name1 + " James"; // "报错"

    这个时候如果我们打印出name1就会发现,name1是这样的:
    optional
    所以我们需要进行unwrapped,可以是这样的:

    var name1: String? = "Tom";
    if let name = name1 {
        // 进行解析可选型,如果不是nil那么就将让name等于实际的字符串
        print(name + " James"); // "Tom James"
    } else {
        // 可选型为nil
        print("unwrapped fail");
    }

    当然Swift还提供了另一种符号,就是!,是可以强行拿到可选型实际的值,但是如果值为nil就会发生错误。

    var name1: String? = "Tom";
    print(name1! + " James");
    var name2: String? = nil;
    print(name2! + " Jack"); // "报错"

    当我们想获取可选型的值时,如果不是nil,给一个默认值;如果不是nil那就取可选型解包后的值,可以这样写:

    // 假设name1是一个可选型(String?)
    var name2 = name1 ?? "DefaultName";
    /* 也可以使用三木运算符 */
    var name3 = name1 != nil ? name1 : "DefaultName";

    有时候也可以不使用if进行解包,比如这样:

    var str1: String? = "my str";
    var STR = str1?.uppercased();
    print(STR); // Optional("MY STR")

    从上面的例子可以看出,可选型是可以进行链式操作的;并且,从得到的结果发现,对可选型就行解包之后调用函数得到的还是可选性,如果相对STR进行进一步操作的话,还是可以使用之前的if语句。

  7. 枚举类型
    枚举类型是Swift中的一种数据类型,用enum声明,例如:

    enum Color {
        case red
        case yellow
        case blue
    }

    当然也可以给定case的类型,或者给初始值,就像这样:

    enum Color: Int {
        case red = 1
        case yellow
        case blue
    }

    可以简写为:

    enum Color: Int {
        case red, yellow, blue
    }

    使用类型的时候:

    enum Color: Int {
        case red = 1
        case yellow
        case blue
    }
    var red: Color = Color.red;
    print(red); // "red"

    如果要去red对应的数值,使用rawValue

    enum Color: Int {
        case red = 1
        case yellow
        case blue
    }
    var red: Color = .red; // 此处可以简写为.red
    print(red.rawValue); // 1
    var blue: Color = .blue;
    print(blue.rawValue); // 3

    注:
    这里并没有给blue赋初始值,因为red为1,Swift自动给下面的case依次加1,所以blue为3。
    如果都不给初值,第一个也就是red默认为0,之后依次累加。

    enum Color: Int {
        case red
        case yellow
        case blue
    }
    var blue: Color = .blue;
    print(blue.rawValue); // 2

    同理,如果是String类型,那么默认值就是字符串:

    enum Color: String {
        case red
        case yellow
        case blue
    }
    var blue: Color = .blue;
    print(blue.rawValue); // "blue"

    如果知道了rawValue的值,如何知道是哪个case呢?方法是这样的:

    enum Color: Int {
        case red = 1
        case yellow
        case blue
    }
    if let blue = Color(rawValue: 3) {
        print("case的值是:" + blue); // "case的值是:blue"
    } else {
        print("fail");
    }

    这里通过rawValue获得值是一个可选型,因为如果这个rawValue可能是枚举类型中不存在的,所以,在上面的例子中,如果Color(rawValue: 4),那么得到的是nil,打印的应该是"fail"

    如果不想给case一个初始值,可以定义一个关联值(associated values),可以在后续进行赋值,就像这样:

    enum People {
        case name(String)
        case age(Int)
    }
    
    func getName( username: String) -> People {
        return .name(username);
    }
    
    var userInfo = getName(username: "Tom James");
    
    switch userInfo {
        case let .name(nameVal):
            print("姓名是:\(nameVal)"); // "姓名是:Tom James"
        case let .age(ageVal):
            print("年龄是:\(ageVal)");
    }

写在后面

本来想着一周搞定的,结果中间有很多事耽误了,现在已经搞了两周还是没写完,那就后续再补一篇 :)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值