클래스 자체가 캡슐화 but 수준이 낮음

구조체는 상속이 불가능 <- 이것만 알아둘 것. 시험범위 아님 다 적지말것

java 같은 언어에서는 class 안의 변수를 필드, 함수를 메소드라 함.
Swift에서는 프로퍼티와 메소드라고 함. 프로퍼티는 웬만하면 stored property.

Swift의 stored property 는 반드시 초기값이 있어야함.

init 메서드로 초기화하는 것이 일반적. 메소드이지만 func를 사용하지 않음. -> '생성자'
class Man{ //캡슐화 수준이 높지 않음
var age : Int = 1
var weight : Double = 3.5
//init(){} 생성하지 않아도 자동으로 생성
//눈에 보이지 않지만 자동으로 만들어지는 default initializer
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
class func cM(){ //타입 메소드: 클래스 자체가 이용하는 메소드, 객체 생성없이 사용가능
print("cM은 클래스 메서드입니다.")
}
static func scM(){
print("scM은 클래스 메서드(static)")
}
}
var kim = Man() // ()는 init()호출하는 것, var kim : Man = Man.init()
kim.display() //인스턴스 메서드는 인스턴스가 호출
print(kim.age)
//Man.display() //Man클래스에서 만들어진 객체가 메서드를 사용가능,Man 자체는 불가 -> class method를 만들면 됨
Man.cM() //클래스 메서드는 클래스가 호출
Man.scM() //클래스 메서드는 클래스가 호출

자식 클래스에서 override 하려면 class 키워드로 클래스 메서드를 생성해야함. (= factory method)

class Man{ //캡슐화 수준이 높지 않음
var age : Int
var weight : Double
// init(){
// age = 1
// weight = 3.5
// }
init(yourAge: Int, yourWeight : Double){
age = yourAge
weight = yourWeight
} //designated initializer, 초기화가 반드시 필요한 생성자
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
}
var kim = Man(yourAge:23,yourWeight:71) // ()는 init()호출하는 것, var kim : Man = Man.init()
kim.display() //인스턴스 메서드는 인스턴스가 호출
print(kim.age)
self: 클래스 내의 변수와 메서드 가리킴
class Man{ //캡슐화 수준이 높지 않음
var age : Int
var weight : Double
// init(){
// age = 1
// weight = 3.5
// }
init(age: Int, weight : Double){
self.age = age //self가 없으면 오류발생, 매개변수는 변경이 불가능한 값. 클래스 내 프로퍼티를 가리킨다는 것을 명시해야함.
self.weight = weight
} //designated initializer, 초기화가 반드시 필요한 생성자
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
}
var kim = Man(age:23,weight:71) // ()는 init()호출하는 것, var kim : Man = Man.init()
kim.display() //인스턴스 메서드는 인스턴스가 호출
print(kim.age)

생성자 중첩 (다형성)
-method overloading: 같은 이름의 함수가 여러개 (매개변수의 개수와 자료형이 다름)
class Man{ //캡슐화 수준이 높지 않음
var age : Int
var weight : Double
init(){ //"2" 메서드 오버로딩: 생성자 중첩
age = 1
weight = 3.5
}
init(age: Int, weight : Double){ //"1"
self.age = age //self가 없으면 오류발생, 매개변수는 변경이 불가능한 값. 클래스 내 프로퍼티를 가리킨다는 것을 명시해야함.
self.weight = weight
} //designated initializer, 초기화가 반드시 필요한 생성자
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
}
var yoo = Man(age:23,weight:71)
yoo.display() //1
var kim = Man()
kim.display() //2
failable initializer

class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){
self.age = age
self.weight = weight
}
}
var kim : Man = Man(age:-3, weight:20.5)
//정상적인 객체가 아닌 경우에는 안만들어지도록, nil이 나오도록
kim.display()
-> 옵셔널형으로 변경
class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init?(age: Int, weight : Double){
if age <= 0 || weight <= 0.0 {
return nil
}else{
self.age = age
self.weight = weight
}
}
}
var kim = Man(age:-3, weight:20.5)! //이경우도 nil인데 강제 언래핑, 크래쉬 발생.
//정상적인 객체가 아닌 경우에는 안만들어지도록, nil이 나오도록.
kim.display() //kim!.display()-> age가 nil 인데 kim을 언래핑, 크래쉬 발생
//두 경우 다 0 밑의 수가 나오지 않으면 오류발생 없음 but, nil인 순간 크래쉬 발생
print(type(of: kim))
class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init?(age: Int, weight : Double){
if age <= 0 || weight <= 0.0 {
return nil
}else{
self.age = age
self.weight = weight
}
}
}
//1-1.옵셔널 형으로 선언
var kim : Man? = Man(age:-3, weight:20.5)
//1-2.옵셔널 바인딩
if let kim{ //optional binding
kim.display()
}else{
print("nil")
}
//2.인스턴스 생성과 동시에 옵셔널 바인딩
if let yoo = Man(age:23,weight:-0.45){
yoo.display()
}
guard let kim1 = Man(age: -1, weight: 3) else{
//guard let은 특정 블럭 안에서 사용해야함 ex) 함수. 블럭 바깥이라 guard let이 작동안하는것
print("nil")
return
}
kim1.display()
객체지향언어의 특징 - 상속성
프로토콜은 자바의 인터페이스라고 생각.

부모가 가장 먼저 온다. 부모는 없을수도 있고 있다면 반드시 하나만 상속가능.
여러개가 오면 다 프로토콜을 채택한 것.

상속을 받으면 코드를 따로 작성하지 않아도 부모의 것을 다 사용가능
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{
}
let kim : Man = Man(age:10, weight:20.5) //객체 생성시 let을 쓰던 var을 쓰던 상관없음
kim.display()
var lee = Student(age: 5, weight: 10)
lee.display()
super : 부모 메서드 호출 시 사용
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 {
var name : String
func displayS() {
print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double, name : String){
self.name = name //자식의 프로퍼티 먼저 초기화
super.init(age:age, weight:weight) //과제: 이 줄을 안쓰면?
//부모 생성자의 argument label과 자식의 매개변수를 부모 생성자로 초기화
}//error:'super.init' isn't called on all paths before returning from initializer
}
var lee : Student = Student(age:20,weight:65.2,name:"홍길동")
lee.displayS()
lee.display()
override : 자식 클래스에서 메서드 재정의
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 {
var name : String
override func display() { //override 키워드 작성
print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double, name : String){
self.name = name //자식의 프로퍼티 먼저 초기화
super.init(age:age, weight:weight) //과제: 이 줄을 안쓰면? 인스턴스의 모든값이 초기값이
있어야하기 때문에 반드시 적어야함
}//error:'super.init' isn't called on all paths before returning from initializer
}
var lee : Student = Student(age:20,weight:65.2,name:"홍길동")
lee.display()
오버라이드할 때는 부모 메서드와 이름, 매개변수, 반환타입이 완전히 일치해야 함
부모와 자식에 display()라는 메서드가 있어서 Student클래스는 display() 메서드가 두 개임
Student클래스의 인스턴스 lee가 display()를 호출할 때, 자식클래스가 새로 만든 display() 메서드가 우선적으로 호출되려면 func 앞에 override키워드 씀
다음주는 중간고사. 열공!
'iOS' 카테고리의 다른 글
| iOS_week10 (0) | 2025.11.03 |
|---|---|
| iOS_week9 (0) | 2025.10.27 |
| iOS_week5 (0) | 2025.09.29 |
| iOS_week4 (0) | 2025.09.22 |
| iOS_week_3 (0) | 2025.09.15 |