swift之方法&下标&继承重写

14 篇文章 0 订阅

一、方法

1.1-什么是方法

/*
枚举、结构体、类都可以定义实例方法、类型方法
实例方法:通过实例调用
	需要创建实例后调用的方法
类型方法:通过类型调用,用static或者class关键字定义
	static func getCount() -> Int{count}
	直接调用,类名.方法调用

self在实例方法中代表实例对象,在类型方法中代表类型
Person->static var count=0在类型方法中count=self.count=Person.self.count=Person.count
*/
class Person{
    static var count=0
    init(){
        Person.count+=1
    }
    static func getCount()->Int{ count }
}
let p1=Person()
let p2=Person()
let p3=Person()
print(Person.getCount())
3

1.2-mutating(值类型方法修改自身属性)

/*
结构体和枚举是值类型,默认情况下,值类型的属性不能被自身的实例方法修改
在func关键字前加mutating可以允许修改
*/
struct Person {
    var height=180,weight=140
    mutating func grow(_ h:Int,_ w:Int){
        height += h
        weight += w
        //self=Person(height:height+h,weight:weight+w)
    }
}
var p = Person()
p.grow(5, 5)
print(p.height,p.weight)
185 145

enum Person {
    case child,old,young
    mutating func grow(){
        switch self {
        case .child:
            self = .young
        case .young:
            self = .old
        case .old:
            self = .old
        }
    }
}
var p=Person.child
p.grow()
print(p)
young

1.3-@discardableResult(忽略警告)

/*

*/
//Result of call to 'getCount()' is unused
class Person{
    var count=0
    @discardableResult
    func getCount()->Int{ 1 }
}
var p = Person()
p.getCount()

@discardableResult
func run()->Int{
    //process
    10
}
run()


二、下标

2.1-什么是下标

/*
使用subscript可以给人以类型增加下标功能,下标脚本
语法类似于实力方法、计算属性、本质就是方法(函数)
subscript中定义了返回值类型决定了get方法的返回值类型和set中的newValue的类型
subscript可以接受多个参数并任意类型
*/


class Person{
    var height=180,weight=140
    subscript(type:Int)->Int{
        set{
            if type==0{
                height=newValue
            } else if type==1{
                weight=newValue
            }
        }
        get{
            if type==0{
                return height
            } else if type==1{
                return weight
            }
            return 0
        }
    }
}
var p = Person()
print(p[0],p[1])
p[0]=175
p[1]=120
print(p.height,p.weight)
180 140
175 120

2.2-下标的细节

/*
subscript可以没有set方法,但必须要有get方法,如果只有get方法可以省略get
subscript可以设置参数标签,下标也可以是类型方法
*/

class Person{
    var height=180,weight=140
    subscript(type:Int)->Int{
            if type==0{
                return height
            } else if type==1{
                return weight
            }
            return 0
    }
}
var p = Person()
print(p[0],p[1])
180 140

class Person{
    var height=180,weight=140
    subscript(type type:Int)->Int{
            if type==0{
                return height
            } else if type==1{
                return weight
            }
            return 0
    }
}
var p = Person()
print(p[type:0],p[type:1])
180 140

class Person{
    static subscript(height:Int)->Double{
        return Double(height)*0.7
    }
}
print(Person[185])
185

2.3-结构体、类做为返回值对比

/*
类是引用类型可以直接修改,结构体是值类型所以要set

*/

class Person{
    var height=0,weight=0
}
class Child{
    var person = Person()
    subscript(index:Int)->Person{
        get {person}
    }
}
var c = Child()
c[0].height=180
print(c[0].height,c[0].weight)
180 0


struct Person{
    var height=0,weight=0
}
class Child{
    var person = Person()
    subscript(index:Int)->Person{
        set {person=newValue}
        get {person}
    }
}
var c = Child()
c[0].weight=140
print(c[0].height,c[0].weight)
0 140

2.4-接受多个参数的下标

class Map{
    var data=[
        [0,1,2],
        [3,4,5],
        [6,7,8]
    ]
    subscript(row:Int,col:Int)->Int{
        set{
            guard row>=0 && row<3 && col>=0 && col < 3 else{
                return
            }
            data[row][col]=newValue
        }
        get{
            guard row>=0 && row<3 && col>=0 && col < 3 else{
                return 0
            }
            return data[row][col]
        }
    }
}
var m = Map()
print(m[1,2])
5
m[1,2]=55
print(m.data)
[[0, 1, 2], [3, 4, 55], [6, 7, 8]]

三、继承

3.1-什么是继承

/*
值类型(枚举、结构体)不支持继承,只有类支持继承
没有父类的类称为基类
swift并没有像oc、java规定任何类最终都要继承自某个基类
子类可以重写父类的下标、方法、属性,重写必须加上override
*/

3.2-内存结构

/*
一个属性8个字节,类信息头两行16字节,整体是16的倍数
*/
class Person{
    var age=0
}
class Child:Person{
    var weight=0
}
class Young: Child{
    var height=0
}
var p = Person()
p.age=1
/*
 0x0000000100008300
 0x0000000000000002
 0x0000000000000001
 0x0000000000000000
 */
var c=Child()
c.age=2
c.weight=2
/*
0x0000000100009302
0x0000000000000002
0x0000000000000002
0x0000000000000000
*/
var y = Young()
y.age=3
y.height=4
y.weight=5
/*
0x0000000100009531
0x0000000000000002
0x0000000000000003
0x0000000000000004
0x0000000000000005
0x0000000000000000
*/

3.3-重写实例方法、实例下标

/*
*/
class Person{
    func walk(){
        print("person walk")
    }
    subscript(index:Int)->Int{
        return index
    }
}
class Child:Person{
    override func walk(){
        super.walk()
        print("child walk")
    }
    override subscript(index: Int) -> Int {
        return super[index]+1
    }
}
var p:Person
p=Person()
p.walk()
person walk
print(p[3])
3
p=Child()
p.walk()
person walk
child walk
print(p[3])
4

3.4-重写类型方法、类型下标

/*
类方法既可用class来修饰,也可用static来修饰。
如果父类的类方法使用static修饰的话,子类不能重写这个类方法;
如果父类的类方法使用class修饰的话,子类能够重写这个类方法。
如果父类的类方法是使用final class修饰的话,子类不能重写这个类方法。
综上,static自带final class的性质。
你希望子类能够重写其父类的某个类方法,那就使用class修饰这个类方法。
你不希望子类能够重写其父类的某个类方法,那就使用static修饰这个类方法。
PS:
final class classMethod:可继承,但禁止子类重写其父类中的类方法
final intanceMethod:可继承,但禁止子类重写其父类中的对象方法
private:本类私有的方法或属性,子类不可继承
fileprivate:本文件私有的方法或属性,本文件外不可访问、继承
*/
class Person{
    class func walk(){
        print("person walk")
    }
    class subscript(index:Int)->Int{
        return index
    }
}
class Child:Person{
    override class func walk(){
        super.walk()
        print("child walk")
    }
    override class subscript(index: Int) -> Int {
        return super[index]+1
    }
}
Person.walk()
person walk
print(Person[1])
1
Child.walk()
person walk
child walk
print(Child[1])
2


3.5-重写属性

/*
子类可以将父类的属性(存储、计算)重写为计算属性,不能重写为存储属性
计算属性的本质是方法所以可以重写
只能重写var属性,不能重写let属性
重写时,属性吗、类型要一致

子类重写后的属性权限不能小于父类属性的权限
如果父类是只读的,那么子类重写后的属性可以是只读的也可以是可读写的
如果父类是可读写的,那么子类重写后必须是可读写的
*/

3.6-重写实例属性

/*

*/
class Square{
    var lenght:Int=0
    var perimeter:Int{
        set{
            print("Square.perimeter set")
            lenght=newValue/4
        }
        get{
            print("Square.perimeter get")
            return lenght*4
        }
    }
}
var square:Square
square=Square()
square.lenght=3
print(square.perimeter)
Square.perimeter get
12
square.perimeter=20
print(square.lenght)
Square.perimeter set
5


class SubSquare:Square{
    override var lenght: Int{
        set{
            print("SubSquare.lenght set")
            super.lenght=newValue>0 ? newValue:0
        }
        get{
            print("SubSquare.lenght get")
            return super.lenght
        }
    }
    override var perimeter: Int{
        set{
            print("SubSquare.perimeter set")
            super.perimeter=newValue>0 ? newValue:0
        }
        get{
            print("SubSquare.perimeter get")
            return super.perimeter
        }
    }
}
var ss=SubSquare()
ss.lenght=5
SubSquare.lenght set
print(ss.perimeter)
SubSquare.perimeter get
Square.perimeter get
SubSquare.lenght get
20
ss.perimeter=20
SubSquare.perimeter set
Square.perimeter set
SubSquare.lenght set
print(ss.lenght)
SubSquare.lenght get
5

3.7-属性观察器

/*
子类可以给父类的计算属性增加属性观察器,之前说的willSet和set不能共存原则但是可以在子类实现
不管父类是实例属性、类型属性、存储属性、计算属性都可以增加属性观察器
*/
class Square{
    var lenght:Int=0
}
class SubSquare:Square{
    override var lenght: Int{
        willSet{
            print("SubSquare.lenght willSet",newValue)
        }
        didSet{
            print("SubSquare.lenght didSet",oldValue)
        }
    }
}
var ss=SubSquare()
ss.lenght=20
SubSquare.lenght willSet 20
SubSquare.lenght didSet 0


class Square{
    var lenght:Int=0{
        willSet{
            print("Square.lenght willSet",newValue)
        }
        didSet{
            print("Square.lenght didSet",lenght)
    }
    }
}
class SubSquare:Square{
    override var lenght: Int{
        willSet{
            print("SubSquare.lenght willSet",newValue)
        }
        didSet{
            print("SubSquare.lenght didSet",lenght)
        }
    }
}
var ss=SubSquare()
ss.lenght=20
SubSquare.lenght willSet 20
Square.lenght willSet 20
Square.lenght didSet 20
SubSquare.lenght didSet 20


class Square{
    var lenght:Int{
        set{
            print("Square.lenght set",newValue)
        }
        get{
            print("Square.lenght get")
            return 11
        }
    }
}
class SubSquare:Square{
    override var lenght: Int{
        willSet{
            print("SubSquare.lenght willSet",newValue)
        }
        didSet{
            print("SubSquare.lenght didSet",lenght)
        }
    }
}
var ss=SubSquare()
ss.lenght=5
Square.lenght get
SubSquare.lenght willSet 5
Square.lenght set 5
Square.lenght get
SubSquare.lenght didSet 11

3.8-final

/*
被final修饰的方法、下标、属性禁止被重写
被final修饰的类禁止被继承
*/
class Square{
    var lenght:Int=0
    final subscript(index:Int)->Int{
        11
    }
    final func perimeter()->Int{
        return 22
    }
}
class SubSquare:Square{
    override var lenght:Int=1 //Cannot override with a stored property 'lenght'
    override subscript(index:Int)->Int{ //Subscript overrides a 'final' subscript
        return 111
    }
    override func perimeter()->Int{ //Instance method overrides a 'final' instance method
        return 222
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值