//方法、下标、继承1-15
//1.方法
/*
枚举、结构体、类都可以定义实例方法、类型方法
实例方法:通过实例对象调用,类似OC对象方法
类型方法:通过类型调用,用static或者class关键字定义
self,在实例方法中代表实例对象,在类型方法中代表类型
*/
class Car {
static var cout = 0
init() {
Car.cout += 1
}
static func getCount() -> Int { self.cout /* 等价self.cout Car.self.cout Car.cout*/ }
}
//2.mutating
//结构体和枚举是值类型,默认情况下,值类型的属性不能被自身的实例方法修改,在func 关键字前加mutating可以允许这种修改行为
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(deltaX: Double, deltaY: Double) {
x += deltaX
y += deltaY
//等价 self = Point(x: x + deltaX, y: y + deltaY)
}
}
enum StateSwitch {
case low, middle, high
mutating func next() {
switch self {
case .low:
self = .middle
case .middle:
self = .high
case .high:
self = .low
}
}
}
//3.discardableResult
//如有警告 在func前加@discardableResult消除,目前没有先不管
struct Point0 {
var x = 0.0, y = 0.0
mutating func moveX(detalX: Double) -> Double {
x += detalX
return x
}
}
var p = Point0()
p.moveX(detalX: 10)
//4.下标(脚本)
//使用subscript可以为任意类型(枚举、结构体、类)增加下标功能,subscript的语法类似于实例方法、计算属性,本质就是方法,subscript中定义的返回值类型决定了get方法的返回值类型、set方法中newValue的类型,subscript可以接受多个参数,并且了类型任意值
class Point1 {
var x = 0.0, y = 0.0
subscript(index: Int) -> Double {
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
}
}
}
var p1 = Point1()
p1[0] = 11.1
p1[1] = 22.2
print(p1.x)
print(p1.y)
print(p1[0])
print(p1[1])
//5.subscript可以没有set方法,但必须要有get方法
class Point2 {
var x = 0.0, y = 0.0
subscript(index: Int) -> Double {
get {
if index == 0 {
return x
} else if index == 1 {
return y
}
return 0
}
}
}
//如果只有get方法,可以省略get
class Point3 {
var x = 0.0, y = 0.0
subscript(index: Int) -> Double {
if index == 0 {
return x
} else if index == 1 {
return y
}
return 0
}
}
//6.结构体、类作为返回值对比
class Point4 {
var x = 0, y = 0
}
class PointManager4 {
var point = Point4()
subscript(index: Int) -> Point4 {
get { point }
}
}
var pm4 = PointManager4()
pm4[0].x = 11
pm4[1].y = 22
//Point4(x: 11, y: 22)报错
print("------")
print(pm4[0])
print(pm4.point)
struct Point5 {
var x = 0, y = 0
}
class PointManager5 {
var point = Point5()
subscript(index: Int) -> Point5 {
set { point = newValue }
get { point }
}
}
var pm5 = PointManager5()
pm5[0].x = 11
pm5[1].y = 22
Point5(x: 11, y: 22)
print("------")
print(pm5[0])
print(pm5.point)
//7.接受多个参数的下标
class Grid {
var data = [[0, 1, 2],[3, 4, 5],[6, 7, 8]]
subscript(row: Int, column: Int) -> Int {
set {
guard row >= 0 && row < 3 && column >= 0 && column <= 3 else {
return
}
data[row][column] = newValue
}
get {
guard row >= 0 && row < 3 && column >= 0 && column < 3 else {
return 0
}
return data[row][column]
}
}
}
var grid = Grid()
grid[0,1] = 77
grid[1,2] = 88
grid[2,0] = 99
print(grid.data)
//8.继承
/*
值类型(枚举、结构体)不支持继承,只有类支持继承
没有父类的类成为基类,swift并没有像OC、java那样的规定:任何类最终都要继承自某个基类。
子类可以重写父类的下标、方法、属性,重写必须加上override关键字
*/
//9.内存结构
class Animal {
var age = 0
}
class Dog: Animal {
var weight = 0
}
class ErHa: Dog {
var iq = 0
}
let aaa = Animal()
aaa.age = 10
print("--------")
//print(Mems.size(ofRef:aaa)) //32
//print(Mems.memStr(ofRef:aaa))
/*
0x000000010001d078
0x0000000000000002
0x000000000000000a
0x0002000000000000
*/
let d = Dog()
d.age = 10
d.weight = 20
//print(Mems.size(ofRef: d)) //32
//print(Mems.memStr(ofRef: d))
/*
0x000000010001d128
0x0000000000000002
0x000000000000000a
0x0000000000000014
*/
let eee = ErHa()
eee.age = 10
eee.weight = 20
eee.iq = 30
//print(Mems.size(ofRef: eee)) //48
//print(Mems.memStr(ofRef: eee))
/*
0x000000010001d1f8
0x0000000000000002
0x000000000000000a
0x0000000000000014
0x000000000000001e
0x0003000000000780
*/
//10.重写实例方法、下标
class Animal0 {
func speak() {
print("Animal0 speak")
}
subscript(index: Int) -> Int {
return index
}
}
class Cat: Animal0 {
override func speak() {
super.speak()
print("Cat speak")
}
override subscript(index: Int) -> Int {
return super[index] + 1
}
}
var anim: Animal0
anim = Animal0()
anim.speak()//Animal0 speak
print(anim[6])//6
anim = Cat()
anim.speak() //Animal0 speak //Cat speak
print(anim[6]) //7
//被class修饰的类型方法、下标,允许被子类重写,被static修饰的类型方法、下标,不允许被子类重写
class Animal1 {
class func speak() {
print("Animal1 speak")
}
class subscript(index: Int) -> Int {
return index
}
}
Animal1.speak() //Animal1 speak
print(Animal1[6]) //6
class Cat1: Animal1 {
override class func speak() {
super.speak()
print("Cat1 speak")
}
override class subscript(index: Int) -> Int {
return super[index] + 1
}
}
Cat1.speak() //Cat1 speak
print(Cat1[6]) //7
//11.重写属性
/*
子类可以将父类的属性(存储、计算)重写为计算属性,子类不可以将父类属性重写为存储属性。只能重写var属性,不能重写let属性,重写时属性名、类型要一致.
子类重写后的属性权限不能小于父类属性的权限,如果父类属性是只读的,那么子类重写后的属性可以是只读的、也可以是读写的,
如果父类属性是可读写的,那么子类重写后的属性也必须是可读写的
*/
//12.重写实例属性
class Circle {
var radiu: Int = 0
var diameter: Int {
set {
print("Circle setDiameter")
radiu = newValue / 2
}
get {
print("Circle getDiameter")
return radiu * 2
}
}
}
var circle: Circle
circle = Circle() //Circle getDiameter
circle.radiu = 6 //12
print(circle.diameter)
circle.diameter = 20 //Circle setDiameter
print(circle.radiu) //10
class SubCircle: Circle {
var radius: Int {
set {
print("SubCircle setRadius")
super.radiu = newValue > 0 ? newValue : 0
}
get {
print("CubCircle getRadius")
return super.radiu
}
}
override var diameter: Int {
set {
print("SubCircle setDiameter")
super.diameter = newValue > 0 ? newValue : 0
}
get {
print("SubCircle getDiameter")
return super.diameter
}
}
}
circle = SubCircle()
circle.radiu = 6
print(circle.diameter)//SubCircle getDiameter//Circle getDiameter//12
circle.diameter = 20//SubCircle setDiameter//Circle setDiameter
print(circle.radiu) //10
//13.重写类型属性
//被class修饰的计算类型属性,可以被子类重写,被static修饰的类型属性(存储、计算),不可以被子类重写
class Circle0 {
static var radius: Int = 0
class var diameter: Int {
set {
print("Circle0 setDiameter")
radius = newValue / 2
}
get {
print("Circle0 getDiameter")
return radius * 2
}
}
}
class SubCircle0: Circle0 {
override static var diameter: Int {
set {
print("SubCircle0 setDiameter")
super.diameter = newValue > 0 ? newValue : 0
}
get {
print("SubCircle0 getDiameter")
return super.diameter
}
}
}
print("00000000")
Circle0.radius = 6
print(Circle0.diameter) //Circle0 getDiameter //12
Circle0.diameter = 20 //Circle0 setDiameter
print(Circle0.radius)//10
//14.属性观察器
class Circle1 {
var radius: Int = 1
}
class SubCircle1: Circle1 {
override var radius: Int {//可以在子类中为父类属性(除了只读计算属性、let属性)增加属性观察器
willSet {
print("SubCircle1 willSetRadius",newValue)
}
didSet {
print("SubCircle1 didSetRadius",oldValue,radius)
}
}
}
var circle1 = SubCircle1()
circle1.radius = 10 //SubCircle1 willSetRadius 10 //SubCircle1 didSetRadius 1 10
class Circle2 {
var radius: Int = 1 {
willSet {
print("Circle2 willSetRadius",newValue)
}
didSet {
print("Circle2 didSetRadius",oldValue,radius)
}
}
}
class SubCircle2: Circle2 {
override var radius: Int { //重写父类存储属性观察器
willSet {
print("SubCircle2 willSetRadius",newValue)
}
didSet {
print("SubCircle2 didSetRadius",oldValue,radius)
}
}
}
var circle2 = SubCircle2()
circle2.radius = 10
/*
SubCircle2 willSetRadius 10
Circle2 willSetRadius 10 //真正的修改是在父类中修改的
Circle2 didSetRadius 1 10
SubCircle2 didSetRadius 1 10
*/
class Circle3 {
var radius: Int {
set {
print("Circle3 setRadius",newValue)
}
get {
print("Circle3 getRadius")
return 20
}
}
}
class SubCircle3: Circle3 {
override var radius: Int { ////重写父类计算属性观察器
willSet {
print("SubCircle3 willSetRadius",newValue)
}
didSet {
print("SubCircle3 didSetRadius",oldValue,radius)
}
}
}
var circle3 = SubCircle3()
circle3.radius = 10
/*
Circle3 getRadius //在改值之前就先拿到oldValue,所以会打印这句
SubCircle3 willSetRadius 10
Circle3 setRadius 10
Circle3 getRadius
SubCircle3 didSetRadius 20 20
*/
class Circle4 {
class var radius: Int {
set {
print("Circle4 setRadius",newValue)
}
get {
print("Circle4 getRadius")
return 20
}
}
}
class SubCircle4: Circle4 {
override static var radius: Int { //重写父类类型属性
willSet {
print("SubCircle4 willSetRadius",newValue)
}
didSet {
print("SubCircle4 willSetRadius",oldValue,radius)
}
}
}
SubCircle4.radius = 10
/*
Circle4 getRadius
SubCircle4 willSetRadius 10
Circle4 setRadius 10
Circle4 getRadius
SubCircle4 willSetRadius 20 20
*/
//15.final
//被final修饰的方法、下标、属性,禁止被重写,被final修饰的类,禁止被继承
网友评论