Upload
kwang-woo-nam
View
37
Download
0
Embed Size (px)
Citation preview
Swift 3 : Class and Structure
군산대학교 컴퓨터정보통신공학부 컴퓨터정보공학전공
남 광 우
Swift 3 Tour and Language Guide by Apple꼼꼼한재은씨의 Swift 2 프로그래밍
Class와 Structure
•공통점• Properties : 값을저장하기위한 Properties• Method : 함수기능을제공하기위한메소드• Subscript : 속성값에접근하기위한 subscript • Initializer : 초기상태를설정하기위한초기화• Extension : 디폴트구현이상으로확장• 표준기능을제공하기위한프로토콜
struct Resolution {var width = 0var height = 0
}
class VideoMode {var resolution = Resolution()var interlaced = falsevar frameRate = 0.0var 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 = 0var height = 0
func desc() ‐> String {return “Resolution 구조체”;
}}
class VideoMode {var resolution = Resolution()var interlaced = falsevar frameRate = 0.0var 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 = 1280print("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 = hdtenEighty.interlaced = truetenEighty.name = "1080i"tenEighty.frameRate = 25.0
• Structure는 Reference Type
let alsoTenEighty = tenEightyalsoTenEighty.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: Intlet 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: Intlet 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 stepsstepCounter.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 = 10static var maxInputLevelForAllChannels = 0var currentLevel: Int = 0 {didSet {if currentLevel > AudioChannel.thresholdLevel {// cap the new audio level to the threshold levelcurrentLevel = AudioChannel.thresholdLevel
}if currentLevel > AudioChannel.maxInputLevelForAllChannels {// store this as the new overall maximum input levelAudioChannel.maxInputLevelForAllChannels = currentLevel
}}
}}
Type Properties• Type Properties의사용예
Method• Instance Method
• 특정 Class나 structure의인스턴스에속하는함수
class Counter {var count = 0func increment() {count += 1
}func increment(by amount: Int) {count += amount
}func reset() {count = 0
}}
let counter = Counter()// 0counter.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.0func 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.0mutating func moveBy(x deltaX: Double, y deltaY: Double) {x += deltaXy += 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.0mutating func moveBy(x deltaX: Double, y deltaY: Double) {self = Point(x: x + deltaX, y: y + deltaY)
}}
Method• enumeration에서 self에값을할당하기
enum TriStateSwitch {case off, low, highmutating func next() {switch self {case .off:self = .low
case .low:self = .high
case .high:self = .off
}}
}var ovenLight = TriStateSwitch.lowovenLight.next()// ovenLight is now equal to .highovenLight.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 = 1var currentLevel = 1
static func unlock(_ level: Int) {if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) ‐> Bool {return level <= highestUnlockedLevel
}
@discardableResultmutating func advance(to level: Int) ‐> Bool {if LevelTracker.isUnlocked(level) {currentLevel = levelreturn true
} else {return false
}}
}
class Player {var tracker = LevelTracker()let playerName: Stringfunc 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.0var 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 = truebicycle.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 = truetandem.currentNumberOfPassengers = 2tandem.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 = 1override var description: String {return super.description + " in gear \(gear)"
}}
• getter의 Overriding
•사용
let car = Car()car.currentSpeed = 25.0car.gear = 3print("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.0print("AutomaticCar: \(automatic.description)")
Preventing Override
• final• final var• final func• final class func• final subscript