도슐랭스타

iOS - 클래스 본문

iOS

iOS - 클래스

도도.__. 2024. 10. 16. 16:47

각 프로그래밍 언어에서 클래스를 생성하고 객체를 만드는 방법

1. Swift

class Dog {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func bark() {
        print("\(name) says Woof!")
    }
}

let myDog = Dog(name: "Buddy")
myDog.bark()  // Output: Buddy says Woof!

2. Java

class Dog {
    String name;

    Dog(String name) {
        this.name = name;
    }

    void bark() {
        System.out.println(name + " says Woof!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy");
        myDog.bark();  // Output: Buddy says Woof!
    }
}

3. C#

class Dog {
    public string Name { get; set; }

    public Dog(string name) {
        Name = name;
    }

    public void Bark() {
        Console.WriteLine($"{Name} says Woof!");
    }
}

class Program {
    static void Main(string[] args) {
        Dog myDog = new Dog("Buddy");
        myDog.Bark();  // Output: Buddy says Woof!
    }
}

4. JavaScript

class Dog {
    constructor(name) {
        this.name = name;
    }

    bark() {
        console.log(`${this.name} says Woof!`);
    }
}

const myDog = new Dog("Buddy");
myDog.bark();  // Output: Buddy says Woof!

5. Python

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print(f"{self.name} says Woof!")

my_dog = Dog("Buddy")
my_dog.bark()  # Output: Buddy says Woof!

 

stored property

var x : Int
class Man {
    var age : Int
}

var x : Int
class Man {
    var age : Int = 0
}

stored property는 반드시 초기값이 있어야한다.

var x : Int
class Man {
    var age : Int?
    var weight : Double?
}

옵셔널 변수로 초기값을 설정해도 된다.(옵셔널은 초기값이 없으면 자동으로 nil이 할당됨.)

 

인스턴스 초기화

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    func display() {
        print(age, weight)
    }
}
var dodo : Man = Man()
dodo.age = 10

위의 코드는

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    init(){}
    func display() {
        print(age, weight)
    }
}
var dodo : Man = Man.init()
dodo.age = 10

이 코드를 생략한 것임.

 

인스턴스 만들고 메서드와 프로퍼티 접근

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man = Man()
dodo.age = 10
dodo.weight = 20.5
print(dodo.age, dodo.weight)
dodo.display()

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
    class func cM(){
        print("cM은 클래스 메서드입니다.")
    }
    static func scM(){
        print("scM은 클래스 메서드(static)")
    }
}
var dodo : Man = Man()
dodo.age = 10
dodo.weight = 20.5
print(dodo.age, dodo.weight)
dodo.display()
dodo.cM()
dodo.scM()

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
    class func cM(){
        print("cM은 클래스 메서드입니다.")
    }
    static func scM(){
        print("scM은 클래스 메서드(static)")
    }
}
var dodo : Man = Man()
dodo.age = 10
dodo.weight = 20.5
print(dodo.age, dodo.weight)
dodo.display()
Man.cM()
Man.scM()

클래스로 만들어진 cm()은 자식클래스에서 오버라이드가 가능하다.

designated initializer

  • 모든 프로퍼티(age, weight)를 다 초기화시키는 생성자
class Man {
    var age : Int = 0
    var weight : Double = 0.0
    init(yourAge: Int, yourWeight : Double){
      age = yourAge
      weight = yourWeight
    } //designated initializer
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man = Man.init(yourAge: 5, yourWeight: 10.3) //그냥 Man(yourAge...)로 써도 됨.
dodo.display()
dodo.age = 10
dodo.weight = 20.5
dodo.display()

위의 init을 조금 변경하면

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    init(age: Int, weight : Double){
        age = age
        weight = weight
    } //designated initializer
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man = Man.init(age: 5, weight: 10.3)
dodo.display()
dodo.age = 10
dodo.weight = 20.5
dodo.display()

에러가 남. swift는 this 대신 self를 사용해서

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man = Man.init(age: 5, weight: 10.3)
dodo.display()
dodo.age = 10
dodo.weight = 20.5
dodo.display()

이렇게 수정해야함.

키워드 사용하는 언어
self Swift, Python
this Java, C#, JavaScript

오버로딩

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer
    init(age: Int){
        self.age = age
    }
    
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man = Man.init(age: 5, weight: 10.3)
var kim : Man = Man(age: 33)
dodo.display()
dodo.age = 10
dodo.weight = 20.5
dodo.display()

이런 식으로 init()생성자 함수를 중첩하는 것을 오버로딩이라고 한다.(단, 매개변수의 개수나 자료형이 달라야함.)

매우 많은 initializing이 만들어져 있음.

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer
    init(age: Int){
        self.age = age
    }
    
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
class Student : Man {
    
}
var lee : Student = Student(age: 25, weight: 77.7)
lee.display()
var dodo : Man = Man.init(age: 5, weight: 10.3)
dodo.display()

자식클래스인 Student는 부모클래스(Man)의 프로퍼티들을 상속 받을 수 있음.

 

오버라이딩(Overriding)

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer
    init(age: Int){
        self.age = age
    }
    
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
class Student : Man {
    var name : String
    func display() {
        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: 25, weight: 77.7, name: "soft")
lee.display()
var dodo : Man = Man.init(age: 5, weight: 10.3)
dodo.display()

에러가 남.

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer
    init(age: Int){
        self.age = age
    }
    
    func display() {
        print("나이: \(age), 몸무게:\(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: 25, weight: 77.7, name: "soft")
lee.display()
var dodo : Man = Man.init(age: 5, weight: 10.3)
dodo.display()

"override"를 추가하면 "내 메서드 먼저 써줘!" 이런 느낌. 출력이 잘 됨.
매개변수의 변화가 없기 때문에 오버로드는 할 수 없음.

failable initializer

failable initializer 중요함!

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man = Man(age: -5, weight: -10.3)
dodo.display()

코드에는 문제가 없지만 나이와 몸무게가 음수일 수는 없음.

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init?(age: Int, weight : Double){
        if age <= 0 || weight <= 0.0 { //나이와 몸무게가 0 이하면 nil을 리턴함.
            return nil
        }else{
            self.age = age
            self.weight = weight
        }
    } //failable initializers
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}

이런식으로 만들 수 있음.

하지만 이렇게 출력하면 에러가 남. 

이렇게 바꿔도 에러가 남.

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init?(age: Int, weight : Double){
        if age <= 0 || weight <= 0.0 {
            return nil
        }else{
            self.age = age
            self.weight = weight
        }
    } //failable initializers
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man? = Man(age: 5, weight: 10.3)
dodo!.display()

이렇게까지 해줘야 됨.

단, 값이 음수라서 nil이 리턴된다면

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init?(age: Int, weight : Double){
        if age <= 0 || weight <= 0.0 {
            return nil
        }else{
            self.age = age
            self.weight = weight
        }
    } //failable initializers
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
var dodo : Man? = Man(age: -5, weight: -10.3) //nil이 반환됨.
dodo!.display()

nil이 아닐때만 옵셔널을 풀어야 하기 때문에 문제가 발생함.

방금까지의 방법은 4번의 방법임.(제일 안 좋음. 1,2번 방법이 좋음.)

var dodo : Man? = Man(age: 5, weight: 10.3)
if let dodo = dodo {
    dodo.display()
}

1번째 방법임.(좋은 방법)

var dodo : Man? = Man(age: -5, weight: -10.3)
if let dodo = dodo {
    dodo.display()
}

만약 nil이 반환되면 아무것도 실행하지 않음.

if let dodo = Man(age: 5, weight: 10.3)
{
    dodo.display()
}

2번째 방법.(좋은 방법) 풀면서 만듦.

class Man {
    var age : Int = 0
    var weight : Double = 0.0
    
    init?(age: Int, weight : Double){
        if age <= 0 || weight <= 0.0 {
            return nil
        }else{
            self.age = age
            self.weight = weight
        }
    } //failable initializers
    func display() {
        print("나이: \(age), 몸무게:\(weight)")
    }
}
if let dodo = Man(age: 5, weight: 10.3)
{
    dodo.display()
}

가장 간결한 방법.

코드 예시

import Foundation

// 기본 클래스
class Person {
    var name: String
    var age: Int

    // failable initializer
    init?(name: String, age: Int) {
        if name.isEmpty || age < 0 {
            return nil
        }
        self.name = name
        self.age = age
    }

    func display() {
        print("이름: \(name), 나이: \(age)")
    }
}

// 서브 클래스
class Student: Person {
    var studentID: String

    // failable initializer
    init?(name: String, age: Int, studentID: String) {
        // 부모 클래스의 이니셜라이저 호출
        guard let validPerson = super.init(name: name, age: age) else {
            return nil
        }
        self.studentID = studentID
    }

    // 메서드 오버라이딩
    override func display() {
        super.display() // 부모 클래스의 display 메서드 호출
        print("학생 ID: \(studentID)")
    }

    // 메서드 오버로딩
    func study() {
        print("\(name)가 공부합니다.")
    }

    func study(subject: String) {
        print("\(name)\(subject) 과목을 공부합니다.")
    }
}

// 객체 생성 및 사용
if let john = Person(name: "John", age: 25) {
    john.display()  // Output: 이름: John, 나이: 25
}

if let alice = Student(name: "Alice", age: 20, studentID: "S1234") {
    alice.display() // Output: 이름: Alice, 나이: 20
                     //         학생 ID: S1234
    alice.study()   // Output: Alice가 공부합니다.
    alice.study(subject: "수학") // Output: Alice가 수학 과목을 공부합니다.
}
반응형

'iOS' 카테고리의 다른 글

10주차  (1) 2024.11.06
iOS- 9주  (0) 2024.10.30
iOS - first class object, first class citizen(1급 객체, 1급 시민)  (0) 2024.10.14
iOS - 함수(2)  (0) 2024.10.14
iOS - 함수(1)  (0) 2024.10.04
Comments