상속
상속된 클래스는 부모 클래스의 모든 기능을 상속받으며, 자신만의 기능을 추가할 수 있다.
상속받는 클래스 : 자식클래스(child class), 하위클래스(sub class)
상속하는 클래스 : 부모클래스(parent class), 상위클래스(super class)
단일 상속 : 스위프트에서 하위 클래스는 단 하나의 부모 클래스만 상속 받을 수 있다.
코딩 : class 자식이름 : 부모이름, 프로토콜이름1, 프로토콜이름2... { }
콜론 뒤에 여러개이면 나머지는 프로토콜이다.
프로토콜은 여러개가 올 수 있고 부모가 없이 올 수 도 있다.
상속은 클래스만 가능하며, 프로토콜은 채택(adopt) 라고 한다.
클래스, 구조체, 열거형, extension에 프로토콜을 채택(adopt) 할 수 있다.
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { }
// UIViewController 만 부모클래스이며 나머지는 프로토콜
class Man {
var age : Int = 1
var weight : Double = 3.5
func display() {
print("나이 = \(age), 몸무게 = \(weight)")
}
init(age: Int, weight: Double) {
self.age = age
self.weight = weight
}
}
class Student : Man {
// 비어있어 보여도 클래스 Man의 모든 것을 가지고 있음
}
var kim : Man = Man(age: 10, weight: 20.5)
kim.display()
var lee : Student = Student(age: 20, weight: 65.2)
lee.display()
print(lee.age)
super : 부모 메소드 호출시 사용
자식클래스에서 부모에 있는 것을 호출할때 사용한다
class Student : Man {
var name : String = "kim"
func displayS() {
print("나이 = \(age), 몸무게 = \(weight), 이름 = \(name)")
}
init(age1: Int, weight1: Double, name: String) {
super.init(age:age1, weight: weight1) // 부모클래스의 init을 가져옴
//age1으로 값을 받으면 부모클래스의 age로 값을 넘겨준다
self.name = name // 자식클래스의 name 추가함
}
}
var lee : Student = Student(age1: 20, weight1: 65.2, name: "홍길동")
lee.display() // 부모클래스의 메소드
lee.displayS() // 자식클래스의 메소드
overriding
부모클래스가 가지고 있는 메소드에 이름, 자료형, 매개변수, 리턴값이 똑같으면서 기능만 다르게 하는것
부모클래스로부터 상속받은 메소드의 기능을 바꿀 때 사용
class Student : Man {
var name : String = "kim"
override func display() {
print("나이 = \(age), 몸무게 = \(weight), 이름 = \(name)")
} // override를 사용하여 새로운 기능의 함수 적용
init(age1: Int, weight1: Double, name: String) {
super.init(age:age1, weight: weight1)
self.name = name
}
}
var lee : Student = Student(age1: 20, weight1: 65.2, name: "홍길동")
lee.display() // 자식클래스의 메소드를 우선적으로 사용한다
확장 : extension
클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가하고자 할 때 사용
하위 클래스를 생성하거나 참조하지 않고, 기존 클래스에 메소드나 init, 계산 프로퍼티 등의 기능을 추가하기 위해 사용
스위프트 언어의 built-in클래스(미리 만들어 놓은 클래스)와 iOS프레임워크에 내장된 클래스에 기능을 추가할 때 효과적
코딩 : extension 기존타입이름 { 새로운 기능 }
extension Double {
var squared : Double {
return self * self
}// 표준자료형 Double 구조체에 2배 값을 반환하는 프로퍼티 추가
}
let myValue: Double = 3.0
print(myValue.squared)
print(3.0.squared) // Double형 값에 바로 .squared 로 사용 가능
접근 제어 (access control, access modifier, access specifiers)
접근 속성(접근 수정자, 엑세스 수정자, 엑세스 지정자) 는 클래스, 메소드, 멤버의 접근 가능성을 설정하는 객체지향언어의 키워드
구성요소를 캡슐화 하는 데 사용한다.
(높은 접근수준)
open > public > internal > fileprivate > private (낮은 접근수준)
접근 제어를 생략하면 internal이 기본
public class MyClass {
fileprivate var name : String = "kim"
// fileprivate : 현재 소스 파일 내에서만 사용 가능
private func play() {}
// private : 현재 블럭 (MyClass) 내에서만 사용 가능
func diplay() {}
// internal 기본으로 되어 있음
}
모듈 : 코드 배포(code distribution)의 단일 유닛
앱, 프레임워크(UIKit 등), 외부라이브러리, Import Alamofire
open 및 public :
모듈의 모든 소스 파일 내에서 사용. 정의한 모듈을 가져오는 다른 모듈의 소스파일에서도 사용.
일반적으로 프레임워크에 공용 인터페이스를 지정할 때 open, public 사용
pen 접근은 클래스 및 클래스 멤버에만 적용
internal :
해당 모듈의 모든 소스 파일 내에서 사용, 해당 모듈의 외부 소스 파일에서는 사용되지 않는다.
App 이나 프레임워크 내부 구조를 정의할 때 사용
fileprivate :
해당 소스 파일 내에서만 사용 가능
private :
블록과 동일한 파일에 있는 해당 선언의 extension으로 제한
open class var blue : UIColor {get}
// open : 모듈 외부까지(클래스에만 사용) 접근 가능
// class : 클래스 프로퍼티
// 읽기 쓰기 가능한 프로퍼티는 정의 뒤에 {get set}
// 읽기만 가능한 프로퍼티는 정의 뒤에 {get}
프로토콜
특정 클래스와 관련없이 프로퍼티, 메소드 선언 집합
함수(메소드)의 기능정의는 없음
기능이나 속성에 대한 설계도 -> 기능은 없고 틀(설계도)만 있음
클래스, 구조체, 열거형에서 채택(adopt)하여 메소드를 구현해야함
자바, C#의 interface, C++의 abstract base class(최상 부모 클래스)
POP : portocol oriented programming -> 프로토콜 단위로 묶어 표현하고, extension으로 기본적인것을 구현하여 단일 상속의 한계를 극복
클래스에서 부모클래스는 하나만 가능하며 여러개 라면 나머지는 프로토콜
protocol 프로토콜이름 { 프로퍼티 이름 / 메소드 선언 } // 메소드는 선언만 있음
protocol 프로토콜 이름 : 다른 프로토콜1, 다른 프로토콜2 ... { } //프로토콜은 다중상속도 가능
protocol SomeProtocol {
var x: Int {get set} // 읽기와 쓰기 가능
var y: Int {get} // 읽기 전용
static var tx: Int {get set}
static func typeMethod() // static은 프로토콜 자체가 사용
func random() -> Double // 함수는 선언만 되있음
}
protocol Runnable {
var x : Int {get set}
func run ()
}
class Man : Runnable { // 프로토콜 채택(adopt)
var x : Int = 1 // 프로퍼티에 초기값 부여 -> 준수(conform)
func run() { // 메소드에 기능 부여 -> 준수(conform)
print("달린다~")
}
}
let lee = Man()
print(lee.x)
lee.run()
상속과 프로토콜 채택
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { }
과제
class c { // 부모클래스 c
var name : String = "Unknown" //저장 프로퍼티
var money : Int = -1 //저장 프로퍼티
var sex : String = "human" //저장 프로퍼티
func bank() { //클래스c의 메소드
print("\(name)님의 잔액은 \(money)원 입니다.")
}
init (name:String, money: Int, sex: String) { // 메소드 초기화
self.name = name
self.sex = sex
self.money = money
}
init (name:String, money:Int) { //overloading 1
self.name = name
self.money = money
}
init (name:String, sex:String) { ////overloading 2
self.name = name
self.sex = sex
}
}
protocol b { // 프로토콜 b
func bb(x: Int) -> Int // 프로토콜b의 메소드
}
class a : c, b { //자식클래스a는 부모클래스c 로부터 상속을 받고 프로토콜b를 채택함
var inOut : Int { //계산프로퍼티
get {
return money + 10
}
set(out) {
money = money - out
}
}
func bb(x: Int) -> Int { //프로토콜b의 기능 구현
return x * 2
}
override func bank() { //부모클래스c의 메소드를 overriding
print("\(name)님(\(sex))의 잔액은 \(money)원 입니다.")
}
}
let person : a = a(name: "cjyoun", money: 200) //클래스 a인 person을 만듬, sex는 default값
person.inOut = person.bb(x: 20) // person의 계산프로퍼티 inOut에 프로토콜b의 메소드bb의 값을 넣어줌
person.bank() // 클래스a의 bank 메소드 구현
열거형 : enum
관련있는 데이터들이 멤버로 구성되어 있는 자료형 객체
원치 않는 값이 잘못 입력되는 것 방지
입력 받을 값이 한정되어 있을 때
특정 값 중 하나만 선택하게 할 때
색깔 - 빨, 녹, 파 / 성별 - 남, 여
코딩 : enum 열거형이름 { 열거형 정의 }
enum planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
} // 하나의 case에 멤버들을 나열
enum Compass {
case North
case South
case East
case West
}
print(Compass.North)
var direction = Compass.West
direction = .East // 열거형 이름 생략
print(direction, type(of: direction)) // 자료형은 Compass(열거형)
열거형 멤버별 기능 정의
enum Compass {
case North
case South
case East
case West
}
var direction : Compass
direction = .South
switch direction { // switch-case 와 연결
case .North:
print("북")
case .South:
print("남") // South에 기능 구현
case .East:
print("동")
case .West:
print("서")
}
열거형 예제
스와이프(swipe) 제스처는 UISwipeGestureRecognizer 클래스로 인식
특정 방향으로의 스와이프는 다음 상수를 클래스의 direction 프로퍼티에 할당하여 인식
UISwipeGestureRecognizerDirection.right
UISwipeGestureRecognizerDirection.left
UISwipeGestureRecognizerDirection.up
UISwipeGestureRecognizerDirection.down
.right, .left, .up, .down 으로 축약 가능
설정된 방향이 없다면 기본 설정은 오른쪽 스와이프를 인식
UISwipeGestureRecognizer 인스턴스를 위쪽 스와이프에 인식하도록 설정
let wipeRecognizer = UISwipeGestureRecognizer(target: self, action: "swipeDetected")
swipeRecognizer.direction = .up
self.view.addGestureRecognizer(swipeRecognizer)
//열거형 멤버에는 메소드도 가능
enum Week: String {
case Mon, Tue, Wed, Thur, Fri, Sat, Sun
func printWeek() { //메소드 가능
switch self {
case .Mon, .Tue, .Wed, .Thur, .Fri:
print("주중")
case .Sat, .Sun:
print("주말")
}
}
}
Week.Sun.printWeek()
// 열거형의 rawValue
enum Color: Int { //Hashable 프로토콜을 준수하는 기본자료형
case red = 0
case green // rawValue 1
case blue // rawValue 2
}
print(Color.red)
print(Color.blue)
print(Color.red.rawValue)
print(Color.blue.rawValue)
//String형 값을 갖는 열거형의 rawValue
enum Week: String {
case Monday = "월"
case Tuesday = "화"
case Wednesday = "수"
case Thursday = "목"
case Friday = "금"
case Saturday //값이 지정되지 않으면 case의 이름이 할당된다.
case Sunday
}
print(Week.Monday) //Monday
print(Week.Monday.rawValue) //"월"
print(Week.Sunday) //Sunday
print(Week.Sunday.rawValue) //Sunday
//연관값을 가지는 enum
enum Date {
case intDate(Int,Int,Int)
case stringDate(String)
}
var todayDate = Date.intDate(2020,4,30)
todayDate = Date.stringDate("2020년 5월 20일")
switch todayDate {
case .intDate(let year, let month, let day):
print("(year)년 (month)월 (day)일")
case .stringDate(let date):
print(date)
}
//옵셔널은 연관값을 갖는 enum
//실제로 스위프트에서 옵셔널이 구현된 것을 보면 다음과 같다
public enum Optional {
case none
case some(Wrapped)
}
var x: Int? = 20 // .some(20)
var y: Int? = Optional.some(10) //Optional 생략 가능
var z: Int? = Optional.none //Optional 생략 가능
var x1: Optional = 30 //축약 안된 옵셔널
print(x, y, z, x1) //Optional(20) Optional(10) nil Optional(30)
let age: Int? =. 0
switch age {
case.none:
print("나이 정보가 없습니다.")
case.some(let a) where a < 20: //age를 a에 넣어 옵셔널이 풀린다
print("미성년자 입니다.")
case.some(let a) where a < 71:
print("성인입니다.")
default:
print("경로우대입니다.")
}
출처 : https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA