클래스
프로퍼티는 초기값을 주거나, init으로 초기화하거나, 옵셔널 변수(상수)로 선언(자동 nil 초기화)해야한다.
-> stored property(저장 프로퍼티) (자바,C#에서 필드라고 하는 것)
-> 즉 스토어드 프로퍼티는 초기화가 되어있어야 한다.
옵셔널 변수 선언 -> 자료형 다음에 ! 혹은 ? 붙이기 https://yejprogramming.tistory.com/4
class Dog{
var age : Int = 5
var weight : Double = 3.5
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
}
var nala : Dog = Dog()
// Dog()라는 함수를 호출하는 것은 눈에 보이지 않는
// default initializer(= init함수 =생성자!!!)을 호출하는 것
nala.display()
print(nala.weight)
클래스 메서드 : 인스턴스가 아닌 클래스가 호출하는 메서드
앞에 class가 붙지만 클래스가 아니고 메서드이다.
class가 아닌 static이 붙는 것도 있음 (둘의 차이는 나중에 공부할 오버라이드와 관계가 있음)
class Dog{
var age : Int = 5
var weight : Double = 3.5
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
class func classM(){
print("Class Method")
}
static func staticM(){
print("Static Method")
}
}
var nala : Dog = Dog()
// Dog()라는 함수를 호출하는 것은 눈에 보이지 않는
// default initializer(생성자!!!)을 호출하는 것
nala.display() //인스턴스 메소드
Dog.classM() //클래스 메소드
Dog.staticM() //클래스 메소드(static)
init() : 인스턴스 초기화
함수이지만 func로 시작하지 않고 그냥 init() { }을 쓰면 된다.
- class로 인스턴스 선언할 때 ()에 뭐가 있으면 init 함수 호출한다고 생각!!
인스턴스가 생성되며 자동으로 호출된다.
따로 지정하지 않으면 default initializer
따로 지정한건 designated initializer - stored property의 개수만큼 다 초기화 - 직접 지정하면 default initializer은 사라짐
소멸자 : deinit{} - 인스턴스 사라질 때 자동 호출됨
class Dog{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(myAge: Int, myWeight : Double){
age = myAge
weight = myWeight
}
}
//var nala : Dog = Dog() //오류
var nala : Dog = Dog(myAge:5, myWeight:10.3)
//init()을 직접 만들었기 때문에 default 생성자가 없어져서 초기값을 따로 줘야한다.
nala.display()
self : 현재 클래스 내 메서드나 프로퍼티를 가르킬 때 메서드나 프로퍼티 앞에 self.을 붙인다.
(-> C++의 this 처럼)
생략이 가능한 경우도 있고 불가능한 경우도 있다. 불가능한 경우 : 매개변수와 프로퍼티의 이름이 같을 때는 이름 구분하기 위해 프로퍼티에 self.을 써줘야 한다.
class Dog{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){
self.age = age
// 프로퍼티와 매개변수의 이름이 둘 다 age로 똑같아서 구분 불가. 프로퍼티에 self. 써야함
self.weight = weight
// 프로퍼티와 매개변수의 이름이 둘 다 weight로 똑같아서 구분 불가. 프로퍼티에 self. 써야함
}
}
//var nala : Dog = Dog() //오류
var nala : Dog = Dog(age:5, weight:10.3)
//inigt()을 직접 만들었기 때문에 default 생성자가 없어져서 초기값을 따로 줘야한다.
nala.display()
stored property & computed property
stored property는 일반적인 프로퍼티 - 이 프로퍼티들을 가지고 계산해서 만든 프로퍼티가 computed property
계산 프로퍼티 : getter -값을 리턴, setter -값을 대입
class Dog{
var intAge : Int //Internation age, stored property
var weight : Double
var krAge : Int { //korean age
get{
//setter가 없을 때는 get{} 생략 가능하다.
return intAge+1
}
}
func display(){
print("나이=\(intAge), 몸무게=\(weight)")
}
init(intAge: Int, weight : Double){
self.intAge = intAge
// 프로퍼티와 매개변수의 이름이 둘 다 age로 똑같아서 구분 불가. 프로퍼티에 self. 써야함
self.weight = weight
// 프로퍼티와 매개변수의 이름이 둘 다 weight로 똑같아서 구분 불가. 프로퍼티에 self. 써야함
}
}
//var nala : Dog = Dog() //오류
var nala : Dog = Dog(intAge:5, weight:10.3)
nala.display() // 결과 : 나이=5, 몸무게=10.3
var nalaKrAge = nala.krAge
print("한국나이는 \(nalaKrAge)세입니다.") //한국나이는 6세입니다.
var krAge : Int { //korean age
get{
return intAge+1
}
}
//setter가 없을 때는 밑에 코드처럼get{} 생략 가능하다.
var krAge : Int{
return intAge+1
}
-> get이 보이지 않는 computed property
(setter가 이쓸 때는 get{} 생략 불가
class Dog{
var intAge : Int //Internation age, stored property
var weight : Double
var krAge : Int { //korean age
get{
return intAge+1
}
set(momAge){ //set에는 매개변수가 있음
intAge = momAge-5 //어머니의 나이 보다 5세 적음
}
}
func display(){
print("나이=\(intAge), 몸무게=\(weight)")
}
init(intAge: Int, weight : Double){
self.intAge = intAge
self.weight = weight
}
}
var nala : Dog = Dog(intAge:5, weight:10.3)
nala.display() // 결과:나이=5, 몸무게=10.3
var nalaKrAge = nala.krAge //getter 호출
print("한국나이는 \(nalaKrAge)세입니다.") //결과:한국나이는 6세입니다.
nala.krAge = 7 //setter 호출
print("setter 나이는 \(nala.intAge)세입니다.") //결과:setter 나이는 2세입니다.
위 코드의 setter에서 momAge 자리에 보통 "newValue"라는 값이 들어간다.
또한 newValue 값을 사용하는 경우 set 옆에 (newValue)가 생략 가능하다.
class Dog{
var intAge : Int //Internation age, stored property
var weight : Double
var krAge : Int { //korean age
get{ return intAge+1 }
set{ intAge = newValue-5 } //매개변수 자리에 newValue 생략 가능
}
func display(){
print("나이=\(intAge), 몸무게=\(weight)")
}
init(intAge: Int, weight : Double){
self.intAge = intAge
self.weight = weight
}
}
var nala : Dog = Dog(intAge:5, weight:10.3)
var nalaKrAge = nala.krAge //getter 호출
print("한국나이는 \(nalaKrAge)세입니다.") //결과:한국나이는 6세입니다.
nala.krAge = 7 //setter 호출
print("setter 나이는 \(nala.intAge)세입니다.") //결과:setter 나이는 2세입니다.
-> 더 정렬된 코드
computed property를 잘 써서 코드를 간소하게 만들 수 있지만, 당장은 잘 사용하지 않을 것이다.
(하지만 이해를 위해 알아둬야 함)
method overloading
- 같은 이름의 함수를 한 개 이상 정의(매개변수의 개수와 자료형을 다르게 한다)
- 가장 많이 쓰이는 경우가 생성자(여러 개의 init() 정의)
- 장점 :사용자의 다양한 요구에 맞춰 인스턴스 생성
class Dog{
var age : Int = 1
var weight : Double!
var height : Double!
func display(){
print("나이=\(age), 몸무게=\(weight), 키=\(height)")
}
init(age: Int, weight: Double, height: Double){
self.age = age
self.weight = weight
self.height = height
}
init(age: Int, height: Double){
self.age = age
self.height = height
}
}
var nala : Dog = Dog(age:5, weight:10.3, height:40)
var daisy : Dog = Dog(age:3, height:60.2)
nala.display() //결과 : 나이=5, 몸무게=Optional(10.3), 키=Optional(40.0)
daisy.display() //결과 : 나이=3, 몸무게=nil, 키=Optional(60.2)
failable initializer(실패 가능한 생성자)
let myImage: UIImage = UIImage(named: "apple.jpg")!
- 마지막에 왜 느낌표가 붙어있을까? "값이 없을 수도 있다." (오타나 파일이 없는 상황 등을 대비해서)
- 인스턴스가 옵셔널 형으로 나오기 때문에, 이를 사용하기 위해서는 먼저 옵셔널 언래핑을 해야한다.
- init 다음에 물음표(?) or 느낌표(!), 오류 상황에 nil 리턴 조건문!!(이 말은 즉, 옵셔널형)
class Dog{
var age : Int
var height : Double
func display(){
print("나이=\(age), 키=\(height)")
}
init?(age: Int, height: Double){
if age <= 0 {
return nil
}
else {
self.age = age
}
self.height = height
}
}
if let nala = Dog(age:5, height:40) {
nala.display() //결과: 나이=5, 키=40.0
}
if let daisy1 = Dog(age:-1, height:53.2) {
daisy1.display() //결과X
}
참고 : iOS프로그래밍기초(21년-2학기) 한성현 교수님 강의 및 강의 자료 변형, 요약
'iOS > Swift이론' 카테고리의 다른 글
Swift)iOS프로그래밍 : extension, access modifier, enum (0) | 2021.10.15 |
---|---|
swift)iOS 프로그래밍 : 클래스 상속(override)과 오버로딩 (0) | 2021.10.08 |
Swift) iOS 프로그래밍 함수, 1급객체, 클로저, 클래스 (0) | 2021.10.05 |
iOS guard, switch case, 함수 (0) | 2021.09.28 |
iOS Swift 옵셔널 타입과 강제 언래핑, 연산자, 제어문 (0) | 2021.09.21 |