ksnowlv

回顾过去,总结以往;立足现在,铭记当下;技术为主,笔记而已.

Swift的类-结构-协议-枚举

| Comments

现在主要体验swift类(创建,销毁,继承/派生),结构体,协议,枚举等方面的使用.

1.结构体和常量定义。

结构体定义其实与c/c++大体类似。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
let QMapPointZero:QMapPoint = QMapPoint(x:0,y:0);
let QMapSizeZero:QMapSize = QMapSize(width:0,height:0);

struct QMapPoint{
    var x:Int = 0;
    var y:Int = 0;
}

struct QMapSize{
    var width:Int = 0;
    var height:Int = 0;
}

2.枚举定义(和c/c++中差别比较大)。

swift中,像类和其它类型命名类似,枚举可以拥有和它关联的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

enum QMapType:Int{
    case QMapTypeNone
    case QMapTypeNoraml
    case QMapTypeStreetView
    case QMapTypeTraffic

    func getMapType() ->Int{

        switch self{
        case .QMapTypeNone:
            return 0;
        case .QMapTypeNoraml:
            return 1;

        case .QMapTypeStreetView:
            return 2;

        case .QMapTypeTraffic:
            return 3;

        default:
            return -1;
        }
    }
}

如果访问这些枚举变量,需要通过枚举名来访问。以上为例就是通过QMapType.QMapTypeNoraml访问,如果要访问枚举变量的值,可通过getMapType访问。

3.关于协议/接口。

与objetive-c类似,不支持多继承,同样需要通过protocol声明定义,同样,分为必选协议和可选协议。但是,swift中的协议可以有成员变量。

必选协议的声明

1
2
3
4
5
6
7
8
protocol ShapeInterface{

    //成员变量
    var className: String { get }
    //协议默认属性为required
    func draw();
    func description() -> String
}

可选协议声明

1
2
3
4
5
6
7
8
@objc protocol QMapViewInterface{

    //成员变量
    var className: String { get }
    func mapView(mapType:Int);
    //协议默认属性为required
    optional func draw();
}

4.类的声明,定义,继承,派生等。

c++/objective-c类似,支持面向对象,有构造初始化,有析构,支持继承/派生。

我们声明shape类,继承ShapeInterface协议。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Shape:ShapeInterface{

    var className: String = "Shape"

    var name:NSString;

    //可以看作初始化函数
    init(name:String){
        self.name = name;
    }

    //可以看作析构函数
    deinit{
        print("Shape deinit");
    }

    func draw(){
        print("shape name = \(name)\n");
    }

    func description() -> String {
        return name;
    }

    func area() ->Double {
        return 0;
    }

    func circumference() ->Double{

        return 0;
    }
}

5.示例:地图类和图形类

地图类相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/// 地图坐标相关数据结构和常量定义
let QMapPointZero:QMapPoint = QMapPoint(x:0,y:0);
let QMapSizeZero:QMapSize = QMapSize(width:0,height:0);


struct QMapPoint{
    var x:Int = 0;
    var y:Int = 0;
}



struct QMapSize{
    var width:Int = 0;
    var height:Int = 0;
}

struct QMapRect{
    var point:QMapPoint = QMapPointZero;
    var size:QMapSize = QMapSizeZero;
}

/**
地图支持底图类型

- QMapTypeNone:       初始化类型,无意义
- QMapTypeNoraml:     普通地图
- QMapTypeStreetView: 街景地图
- QMapTypeTraffic:    实时路况地图
*/
enum QMapType:Int{
    case QMapTypeNone
    case QMapTypeNoraml
    case QMapTypeStreetView
    case QMapTypeTraffic

    func getMapType() ->Int{

        switch self{
        case .QMapTypeNone:
            return 0;
        case .QMapTypeNoraml:
            return 1;

        case .QMapTypeStreetView:
            return 2;

        case .QMapTypeTraffic:
            return 3;

        default:
            return -1;
        }
    }
}

/**
*  地图View,支持地图显示,拖拽等
*/
class QMapView{
    var mapType:QMapType = QMapType.QMapTypeNone;
    var mapRect:QMapRect;

    init(mapType:QMapType){
        self.mapType = mapType;
        self.mapRect = QMapRect()
    }

    func setMapRect(mapRect:QMapRect){
        self.mapRect = mapRect;
    }

    func getMapRect() -> QMapRect{
        return mapRect
    }

    deinit{
        print("QMapView deinit\n")
    }

    func draw(){
        print("mapType = \(mapType.getMapType()) drawing\n");
    }
}


/**
*  地图协议,支持可选协议
*/
@objc protocol QMapViewInterface{

    //成员变量
    var className: String { get }
    func mapView(mapType:Int);
    //协议默认属性为required
    optional func draw();
}

调用:

1
2
3
4
5
6
var mapView:QMapView = QMapView(mapType:QMapType.QMapTypeNoraml);
var mapSize =  QMapSize(width: Int(self.view.frame.width), height:Int(self.view.frame.height));
mapView.setMapRect(QMapRect(point: QMapPointZero, size: mapSize));
mapView.draw();
print("mapView rect = {point = {\(mapView.mapRect.point.x),\(mapView.mapRect.point.y)},size = {\(mapView.mapRect.size.width),\(mapView.mapRect.size.height)}}\n");

日志输出:

1
2
3
mapType = 1 drawing
mapView rect = {point = {0,0},size = {320,480}}
QMapView deinit

图形类(Shape类族)相关

Shape类族 image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
*  图形接口
*/
protocol ShapeInterface{

    //成员变量
    var className: String { get }
    //协议默认属性为required
    func draw();
    func description() -> String
}


/**
*  图形基类
*/
class Shape:ShapeInterface{

    var className: String = "Shape"

    var name:NSString;

    //可以看作初始化函数
    init(name:String){
        self.name = name;
    }

    //可以看作析构函数
    deinit{
        print("Shape deinit\n");
    }

    func draw(){
        print("shape name = \(name)\n");
    }

    func description() -> String {
        return name;
    }

    func area() ->Double {
        return 0;
    }

    func circumference() ->Double{

        return 0;
    }
}


let KPI:Double = 3.14159265;
/**
*  圆类
*/
class Circle :Shape{
    var center:Point;
    var radius:Double;

    init(name:String, center:Point, radius:Double){

        self.center = center;
        self.radius = radius;
        super.init(name:name);
        super.className = "Circle";
    }

    deinit{
        print("Circle deinit\n");
    }

    override func description() -> String {
        return name;
    }

    override func area() ->Double{
        return 3.14159265 * pow(self.radius,2);
    }

    override func circumference() ->Double{

        return KPI * 2 * radius;
    }
}

/**
*  正方形类
*/
class Square: Shape{
    var _size:Double!;//加!后,可以不用添加self._size方法在init方法super.init之前

    init(name:String, size:Double){

        super.init(name: name);
        super.className = "Square";
        _size = size;
    }

    deinit{
        print("Square deinit\n");
    }

    override func area() -> Double {
        return pow(_size, 2);
    }

    override func circumference() -> Double {
        return 4 * _size;
    }
}

调用

1
2
3
4
5
6
7
8
9
10
11
var shape:Shape = Shape(name: "Shape");
shape.draw();
print("className = \(shape.className) shape:{description = \(shape.description()), area = \(shape.area()), circumference = \(shape.circumference())}\n");

var circle:Circle = Circle(name: "Circle", center: Point(v: 10, h: 20), radius: 10.5);
circle.draw();
print("className = \(circle.className) circle:{description = \(circle.description()), area = \(circle.area()), circumference = \(circle.circumference())}\n");

var square:Square = Square(name: "Square", size:4);
square.draw();
print("className = \(square.className) square:{description = \(square.description()), area = \(square.area()), circumference = \(square.circumference())}\n");

日志输出

1
2
3
4
5
6
7
8
9
10
11
shape name = Shape
className = Shape shape:{description = Shape, area = 0.0, circumference = 0.0}
shape name = Circle
className = Circle circle:{description = Circle, area = 346.3605896625, circumference = 65.97344565}
shape name = Square
className = Square square:{description = Square, area = 16.0, circumference = 16.0}
Square deinit
Shape deinit
Circle deinit
Shape deinit
Shape deinit

小结:

  • 1.派生类的初始化顺序,先初始化基类,再初始化自身;析构顺序和初始化顺序相反,
  • 2.对象的创建顺序和析构顺序是相反的。
  • 3.如果派生类在类的外部调用基类的同名函数,如何调用呢? 与objective-c/python中的调用都不太一样。可以使用声明基类指针的方式。
1
2
   var squareShap:Shape = square;
   squareShap.draw();


参考链接:http://stackoverflow.com/questions/24021093/error-in-swift-class-property-not-initialized-at-super-init-call/24150540#24150540

Comments

comments powered by Disqus
Included file 'custom/after_footer.html' not found in _includes directory