JHHK

欢迎来到我的个人网站
行者常至 为者常成

9_2、方法、下标、继承(二)

目录

下标使用

/// 一、下标使用
func subscriptUse(){
    
    //1、下标使用
    do{
        print("-------1----------")
        class Point{
            var x=0,y=0
            static var z = 0
            
            subscript(index:Int)->Int{
                set{
                    if index == 0{
                        x = newValue
                    }else if index == 1{
                        y = newValue
                    }
                }
                get{
                    if index == 0{
                        return x
                    }else if index == 1{
                        return y
                    }
                    return 0
                }
            }
            
            //下标可以是类型方法
            static subscript(v1:Int,v2:Int)->Int{
                set{
                   z = newValue
                }
                get{
                   v1+v2
                }
            }
        }
        
        let p = Point()
        p[0] = 11
        p[1] = 12
        Point[20,30]=100
        print(p[0],p[1],Point[20,30])//11 12 50
    }
    
    
    //2、下标的使用
    do{
        print("----------2-----------")
        /**
         结构体 枚举 同样适用于下标 但要注意引用类型和值类型 内存改变时的区别
         subscript的返回值类型决定了 get方法内返回值的类型和set方法内newValue的类型
         subscript可以接受多个参数并且是任意类型的
         */
        
        struct Size{
            var x=0,y=0
            init(x:Int,y:Int) {
                self.x = x
                self.y = y
            }
        }
        
        class SizeManager{
            var size = Size(x: 0, y: 0)
            subscript(index:Int)->Size{
                set{
                    size = newValue
                }
                get{
                    return size
                }
            }
        }
        
        
        let sizeManager = SizeManager()
        sizeManager[0].x = 10
        sizeManager[0].y = 20
        print(sizeManager[0].x,sizeManager[0].y)//10 20
        
        
        /**
         如果Size是结构体类型 在SizeManager内拿掉set方法:
         sizeManager[0].x = 10//改行代码报错:Cannot assign to property: subscript is get-only
         sizeManager[0].y = 20//改行代码报错:Cannot assign to property: subscript is get-only
         根本原因是 sizeManager[0] 是值传递,返回的只是一个值,没有指向具体的内存
         //这样就不会报错,但是没有意义
         var newSize = sizeManager[0]
         newSize.x = 10

         
         如果将Size改为class类型 在SizeManager内拿掉set方法:
         编译正常通过 且赋值成功
         原因是:sizeManager[0] 引用传递 返回的是一个地址,这个地址指向sizeManager内的size属性的那块内存,
         此时sizeMnager[0].x 相当于var size = sizeManger[0] size.x = 10 并没有调用下标的set方法
         */
    }
}

继承的使用

/// 二、继承的使用
func inheritanceUse() -> Void {
    //值类型不支持继承 只有类支持继承
    //1、继承的内存结构
    class Animal {
        var age = 0
    }
    
    class Dog:Animal{
        var weight = 0
    }
    
    class ErHa:Dog{
        var iq = 0
    }
    
    let dog = ErHa()
    dog.age = 1
    dog.weight = 20
    dog.iq = 9
    print(dog.age,dog.weight,dog.iq)
    
    print(Mems.size(ofRef: dog))//引用所指向的内存大小    48
    print(Mems.ptr(ofRef:  dog))//引用所指向的内存地址    0x0000000102803d80
    //0x0000000100034420
    //0x0000000000000002
    //0x0000000000000001    //age
    //0x0000000000000014    //weight
    //0x0000000000000009    //iq
    //0x0000000102803d28
    print(Mems.memStr(ofRef: dog))//引用所指向的内存数据
}

重写

/// 三、重写
func overrideUse(){
    //1、重写方法、下标
    do{
        print("-------1----------")
        class Animal{
            func speak() -> Void {
                print("Animal speak")
            }
            subscript(index:Int)->Int{
                return index
            }
            
            //用class修饰的类型方法下标,允许被子类重写
            //用static修饰的类型方法下标,不允许被子类重写
            class func speak() {
                print("Class Animal speak")
            }
            class subscript(index:Int)->Int{
                return index
            }
            static func myself(){
                print("static Animal myself")
            }
        }
        
        
        class Cat:Animal{
            override func speak() {
                super.speak()
                print("Cat speak")
            }
            override subscript(index: Int) -> Int {
                let sum = index + super[index]
                return sum
            }
            
            override class func speak() {
                super.speak()
                print("Class Cat speak")
            }
            override class subscript(index: Int) -> Int {
                let sum = index + super[index]
                return sum
            }
            
            func myself() {
                print("Cat myself")
            }
        }
        
        var anim:Animal
        anim = Animal()
        anim.speak()
        print(anim[6])
        
        anim = Cat()
        anim.speak()
        print(anim[7])//14
        
        print("----------------------")
        
        Animal.speak()
        Animal.myself()
        print(Animal[6])
        
        Cat.speak()
        Cat.myself()
        print(Cat[7])
        
        /**
         打印结果如下:
         -------1----------
         Animal speak
         6
         Animal speak
         Cat speak
         14
         ----------------------
         Class Animal speak
         static Animal myself
         6
         Class Animal speak
         Class Cat speak
         static Animal myself
         14
         */
    }
    
    
    
    //2、重写属性(实例存储计算属性 类型存储计算属性)
    do{
        print("------------2----------")
        /**
         子类可以将父类的属性(存储、计算)重写为计算属性
         子类不可以将父类属性重写为存储属性
         只能重写var属性、不能重写let属性
         重写时,属性名、类型要保持一致
         
         子类重写后的属性权限 不能小于 父类属性的权限
         如果父类属性是只读的,那么类重写后的属性可以是只读的,也可以是可读写的
         如果父类属性是可读写的,那么子类重写后的属性也必须是可读写的
         */
        
        class Circle{
            var radius:Int = 0
            var diameter:Int{
                set{
                    print("Circle setDiameter")
                    radius = newValue / 2
                }
                get{
                    print("Circle getDiameter")
                    return radius * 2
                }
            }
            
            static var radius:Int = 0
            class var diameter: Int {
                set{
                    print("Class Circle setDiameter")
                    radius = newValue / 2
                }
                get{
                    print("Class Circle getDiameter")
                    return radius * 2
                }
            }
        }
        
        
        class SubCircle:Circle{
            override var radius: Int{
                set{
                    print("SubCircle setRadius")
                    super.radius = newValue > 0 ? newValue : 0
                }
                get{
                    print("SubCircle getRadius")
                    return super.radius
                }
            }
            
            override var diameter: Int{
                set{
                    print("SubCircle setDiameter")
                    super.diameter = newValue > 0 ? newValue : 0
                }
                get{
                    print("SubCircle getDiameter")
                    return super.diameter
                }
            }
            
            override class var diameter: Int{
                set{
                    print("Class SubCircle setDiameter")
                    super.diameter = newValue > 0 ? newValue : 0
                }
                get{
                    print("Class SubCircle getDiameter")
                    return super.diameter
                }
            }
        }
        
         
        print("----------------------")
        
        var circle:Circle
        circle = Circle()
        circle.radius = 6
        //Circle getDiameter
        //12
        print(circle.diameter)
        //Circle setDiameter
        circle.diameter = 20
        //10
        print(circle.radius)
        
        print("----------------------")
        
        circle = SubCircle()
        //SubCircle setRadius
        circle.radius = 6
        //SubCircle getDiameter
        //Circle getDiameter
        //SubCircle getRadius
        //12
        print(circle.diameter)
        //SubCircle setDiameter
        //Circle setDiameter
        //SubCircle setRadius
        circle.diameter = 20
        //SubCircle getRadius
        //10
        print(circle.radius)
        
        print("----------------------")
        
        Circle.radius = 6
        //Class Circle getDiameter
        //12
        print(Circle.diameter)
        //Class Circle setDiameter
        Circle.diameter = 20
        //10
        print(Circle.radius)
        
        print("----------------------")
        
        SubCircle.radius = 6
        //Class SubCircle getDiameter
        //Class Circle getDiameter
        //12
        print(SubCircle.diameter)
        //Class SubCircle setDiameter
        //Class Circle setDiameter
        SubCircle.diameter = 20
        
        //10
        print(SubCircle.radius)
    }
}

为父类添加属性观察器

/// 四、为父类添加属性观察器
func overridePropertyObserver()->Void{
    class Circle{
        var radius:Int = 1{
            willSet{
                print("Circle willSetRadius")
            }
            didSet{
                print("Circle didSetRadius")
            }
        }
        
        var computePro:Int{
            set{
                print("Circle setComputePro")
            }
            get{
                print("Circle getComputePro")
                return 10
            }
        }
        
        class var clComputePro: Int {
            set{
                print("Circle setclComputePro")

            }
            get{
                print("Circle getclComputePro")
                return 20
            }
        }
    }
    
    class SubCircle:Circle{
        override var radius:Int{
            willSet{
                print("SubCircle willSetRadius")
            }
            didSet{
                print("SubCircle didSetRadius")
            }
        }
        
        
        override var computePro: Int{
            willSet{
                print("SubCircle willSetComputePro")
            }
            didSet{
                print("SubCircle didSetComputePro")
            }
        }
        
        
        override class var clComputePro: Int{
            willSet{
                print("SubCircle willclComputePro")
            }
            didSet{
                print("SubCircle didclComputePro")
            }
        }
    }
    
    
    let circle = SubCircle()
    
    
//    SubCircle willSetRadius
//    Circle willSetRadius
//    Circle didSetRadius
//    SubCircle didSetRadius
    circle.radius = 10
    
    
    print("----------------------")
    
    
//    SubCircle willSetComputePro
//    Circle setComputePro
//    SubCircle didSetComputePro
    circle.computePro = 12
    
    
     
    print("----------------------")
    

//    SubCircle willclComputePro
//    Circle setclComputePro
//    SubCircle didclComputePro
    SubCircle.clComputePro = 22
}

final使用

//五、final使用
func finalUse() -> Void {
    
    /**
     被final修饰的方法、下标、属性、禁止被重写
     被final修饰的类、禁止被继承
     */

    
    
//    final class Circle{
    class Circle{
        //final var radius:Int = 0
        var radius:Int = 0
        var diameter:Int = 0
    }
    
    
    class SubCircle:Circle{
        override var radius:Int{
            set{
                
            }
            get{
                return 10
            }
        }
    }
    
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.