[F-Lab 모각코 챌린지 16일차] 객체 지향의 4대 특성

부추·2023년 6월 16일
0

F-Lab 모각코 챌린지

목록 보기
16/66

TIL

객체 지향의 4대 특성

객체 지향의 4대 특성

객체 지향을 초간단히 줄이면 프로그램을 객체들의 상호작용으로 설계하는 패러다임이다. 객체는 유일무이하며, 객체 고유의 상태 값(field)과 가능한 행위(method)를 가진다.

1) 추상화

추상화는 모델링이다. 은행 어플리케이션에서 사용할 '고객'을 모델링하는 상황이라 생각해보자.

고객은 기본적으로 인간이다 .내가 좋아하는 만화 "강철의 연금술사"에서 인간은 다음과 같이 이뤄져있다고 한다.

물 35리터, 탄소 20킬로그램, 암모니아 4리터, 석회 1.5킬로그램, 인 800그램, 염분 250그램, 질산칼륨 100그램, 유황 80그램, 플루오린 7.5그램, 철 5그램, 규소 3그램, 기타 미량 원소 15가지.

그렇다고 해서 은행 앱에서 사용할 인간 클래스를 다음과 같이 작성하면 혼나는거다.

public class Person {
	int water;
    int carbonHydrate;
    int ammonia;
    int silicon;
    // ...
    
    public void eat() {
    	System.out.println("yum yum");
    }
    public void sleep() {
    	System.out.println("zzz");
    }
    // ...
}

우리가 관심 있는 특성과 기능, 즉 어플리케이션 경계에 맞는 특성만을 프로그램에 이용해야한다. 은행 어플리케이션의 경우, 이름과 계좌 번호 포함한 기본적인 고객 정보를 필드 값, 입금하다/출금하다 등의 행위를 메소드로 정의할 수 있다. 이 과정을 보통 모델링이라고 한다. 모델링의 결과는 은행 고객 객체의 설계도가 되고, 객체 지향 프로그래밍에선 그것을 "클래스"라고 부른다.


2) 상속 : 재사용과 확장

멘토링 시간에 위대하신 멘토님이 물으셨다.

상속을 왜 사용하냐? 이점이 뭐냐?

~~.. 머릿속으로 떠오르는건 너무나 많았다. 오버라이딩.. 코드재사용.. 분류.. 인터페이스와의 차이.. 일단 공통된 걸 묶어 분류하고, 중복되는 코드를 재사용하기 위해서라고 했다.

공통된 걸 묶는다. 그렇다면 뭘 묶나요? 뭐 필드 메소드 이런걸까요?

필드도 될 수 있고 메소드도 될 수 있지 않을까. 뭔가 확답을 드리기 애매해서 음~~, 하고 민망 표정 작렬했다. 그 뒤에 멘토님의 말씀이 더 충격이었다.

말씀하신 재사용은, 상속을 사용하면 안되는 사례중 하나입니다. 재사용 할거라면 상속보다 더 좋은 방법이 있기 때문이에요.

지금 생각해보면 뭐 Composition을 사용하는 식으로 DI를 한다거나,, Strategy 패턴을 이용한다거나.. 하는 얘기일 것 같다.

아. 무. 튼. 재사용이 상속의 목적이 아니라고?! 얼른 개구리 책을 다시 펼치고 객체지향 4대 특성, 그 중에서도 상속 부분을 훑어봤다. 그리고 나름대로 이렇게 결론을 내릴 수 있었다.

"상위 클래스의 일반적 특성을 재활용하며, 하위 클래스에서 그 기능을 구체화(확장) 하기 위해 사용하는군요!"

책에 나온 예시 코드를 겜순이인 나에게 맞춰 바꿔보았다.

public class Character {
    public void attack() {
        System.out.println("기본 공격!");
    }
}

public class Magician extends Character {
    @Override
    public void attack() {
        System.out.println("마법 공격!");
    }
}

public class Warrior extends Character {
    @Override
    public void attack() {
        System.out.println("물리 공격!");
    }
}

상위 클래스인 Character을 기준으로 Magician, Warriorattack() 메소드를 오버라이딩 하고 있다.

public class AttackDriver {
    public static void main(String[] args) {
        Character [] characters = new Character[3];
        characters[0] = new Character();
        characters[1] = new Magician();
        characters[2] = new Warrior();

        for (Character c : characters) {
            c.attack();
        }
    }
}

위 코드를 돌려보면 후술할 다형성에 의해, 오버라이딩 된 각 하위 클래스의 attack() 메소드가 호출된다. 클래스가 가지는 "공격하다"라는 일반적 특성/행위를 유지하며, 하위 타입이 해당 기능을 특수하게 확장할 수 있는 좋은 예시다.

상위 클래스로 갈수록 일반/추상화 되고, 하위 클래스로 갈수록 구체/특수화 된다는 상속의 extend 개념 자체도 챙겨가야겠다.


3) 다형성

다형성에선, Overriding을 제대로 알아야 한다.

하위 클래스의 객체가 new를 통해 생성될 때 상위 클래스의 객체가 자동으로 생성된다. 때문에 하위 클래스에서 상위 클래스의 필드나 메소드 코드를 중복 작성하지 않아도 그것들을 이용할 수 있는 것이다. 이 때, 만약 하위 클래스에서 메소드를 재정의했다면 재정의한 메소드가 호출된다.

바로 위 상속에 관한 예시 코드에서도, characters 배열 각각의 객체는 모두 Character 참조 변수 타입을 가졌지만 attack()메소드를 호출한 결과는 실제 생성된 객체 타입임을 알 수 있다.

알아둬야 할 것이 있다! 실제로 생성된 객체가 하위 클래스 타입이라도 참조 변수가 상위 클래스 타입이라면 하위 클래스에만 존재하는 메소드를 호출하기 위해 형변환이 필요하다는 점이다.


4) 캡슐화

캡슐화에선 정보 은닉이 중요하다. 프로그램에서 객체가 가진 내부 필드 값이나 기능들은 접근 제어자 등을 통해 원하는 범위로만 바깥에 들어나거나 사용되게 할 수 있어야 한다.

접근 제어자와 각 접근제어자에 따른 접근 가능 범위를 나타낸 표다.

keyword접근 가능 범위비고
private해당 객체 내부 에서만 가능
protected해당 객체, 객체를 상속한 하위 클래스 객체에서만 접근 가능하위 클래스에서 this로 접근
default해당 객체, 같은 패키지 내에서만 접근 가능
public모든 범위에서 접근 가능




REFERENCE

스프링 입문을 위한 자바 객체지향의 원리와 이해 - 3장

profile
부추튀김인지 부추전일지 모를 정도로 빠싹한 부추전을 먹을래

0개의 댓글