Swift 3 :
Class and Structure
군산대학교 컴퓨터정보통신공학부 컴퓨터정보공학전공
남 광 우
kwnam@kunsan.ac.kr
Swift 3 Tour and Language Guide by Apple
꼼꼼한 재은씨의 Swift 2 프로그래밍
Class와 Structure
• 공통점
• Properties : 값을 저장하기 위한 Properties
• Method : 함수기능을 제공하기 위한 메소드
• Subscript : 속성값에 접근하기 위한 subscript 
• Initializer : 초기 상태를 설정하기 위한 초기화
• Extension : 디폴트 구현이상으로 확장
• 표준 기능을 제공하기 위한 프로토콜
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
structure class
Camel 표기법 : 
• Structure와 class 이름은
대문자로 시작
• 변수는 소문자로 시작
• 이후 단어 첫글자 대문
자
• Class가 추가적으로 갖는 기능
• 상속 기능
• Type Casting 기능
• Deinitializer 기능(소멸자)
• 하나 이상의 레퍼런스 카운팅 
 
 
• 값의 전달
• Structure : Value Type
• Class : Reference Type
Class와 Structure
Class와 Structure
• Method와 Properties
• Instance 생성
struct Resolution {
var width = 0
var height = 0
func desc() ‐> String {
return “Resolution 구조체”;
}
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
func desc() ‐> String {
return “Resolution 구조체”;
}
}
structure class
let  someResolution = Resolution(); let  someVideo = VideoMode();
Properties 접근
• Propertie 접근 방법(structure)
• Propertie 접근 방법(Class)
let  someResolution = Resolution();
let  someVideo = VideoMode();
print("The width of someResolution is (someResolution.width)")
// Prints "The width of someResolution is 0
someVideoMode.resolution.width = 1280
print("The width of someVideoMode is (someVideo.resolution.width)")
// Prints "The width of someVideoMode is 0"
Memberwise 초기화
• Structure만 지원
• Properties 들을 별도 구현 없이 생성자 형태로 초기화
가능
• 다음 두 가지 형태 모두 지원
• 예
let vga = Resolution(width: 640, height: 480)
Resoultion();
Resolution( width: int, height : int ); 
Structure = Value Type
• Structure는 Value Type
let  hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
print("cinema is now (cinema.width) pixels wide")
print("hd is still (hd.width) pixels wide") Result : 1920
Result : 2048
Structure = Reference Type
let  tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
• Structure는 Reference Type
let  alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print("The frameRate is now (tenEighty.frameRate)")
Result : 30.0
print("The frameRate is now (alsoTenEighty.frameRate)")
Result : 30.0
동일 비교
• === 와 !==
• Identical to (===)
• Not identical to (!==)
let  hdtv01 = VideoMode();
let   hdtv02 = tenEighty;
let   hdtv03 = VideoMode();
if  ( hdtv01 === hdtv02 ) {
print(“ hdtv01 === hdtv02 “);
}
if(  (hdtv01 === hdtv03 ) }
print(“ hdtv01 === hdtv03 “);
}
true
false
Structure와 Class 선택
• 다음의 경우 중 하나 이상 해당하면 Structure
• 서로 연관된 몇 개의 기본 데이터 타입을 캡슐화
• 상속 필요 없음
• 값의 전달에 Value Type이 합리적일 때
• 캡슐화된 원본 데이터를 보존해야 할 때
Properties
• Stored Properties
• Computed Properties
• Type Properties
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
struct Rect {
var origin = Point()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
}
}
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
Stored Properties
• 변수형 Stored Properties
• 상수형 Stored Propties
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6  // Error !!!
Stored Properties
• Lazy Stored Properties
class DataImporter {
var fileName = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// the DataImporter instance는 아직 생성되지 않음
print(manager.importer.fileName)
// 실제 사용되는 순간 DataImporter 인스턴스가 생성됨
Computed Properties
• 연산 Properties
• 실제 값을 저장하는 것이 아니라, 값을 만들기 위한
메소드를 저장
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set(newCenter) {
origin.x = newCenter.x ‐ (size.width / 2)
origin.y = newCenter.y ‐ (size.height / 2)
}
}
}
var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at ((square.origin.x), (square.origin.y))")
// Prints "square.origin is now at (10.0, 10.0)"
Computed Properties
• 연산 Properties의 사용
Computed Properties
• 연산 Properties에서 setter 파라미터 생략
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x ‐ (size.width / 2)
origin.y = newValue.y ‐ (size.height / 2)
}
set (newCenter) {
origin.x = newCenter.x ‐ (size.width / 2)
origin.y = newCenter.y ‐ (size.height / 2)
}
}
}
Property Observer
• Properties 값의 변경을 감지
• willSet : 값이 저장되기 직전 호출
• didSet : 값이 저장된 직후 호출
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to (newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added (totalSteps ‐ oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
Type Properties
• 정의
• 같은 Type의 모든 인스턴스가 공유하는 Properties
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
didSet {
if currentLevel > AudioChannel.thresholdLevel {
// cap the new audio level to the threshold level
currentLevel = AudioChannel.thresholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
// store this as the new overall maximum input level
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}
Type Properties
• Type Properties의 사용 예
Method
• Instance Method
• 특정 Class나 structure의 인스턴스에 속하는 함수
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter()
// 0
counter.increment()
// 1
counter.increment(by: 5)
// 6
counter.reset()
// 0
Method
• self
• class 나 structure 내의 property를 참조할 때
func increment() {
self.count += 1
}
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) ‐> Bool {
return self.x > x
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
print("This point is to the right of the line where x == 1.0")
}
Method
• mutating
• 인스턴스 메소드내에서 Property를 수정하는 함수
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at ((somePoint.x), (somePoint.y))")
// Prints "The point is now at (3.0, 4.0)"
Method
• self에 값을 할당하기
• mutating 메소드 내에서 실행
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
Method
• enumeration에서 self에 값을 할당하기
enum TriStateSwitch {
case off, low, high
mutating func next() {
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off
Type Method
• 정의
• 인스턴스를 생성하지 않고 호출할 수 있는 메소드
• 예 : Java의 static method
• class keyword 사용
• 주의
• class에서는 class, struct/enum에서는 static 키워드
• 인스턴스 메소드를 참조할 수 없음
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod()
struct LevelTracker {
static var highestUnlockedLevel = 1
var currentLevel = 1
static func unlock(_ level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) ‐> Bool {
return level <= highestUnlockedLevel
}
@discardableResult
mutating func advance(to level: Int) ‐> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}
class Player {
var tracker = LevelTracker()
let playerName: String
func complete(level: Int) {
LevelTracker.unlock(level + 1)
tracker.advance(to: level + 1)
}
init(name: String) {
playerName = name
}
}
var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now (LevelTracker.highestUnlockedLevel)")
player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
print("player is now on level 6")
}
Type Method
상속(Inheritance)
• 기본 클래스의 정의
• 인스턴스 생성과 사용
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at (currentSpeed) miles per hour"
}
func makeNoise() {
// do nothing ‐ an arbitrary vehicle doesn't necessarily make a noise
}
}
let someVehicle = Vehicle()
print("Vehicle: (someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour
상속(Inheritance)
• 상속의 구현
• 상속 인스턴스 생성과 사용
class Bicycle: Vehicle {
var hasBasket = false
}
let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 15.0
print("Bicycle: (bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour
상속(Inheritance)
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: (tandem.description)")
// Tandem: traveling at 22.0 miles per hour
• 상속의 사용
Overriding
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
• 메소드의 Overriding
• 사용 예
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
Overriding Getter/Setter
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear (gear)"
}
}
• getter의 Overriding
• 사용
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: (car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
Overriding Observer
• Observer의 Overriding
• 사용
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: (automatic.description)")
Preventing Override
• final
• final var
• final func
• final class func
• final subscript

Swift 3 Programming for iOS : class and structure