티스토리 뷰

 

*이 글은 객체지향과 관련된 개념을 지금 수준에서 제가 이해한 내용을 작성한 글입니다. 실제 내용과는 상당히 다를 수 있습니다~! 😀

클래스와 오브젝트, 인스턴스

- 클래스 : 내가 생각하는 클래스는 essence(본질)이다. 인스턴스로 만드려는 각 특성의 본질을 뽑아 정의한 것이다.

- 오브젝트 : 객체는 구체화 된 실체(대상)이다. 자바에서는 인스턴스를 오프젝트라고 한다.

- 인스턴스 : 클래스를 구체화한 대상이다.

상속과 다형성

- 상속 : 부모의 성질을 물려받는 것이다. 클래스가 essence였다면 상속되는 부모 클래스는 자식 클래스들의 essence이다. 한 번 더 클래스의 공통되는 본질을 뽑아낸 것을 부모 클래스로 만들어 상속하게 된다.

 

- 다형성 : 말 그대로 다양한 형(타입)이 사용할 수 있게 만드는 것이다. 상속을 사용한다는 것, 인터페이스를 구현한다는 것은 공통된 essence를 가진다는 것을 의미한다. 공통된 특징이 있기 때문에 부모의 타입을 지정한다면 자식 타입을 아우를 수 있게 된다. 각기 다른 자식 타입들을 부모의 타입으로 묶어 공통된 로직으로 사용할 수 있게 하는 것이다.

this, super

- this : 자바에서는 this는 인스턴스 된 자신을 가리킨다.

- super : super는 부모의 특성을 가리킨다. 내가 중복되는 이름의 특성을 정의했더라도 super는 부모에게서 찾는다.

객체 인스턴스 비교 방법

hashcode나 equals를 재정의하여 비교한다고 알고 있으나 사실 재정의하여 사용해본 적은 없다. 😂 재정의 한다면 자신이 비교 대상을 정의할 수 있다. 어떤 값으로 인스턴스를 비교할 것인지 내가 정의하여 사용할 수 있다.

SOLID 원칙에서 SRP 단일책임원칙

모든 클래스는 하나의 책임만 가진다. 그 책임은 캡슐화되어 다른 클래스가 어떻게 책임을 수행하는지 알 수 없게 한다. 로버트 마틴은 책임을 변경하려는 이유라고 정의한다. 어떤 클래스나 모듈은 변경하려는 단 하나의 이유만을 가져야 한다. (출처: 위키백과) 어떤 클래스에게 어느정도의 책임을 부과할 것인가는 어려운 문제이다.

 

사실 책임 문제가 어렵기 때문에 생각할 때, 나는 "너가 어떻게 하든지 상관없고 내가 요청하는 걸 해줘"라며 일을 시키는 상황을 생각한다. 그럼 그 클래스는 요청하는 걸 해줘야 하는 책임을 갖는다. 책임은 작은 클래스 단위로 내려갈수록 구체화되어 하나의 책임만 갖게 되어야 된다고 생각한다. 따라서 나는 단일책임원칙이 그 클래스가 단 하나의 책임만 갖는다 보다는 객체들의 관계속에서 단 하나의 책임을 갖는다고 생각한다.

 

만약, A가 B에게 계산가능한 좌표값을 알려달라고 했다. B의 책임은 계산가능한 좌표값을 알려주는 것이다. 하지만 값도 입력받아야하고, 값이 제대로 입력되었는지도 확인해야하고, 입력받은 값을 좌표값으로 변환해서 알려줘야 한다. B가 이 모든일을 하면 일이 너무 많기 때문에 B는 C,D,E에게 일을 나눠준다.(구체화)

A-B관계에서 B의 책임은 계산가능한 좌표값을 알려주는 것이다.

하지만, B-C,D,E 관계에서는 C : 값 입력받기, D: 제대로된 값인지 체크하기, E: 입력받은 값을 좌표값으로 변환하기가 되고, B의 책임은 C,D,E에게 일을 시키고 그 일을 잘 정리해서 A에게 주는 것이 된다. 

이렇게 객체의 책임은 관계에 따라 달라지는 것이라고 생각한다. 하지만, 관계에서 각각의 클래스는 자신이 가진 책임이 하나여야 한다. 그래야 누가 잘 못했는지를 확인할 수 있고 일이 잘못되었을 경우, 수정할 타켓은 하나가 된다.

 

SOLID 원칙에서 OCP 열림-닫힘원칙

클래스, 모듈, 함수 등 소프트웨어 객체는 확장에 열려있어야 하고, 수정에는 닫혀있어야 한다.

하나의 개체를 변경해도 이것이 다른 개체에 영향을 미치지 않아야한다는 것이다.

추상화를 사용하는 것이다. 상속과 다형성의 원리를 사용하여 공통된 essence만 가지고 객체들을 다룬다면, 그 추상화 영역에 포함된 객체이기만 하면 어떤 객체이든 상관이 없다. 객체가 추가되더라도 수정이 필요하지 않고, 다양한 타입에 대해 확장 가능하게 되는 것이다.

 

    private Figure runByCases(int[][] inputXYs) {
    // 객체가 Figure를 상속받고 있기 때문에 경우에 따라 다른 타입의 객체를 리턴가능
        if (inputXYs.length == 2) {
            return new Line(inputXYs);
        }
        if (inputXYs.length == 3) {
            return new Triangle(inputXYs);
        }
        if (inputXYs.length == 4) {
            return new Rectangular(inputXYs);
        }
        throw new IllegalArgumentException("해당하는 도형이 없어요ㅠ");
    }

 

 

정리

이런 객체지향의 원칙들을 지키기 위해서는 객체는 자신의 책임(역할)이 분명해야한다. 또한, 개체 간에 값(메세지)를 주고받으며 소통해야한다고 생각한다. 즉, 어떤 행동의 결과를 통해 소통해야 한다. 

 

역할(책임)의 단계를 항상 고민하는데 수업에서 도움이 되는 내용을 발견했다.

 

input ---> 분리/검증 ---> 저장/생성 ---> 형식/변환 ---> output

 

어렵다면 이 순서대로 생각해보고 책임을 나눠보는 것도 도움이 많이 될 것 같다. 리스코프치환 원칙(S가 T의 하위형이라면 변경없이 T의 객체를 S의 객체로 치환 가능해야한다.) 은 여러 글을 찾아봐도 아직은 이해가 안 된다. 추후 어느정도 이해가 된다면 다시 정리해보겠다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함