클래스와 객체

이가현·2023년 7월 27일
0

코틀린

목록 보기
4/12

객체 지향 프로그래밍은 프로그램의 구조를 객체 간 상호작용으로서 표현하는 프로그래밍 방식이다.

추상화 : 특정 클래스를 만들 때 기본 형식을 규정하는 방법
인스턴스 : 클래스로부터 생성한 객체
상속 : 부모 클래스의 내용을 자식 클래스가 그대로 물려받음
다형성 : 하나의 이름으로 다양한 처리를 제공
캡슐화 : 내용을 숨기고 필요한 부분만 사용
메시지 전송 : 객체 간에 주고받는 메시지
연관 : 클래스 간의 관계

이러한 개념을 잘 알아두어야 한다.

객체 지향 프로그래밍의 용어 정리

클래스 : 분류, 범주
프로퍼티 : 속성, 변수, 필드, 데이터
메서드 : 함수, 동작, 행동
객체 : 인스턴스

코틀린 언어 : 자바 언어

클래스 다이어그램

클래스 다이어그램으로 Bird 클래스를 표현하면 이렇다.

프로퍼티나 메서드 앞에 있는 +, -는 가시성을 나타낸다. 여기서 -는 private을 의미하고 +는 public을 의미한다.

클래스와 추상화


새의 기본동작을 함수(메서드)로서 특징을 변수(프로퍼티)로서 나타낸다.

그렇다면 이제 클래스를 만들어보겠다.

점( . )을 통해 멤버 메서드에 접근할 수 있다.

Bird라는 표현은 모든 새를 가리키는 개념일 뿐 실제 살아서 움직이는 것이 아니다. 다시 컴퓨터의 세계에서 말하자면 Bird 클래스란 일종의 선언일 뿐, 실제 메모리에 존재해 실행되고 있는 것이 아니다. 이 클래스로부터 객체를 생성해야만 비로소 클래스라는 개념의 실체인 객체가 물리적인 메모리 영역에서 실행된다. 클래스를 사용하는 이유다.
이것을 인스턴스화 되었다고 이야기 한다. 특정 클래스로부터 인스턴스화해 객체의 이름을 줄 수 있다고 생각하면 구분이 쉽다. 이름 모를 새에게 coco라는 이름을 지어주면 새라는 추상적인 개념이 coco라는 구체적인 객체가 된 것이다.


프로퍼티는 선언만 하고 9째과 같이 부 생성자의 매개변수를 통해 초기화할 수 있다. 단, constructor 블록에서 매개변수로 전달받은 name과 프로퍼티 선언의 name을 구분하기 위해 Bird의 클래스를 가리키는 this 키워드를 사용해 프로퍼티를 지정한다. 즉 this.name의 name은 변수(프로퍼티)이고 그 다음 name은 매개변수인 것이다.


주 생성자의 매개변수에 프로퍼티가 선언되었으므로 본문에서 프로퍼티 선언이 생략되었다. 코드가 매우 간략화되었다.

Init 초기화 블록


init 초기화 블록에서 name과 beak를 출력하고 sing 메서드를 사용했다. 객체 생성 시점에서 코드 수행 문장을 실행할 수 있기 때문에 매우 편리하다.

프로퍼티는 기본값을 지정할 수 있다.(함수와 유사)

상속 클래스

Bird 클래스만으로는 특별한 새를 나타내기에 애매할 때 하위에 새로운 분류를 넣을 수 있다. 앵무새라는 새로운 클래스를 만들 때 기반 클래스는 Bird 클래스이므로 파생 클래스로서 앵무새를 나타내는 Parrot 클래스를 새로 정의하면 기반 클래스인 Bird의 프로퍼티와 메서드를 Parrot 클래스에 상속할 수 있다.


그렇다면 파생 클래스를 만들어보겠다.


open 키워드를 사용하여 Bird 클래스를 정의했다. Lark 클래스는 주 생성자를 사용하는 방법으로 선언했다. 이때 상위 클래스인 Bird 클래스에 생성자를 사용하는 매개변수와 인자들을 지정해야 한다. Parrot 클래스는 부 생성자를 이용하는 방법으로 선언했는데, 이때는 본문 내부에 constructor( )를 이용한다. 또한 language를 초기화해 확장되었다. speak 메서드도 추가되었기 때문에 Parrot 클래스에는 fly, sing, speak 메서드를 갖는다.

다형성

만약 하위 클래스에서 똑같은 이름의 메서드나 프로퍼티를 지정한다면 어떻게 될까? 이름이 동일하지만 매개변수가 서로 다른 형태를 취하거나 실행 결과를 다르게 가질 수 있는 것을 다형성이라고 한다.
.
.

  • 오버로딩(Overloading) : print(123), print("hello")와 같이 동작은 동일하지만 인자의 형식만 달라지는 것.

    서로 다른 매개변수를 가진 add 함수다.
    .
    .
    .
    .
  • 오버라이딩(Overriding) : push 버튼을 눌렀을 때 취소 버튼에 적용되면 프로그램을 종료하고, 저장 버튼에 적용되면 작업을 저장하는 것처럼 같은 이름의 메서드로 서로 다른 동작을 하는 것.
    즉, 상위 하위 클래스에서 메서드와 프로퍼티의 이름을 같지만 기존의 동작을 다른 동작으로 재정의 하는 것.

    기반 클래스인 Bird는 open으로 선언되어 상속 가능하다. 또 Bird 클래스의 멤버 메서드인 sing 또한 open으로 선언되어 오버라이딩할 수 있는 메서드가 되었다.
    이처럼 오버라이딩은 하위 클래스에서 특정 메서드를 재설계할 때 유용한 기법으로 유용하면서도 사용하기 쉬운 메서드를 설계할 수 있다.
    sing함수를 27째 줄에서 호출했을 때 오버라이딩 된 sing이 쭉 출력된다.

Super, this

클래스를 상위와 하위 클래스로 설계하다 보면 상위와 현재 클래스의 특정 메서드나 프로퍼티, 생성자를 참조해야하는 경우가 생긴다. 상위 클래스는 super 키워드로, 현재 클래스는 this 키워드로 참조가 가능하다.


main함수의 Developer의 인자 한 개를 보냈기 때문에 13째 줄로 간다. 13째 줄에서 this 키워드를 사용했으므로 Sean, 10을 가지고 16째 줄로 간다. 16째 줄에서 super 키워드를 사용했으므로 상위 클래스로 올라간다. 인자를 두 개를 가지므로 7째 줄로 간다. 거기서 8째 줄을 출력하고 super로 내려와서 17째 줄을 출력하고, 14째 줄을 출력하게된다. 즉, 8, 17, 14 순서로 출력한다. 가리키는 곳으로 가서 this, super 키워드가 존재하면 그 부분을 먼저 처리하는 식인 것 같다.


주 생성자와 부 생성자가 함께 있다면 this를 사용해 주 생성자를 가리킬 수 있다. 인자가 두 개일 때와 한 개일 때 달라진다.

바깥 클래스 호출하기

클래스를 선언할 때 클래스 안에 다시 클래스를 선언하는 것이 가능하다. 이를 이너 클래스라고 한다. 만일 이너 클래스에서 바깥 클래스의 상위 클래스를 호출하려면 super 키워드와 @기호 옆에 바깥 클래스 이름을 작성하면 된다.


Child 클래스는 Base 클래스를 상속하고 있다. c1.Inside( ).test( )는 Inside에 접근하고 다시 test에 접근한다. 15째 줄의 f( )는 13째 줄의 f( )를 접근하여 실행한다. 그 다음 Child( ).f( )는 10째 줄의 f( )를 접근하여 실행한다. 그 다음 17째 줄의 f( )는 Child의 상위 클래스인 Base의 f( ), 5째 줄을 실행한다. 마지막으로 18째 줄을 실행한다.

인터페이스에서 참조하기

인터페이스 자체로는 객체로 만들 수 없고 항상 인터페이스를 구현하는 클래스에서 생성해야 한다. 만일 동일한 이름의 프로퍼티나 메서드가 있다면 앵글 브래킷<>을 사용해 접근하려는 클래스나 인터페이스의 이름을 정해준다.

  • 앵글 브래킷을 사용한 이름 중복 해결하기

    b함수처럼 중복되지 않을 때에는 그냥 사용하면 되지만 f함수처럼 중복된다면 앵글브래킷을 사용하여 구분할 수 있다. 이 코드에는 f함수가 총 3개 있는데 그냥 f만 사용하면 현재 클래스, 앵글브래킷을 사용하면 그 클래스에 있는 f를 사용하게 된다.

1개의 댓글

comment-user-thumbnail
2023년 8월 6일

좋은 글 잘보고갑니다 ^^
저도 코틀린 공부를 해볼까 하는데 도움이 많이 되었습니다.

답글 달기