티스토리 뷰


[iOS프로그래밍기초] 6주차

 

 

설계도인 클래스로부터 만들어진 실체를 객체라 하고 실제로 사용 중인 객체를 인스턴스라 한다. **

 

 

property는 저장 프로퍼티(stored property)과 계산 프로퍼티(computed property)

 

초기값이 있는 경우

class Man { //upperCamelCase
    var age : Int = 0 //stored property
    var weight : Double = 0.0
}

 

저장 프로퍼티 (stored property) 를 선언할 때에는 반드시 초기값이 필요하다

 

init을 이용해서 초기화하는 경우

class Person {
    var name: String
    
    init(name: String) {  // 초기화 메서드
        self.name = name
    }
}

 

옵셔널 변수(상수)로 선언하는 경우

class Person {
    var name: String?  // 옵셔널 저장 프로퍼티, 기본값은 nil
    var weight: Double! // 0.0
}

 

메서드 정의

 

 

 

 

각 언어별로 클래스를 정의하고 객체를 생성하는 예제

 

JAVA

// Dog.java
class Dog {
    String name;
    int age;

    // 생성자
    Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

// Main.java
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy", 3); // 객체 생성
        myDog.bark(); // 메서드 호출
    }
}

 

Python

// Dog.js
class Dog {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

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

// main.js
const myDog = new Dog("Buddy", 3); // 객체 생성
myDog.bark(); // 메서드 호출

 

Javascript

// Dog.js
class Dog {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

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

// main.js
const myDog = new Dog("Buddy", 3); // 객체 생성
myDog.bark(); // 메서드 호출

 

  • 자바에서는 new 키워드를 사용하여 객체를 생성하고, 생성자를 통해 초기화합니다.
  • 파이썬에서는 __init__ 메서드를 사용하여 객체를 초기화하고, 클래스 이름을 호출하여 객체를 생성합니다.
  • 자바스크립트에서는 new 키워드를 사용하여 객체를 생성하고, 생성자 메서드를 통해 초기화합니다.

 

class Man { //upperCamelCase
    var age : Int = 1 //stored property
    var weight : Double = 3.5
    func disply() {
        print("나이=\(age), 몸무게=\(weight)")
    }
    class func cM(){
    print("cM은 클래스 메서드입니다.")
    }
    static func scM(){
    print("scM은 클래스 메서드(static)")
    }
}

var kim : Man = Man()
print(kim.age) //1
Man.scM() //scM은 클래스 메서드(static)
kim.disply() //나이=1, 몸무게=3.5
//주의!!! Man.disply() 는 안 됩니다.

 


 

class Man{
  var age : Int = 1
  var weight : Double = 3.5
  func display(){
   print("나이=\(age), 몸무게=\(weight)")
  }
  init(yourAge: Int, yourWeight : Double){
	age = yourAge
	weight = yourWeight
  } //designated initializer
}
//var kim : Man = Man()  //오류
//init()을 하나라도 직접 만들면 default initializer는 사라짐
var kim : Man = Man(yourAge:10, yourWeight:20.5) 
kim.display()

init()을 하나라도 직접 만들면 기본적으로 만들어지는 눈에 안보이는 default initializer는 사라짐

인스턴스가 만들어지면서 자동 호출되기 때문에 initializer 에 매개변수가 있으면 argument lable 을 통하여 값을 필수로 전달해야 한다.

 

시험에 나오는 중요한 개념! 꼭 알아두길 바랍니다.

designated initializer

모든 프로퍼티(age, weight)를 다 초기화시키는 생성자

 

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
  }
}
var kim : Man = Man(age:10, weight:20.5)
kim.display()

 

self 를 사용하여 지역변수 age 가 아닌 프로퍼티 age 를 사용할 수 있다.

 

언어별 this & self 사용 예제

 

C++

#include <iostream>
using namespace std;

class Dog {
public:
    string name;
    int age;

    Dog(string name, int age) {
        this->name = name; // 'this' 사용
        this->age = age;
    }

    void bark() {
        cout << name << " says: Woof!" << endl;
    }
};

int main() {
    Dog myDog("Buddy", 3); // 객체 생성
    myDog.bark(); // 메서드 호출
    return 0;
}

 

Java 

class Dog {
    String name;
    int age;

    Dog(String name, int age) {
        this.name = name; // 'this' 사용
        this.age = age;
    }

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

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy", 3); // 객체 생성
        myDog.bark(); // 메서드 호출
    }
}

 

C#

using System;

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

    public Dog(string name, int age) {
        this.Name = name; // 'this' 사용
        this.Age = age;
    }

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

class Program {
    static void Main() {
        Dog myDog = new Dog("Buddy", 3); // 객체 생성
        myDog.Bark(); // 메서드 호출
    }
}

 

Javascript

class Dog {
    constructor(name, age) {
        this.name = name; // 'this' 사용
        this.age = age;
    }

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

const myDog = new Dog("Buddy", 3); // 객체 생성
myDog.bark(); // 메서드 호출

 

swift

class Dog {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name // 'self' 사용
        self.age = age
    }

    func bark() {
        print("\(name) says: Woof!")
    }
}

let myDog = Dog(name: "Buddy", age: 3) // 객체 생성
myDog.bark() // 메서드 호출

 

  • C++, Java, C#, JavaScript에서는 this 키워드를 사용하여 객체의 속성에 접근합니다.
  • Python에서는 self를 사용하여 인스턴스 속성에 접근합니다.
  • Swift에서도 self를 사용하여 인스턴스 속성에 접근합니다.

 

클래스 작성하는 게 시험문제로 가장 배점 크게 나올 예정!!

 

method overloading 생성자 중첩

class Man{
  var age : Int = 1
  var weight : Double = 3.5
  func display(){
    print("나이=\(age), 몸무게=\(weight)")
  }
  init(age: Int, weight : Double){  //1
    self.age = age
    self.weight = weight
  }
  init(age: Int){  //2
       self.age = age
  }
}
var kim : Man = Man(age:10, weight:20.5)  //1
var kim1 : Man = Man(age:10) //2
//var kim2 : Man = Man()
//init가 없다면 인스턴스 만드는 방법
kim.display()
kim1.display()

 

 

https://developer.apple.com/documentation/uikit/uiimage

 

앱에서 이미지 데이터를 관리하는 클래스인 UIImage는 15개의 init()가 overloading되어 있음

 


 

클래스 상속

 

 

언어별 상속 예제

 

C++

#include <iostream>
using namespace std;

class Animal {
public:
    void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        cout << "Dog barks" << endl;
    }
};

int main() {
    Dog dog;
    dog.speak(); // Animal method
    dog.bark();  // Dog method
    return 0;
}

 

 JAVA

class Animal {
    void speak() {
        System.out.println("Animal speaks");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.speak(); // Animal method
        dog.bark();  // Dog method
    }
}

 

 C#

using System;

class Animal {
    public void Speak() {
        Console.WriteLine("Animal speaks");
    }
}

class Dog : Animal {
    public void Bark() {
        Console.WriteLine("Dog barks");
    }
}

class Program {
    static void Main() {
        Dog dog = new Dog();
        dog.Speak(); // Animal method
        dog.Bark();  // Dog method
    }
}

 

Javascript

class Animal {
    speak() {
        console.log("Animal speaks");
    }
}

class Dog extends Animal {
    bark() {
        console.log("Dog barks");
    }
}

const dog = new Dog();
dog.speak(); // Animal method
dog.bark();  // Dog method

 

swift

class Animal {
    func speak() {
        print("Animal speaks")
    }
}

class Dog: Animal {
    func bark() {
        print("Dog barks")
    }
}

let dog = Dog()
dog.speak() // Animal method
dog.bark()  // Dog method

 

 

 스위프트에서는 부모 클래스는 하나만 가능하고 프로토콜은 여러 개가 될 수 있다

콜론 다음으로 부모 클래스가 오고 부모 클래스가 없다면 프로토콜이 될 수 있다

 

class Man{
  var age : Int 
  var weight : Double 
  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) //과제: 이 줄을 안쓰면?  
  } //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()

 

 

 

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() {
    print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
  }
  init(age: Int, weight : Double, name : String){
    super.init(age:age, weight:weight)
    self.name = name
  }
}
var lee : Student = Student(age:20,weight:65.2,name:"홍길동")  
lee.display()
// Man이라는 클래스를 정의합니다. 이 클래스는 사람의 기본 정보를 담고 있습니다.
class Man {
    // 나이를 저장할 변수 age를 만듭니다. 기본값은 1입니다.
    var age: Int = 1
    // 몸무게를 저장할 변수 weight를 만듭니다. 기본값은 3.5입니다.
    var weight: Double = 3.5
    
    // display라는 함수를 만듭니다. 이 함수는 나이와 몸무게를 출력합니다.
    func display() {
        print("나이=\(age), 몸무게=\(weight)")
    }
    
    // 초기화 함수입니다. Man 클래스를 만들 때 나이와 몸무게를 설정할 수 있습니다.
    init(age: Int, weight: Double) {
        self.age = age // 전달받은 나이를 age 변수에 저장합니다.
        self.weight = weight // 전달받은 몸무게를 weight 변수에 저장합니다.
    }
}

// Student라는 클래스를 정의합니다. Man 클래스를 상속받아 학생의 정보를 추가합니다.
class Student: Man {
    // 학생의 이름을 저장할 변수 name을 만듭니다. 기본값은 "김소프"입니다.
    var name: String = "김소프"
    
    // display라는 함수를 오버라이드(재정의)합니다. 학생의 이름, 나이, 몸무게를 출력합니다.
    override func display() {
        print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
    }
    
    // 초기화 함수입니다. Student 클래스를 만들 때 나이, 몸무게, 이름을 설정할 수 있습니다.
    init(age: Int, weight: Double, name: String) {
        super.init(age: age, weight: weight) // 부모 클래스인 Man의 초기화 함수를 호출합니다.
        self.name = name // 전달받은 이름을 name 변수에 저장합니다.
    }
}

// lee라는 변수를 만들고 Student 클래스를 사용하여 새로운 학생을 만듭니다.
// 나이는 20, 몸무게는 65.2, 이름은 "홍길동"입니다.
var lee: Student = Student(age: 20, weight: 65.2, name: "홍길동")  

// lee의 display 함수를 호출하여 학생의 정보를 출력합니다.
lee.display()

 


failable initializers(실패 가능한 생성자)

 

사용 이유

  1. 유효성 검사: 초기화할 값이 특정 조건을 만족해야 할 때, 이를 검사하여 유효하지 않으면 nil을 반환할 수 있습니다.
  2. 안전성: 잘못된 데이터로 인한 오류를 방지하고, 안전하게 객체를 생성할 수 있습니다.
  3. 명확한 의도: 객체가 유효한 상태에서만 사용되도록 보장할 수 있습니다.
class Person {
    var name: String
    var age: Int
    
    // failable initializer
    init?(name: String, age: Int) {
        // 나이가 0보다 작으면 nil을 반환하여 초기화 실패
        if age < 0 {
            return nil
        }
        self.name = name
        self.age = age
    }
}

// 유효한 나이로 Person 객체를 생성
if let person1 = Person(name: "홍길동", age: 20) {
    print("이름: \(person1.name), 나이: \(person1.age)") // 출력: 이름: 홍길동, 나이: 20
} else {
    print("초기화 실패")
}

// 유효하지 않은 나이로 Person 객체를 생성
if let person2 = Person(name: "김소프", age: -5) {
    print("이름: \(person2.name), 나이: \(person2.age)")
} else {
    print("초기화 실패") // 출력: 초기화 실패
}

 

  • Person 클래스는 name과 age라는 두 개의 속성을 가지고 있습니다.
  • failable initializer인 init?를 사용하여 나이가 0보다 작으면 nil을 반환합니다.
  • if let 구문을 사용하여 객체가 성공적으로 생성되었는지 확인합니다. 유효한 나이로 객체를 생성하면 정상적으로 출력되고, 유효하지 않은 나이로 생성하면 "초기화 실패" 메시지가 출력됩니다.

 

 

 

 

var lee : Man? = Man(age:1, weight: 3.5)!
if let lee1 = lee {
    lee1.display()
}

//이것도 가능
//if let lee {
//    lee.display()
//}

 

정렬은 ctrl + i

최종 코드~ 나이랑 몸무게가 0보다 커야함

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 = Man(age:10, weight: 20.5)!
kim.display()
var lee : Man? = Man(age:1, weight: 3.5)!
if let lee {
    lee.display()
}

'대학교 > iOS프로그래밍기초' 카테고리의 다른 글

옵셔널 타입  (0) 2024.10.31
[iOS프로그래밍기초] 7주차  (2) 2024.10.17
[iOS프로그래밍기초] 5주차  (2) 2024.10.08
[iOS 프로그래밍 기초] 4주차  (2) 2024.09.26
[iOS 프로그래밍 기초] 3주차  (3) 2024.09.19
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함