'클래스'에 해당되는 글 2건

  1. 2021.01.27 클래스
  2. 2021.01.11 is a / has a

클래스

Swift/문법 2021. 1. 27. 17:17

클래스

- 클래스는 구조체와 유사함

- 구조체는 값 타입, 클래스는 참조 타입

- Swift의 클래스는 다중 상속이 안됨

 

 

프로퍼티 및 메서드

class Sample {

var mutableProperty: Int = 100 // 가변 프로퍼티

let immutableProperty: Int = 100 // 불변 프로퍼티

 

static var typeProperty: Int = 100 // 타입 프로퍼티

 

// 인스턴스 메서드

func instanceMethod() {

print("instance method")

}

 

 

타입 메서드

* 재정의 불가 타입 메서드 - static

static func typemethod() {

print("type method - static")

}

 

* 재정의 가능 타입 메서드 - class

class func classMethod() {

print("type method - class")

}

 

 

클래스 사용

var mutableReference: Sample = Sample()

 

mutableReference.mutableProperty = 200

 

let immutableReference: Sample = Sample()

 

immutableReference.mutableProperty = 200

 

import Foundation

struct Student {
    var name: String = "unknown"
    var 'class' = String = "Swift"
    
    // 타입 메서드
    static func selfIntroduce() {
        print("학생 타입 입니다")
    }
    
    // 인스턴스 메서드
    func selfIntroduce() {
        print("저는 \(self.class)반 \(name)입니다")
    }
}

Student.selfIntroduce() // 학생 타입 입니다

var khon: Student = Student()
khon.name = "khon"
khon.class = "스위프트"
khon.selfIntroduce() // 저는 스위프트반 khon입니다

let khon3: Student = Student()
khon3.name = "khon3"
khon3.selfIntroduce() // 저는 Swift반 unknown입니다

'Swift > 문법' 카테고리의 다른 글

값 타입과 참조 타입(value type / reference type)  (0) 2021.01.27
열거형(enum)  (0) 2021.01.27
구조체  (0) 2021.01.27
옵셔널 추출(Optional Unwrapping)  (0) 2021.01.27
옵셔널(Optional)  (0) 2021.01.27
Posted by khon98
,

is a / has a

C++ 2021. 1. 11. 18:17

https://modoocode.com/210

 

씹어먹는 C++ - <6 - 2. 가상(virtual) 함수와 다형성>

 

modoocode.com

기반 클래스 = 부모 클래스

파생 클래스 = 자식 클래스

 

 

1. is a

- 모든 상속 관계는 is a라고 볼 수 있음, 이를 뒤 바꾸면 성립되지 않음

- 모든 클래스들의 관계는 is a 로만 표현할 수 없음

- 어떤 클래스들 사이에서는 is a 대신에 has a 관계가 성립되기도 함

 

class Manger(파생 클래스) : public Employee(기반 클래스)

 

- Manager 클래스는 Employee의 모든 기능을 포함한다

- Manager를 Employee라고 봐도 무방

- Manager is a Employee

- Employee는 Manager가 아님

- Manager는 Employee로 부를 수 있지만, Employee는 Manager로 부를 수 없음

 

2. has a

- 자동차는 엔진을 가진다 car has a engine, 자동차는 브레이크를 가진다 car has a brake

 

class car {

 pirvate:

  Engine e;

  Brake b;

}

 

- Employeelist는 Employee와 has a 관계임, employee를 포함하고 있음을 알 수 있음

 

class EmployeeList {

 int alloc_employee; // 할당한 총 직원수

 int current_employee; // 현재 직원 수

 Employee **employee_list; // 직원 데이터

}

 

 

EmployeeList

#include <iostream>

class EmployeeList {
    int alloc_employee; // 할당한 총 직원수
    
    int current_employee; // 현재 직원 수
    int current_manager; // 현재 매니저 수
    
    Employee **employee_list; // 직원 데이터
    Manager **manager_list; // 매니저 데이터
};

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    return 0;
}

위 코드에서 가장 문제 되는 것은 각 클래스 별로 따로 데이터를 보관해야 한다는 것

Employee는 Employee * 가 가리켜야 하고, Manager들은 Manager * 가 가리켜야 함

업 캐스팅은 자유롭게 수행될 수 있음

Employee * 가 Manager 객체를 가리켜도 별 문제가 없다는 것

 

void print_employee_info() {
    int total_pay = 0;
    for (int i = 0; i < current_employee; i++) {
        employee_list[i]->print_info();
        total_pay += employee_list[i]->calculate_pay();
}

employee_list[i]->printf_info()를 하게 되면 무조건 Employee 클래스의 print_info 함수가 호출

employee_list[i]는 Employee 객체를 가리키는 포인터이기 때문에 자신이 가리키는 객체가 Employee 객체라고 생각함

Manager 객체와 Employee 객체 모두 Employee* 가 가리키도록 하였으므로,

만일 employee_list[i] 가 가리키는 것이 Manager 객체 일 때, Manager의 print_info함수가 아니라 

Employee의 print_info함수가 호출되서 다른 결과를 냄

마찬가지로 calculate_pay 함수도 Manager의 calculate_pay 가 호출되어야 하는데 

Employee의 calculate_pay가 호출되어서 틀린 결과가 나옴

 

#include <iostream>
#include <string>

using namespace std;

class Employee {
protected:
    string name;
    int age;
    
    string position; // 직책 (이름)
    int rank; // 순위 (값이 클 수록 높은 순위)
public:
    Employee(string name, int age, string position, int rank)
    : name(name), age(age), position(position), rank(rank) {}
    
    // 복사 생성자
    Employee(const Employee& employee) {
        name = employee.name;
        age = employee.age;
        position = employee.position;
        rank = employee.rank;
    }
    
    // 디폴트 생성자
    Employee() {}
    
    void print_info() {
        cout << name << " (" << position << " , " << age << ") ==> " << calculate_pay() << "만원" << endl;
    }
    int calculate_pay() { return 200 + rank * 50; }
};

class Manager : public Employee {
    int year_of_service;
public:
    Manager(string name, int age, string position, int rank, int year_of_service)
    : year_of_service(year_of_service), Employee(name, age, position, rank) {}
    
    // 복사 생성자
    Manager(const Manager& manager)
    : Employee(manager.name, manager.age, manager.position, manager.rank) {
        year_of_service = manager.year_of_service;
    }
    
    // 디폴트 생성자
    Manager() : Employee() {}
    
    int calculate_pay() { return 200 + rank * 50 + year_of_service; }
    void print_info(){
        cout << name << " (" << position << " , " << age << " , " << year_of_service << "년차) ==> " << calculate_pay() << "만원" << endl;
    }
};

class EmployeeList {
    int alloc_employee; // 할당한 총 직원 수
    int current_employee; // 현재 직원 수
    Employee** employee_list; // 직원 데이터
public:
    EmployeeList(int alloc_employee) : alloc_employee(alloc_employee) {
        employee_list = new Employee*[alloc_employee];
        
        current_employee = 0;
    }
    void add_employee(Employee* employee) {
        // current_employee 보다 alloc_employee가 더 많아지는 경우
        // 반드시 재할당을 해야 하지만 여기서는 최대한 단순하게 생각해서
        // alloc_employee는 언제나 current_employee 보다 크다고 생각함
        // 즉 할당된 크기는 현재 총 직원수 보다 많음
        employee_list[current_employee] = employee;
        current_employee++;
    }
    int current_employee_num() { return current_employee; }
    
    void print_employee_info() {
        int total_pay = 0;
        for (int i = 0; i < current_employee; i++) {
            employee_list[i]->print_info();
            total_pay += employee_list[i]->calculate_pay();
        }
        cout << "총 비용 : " << total_pay << "만원 " << endl;
    }
    ~EmployeeList() {
        for (int i = 0; i < current_employee; i++) {
            delete employee_list[i];
        }
        delete[] employee_list;
    }
};


int main(int argc, const char * argv[]) {
    EmployeeList emp_list(10);
    emp_list.add_employee(new Employee("khon01", 10, "평사원", 1));
    emp_list.add_employee(new Employee("khon02", 20, "평사원", 1));
    emp_list.add_employee(new Manager("khon03", 30, "부장", 7, 12));
    emp_list.add_employee(new Manager("khon04", 40, "과장", 4, 15));
    emp_list.add_employee(new Manager("khon05", 28, "차장", 5, 13));
    emp_list.add_employee(new Employee("khon06", 52, "대리", 2));
    emp_list.add_employee(new Employee("khon07", 24, "인턴", -2));
    emp_list.print_employee_info();

    return 0;
}

전부다 Employee의 print_info와 calculate_pay 함수가 호출되서 원래 결과와 달라짐

'C++' 카테고리의 다른 글

예제1  (0) 2021.01.21
static  (0) 2021.01.12
C++ 문제 풀이  (0) 2021.01.11
소켓 프로그래밍 함수와 Winsock2  (0) 2020.12.17
소켓 프로그래밍의 개요  (0) 2020.12.17
Posted by khon98
,