现在主要体验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
9

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

可选协议声明

1
2
3
4
5
6
7
8
9

@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
34

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
98

/// 地图坐标相关数据结构和常量定义
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
7

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
111

/**
*  图形接口
*/
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
12

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
3

   var squareShap:Shape = square;
   squareShap.draw();

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