본문

객체 지향의 4대 특성(JAVA)

반응형

# 객체 지향의 4대 특성 - 캡!상추다


- 캡슐화(Encapsulation) : 정보은닉(information hiding)

- 상속(Inheritance) : 재사용

- 추상화(Abstraction) : 모델링

- 다형성(Polymorphism) : 사용편의



# 추상화 - 객체 지향에서 추상화의 결과는 클래스다.

추상화란 구체적인 것을 분해해서 관심 영역(애플리케이션 경계, Application Boundary)에 있는 특성만 가지고 재조합하는겻 = 모델링


모델은 실제 사물을 정확히 복제하는 게 아니라 목적에 맞게 관심 있는 특성만을 추출해서 표현하는 것이다. 바로 모델은 추상화를 통해 실제 사물을 단순하게 묘사하는 것이다. 이런 모델링(추상화)은 객체 지향에서 클래스를 설계할 때 필요한 기본이고 또한 데이터베이스의 테이블을 설계할 때 필요한 기법이다. 어떻게 모델링(추상화)하느냐가 얼마나 중요한지는 협업 프로그래머들에게 물어보면 피를 토하며 그 중요성을 이야기해 줄 것이다.


자바는 객체 지향의 추상화를 어떻게 지원하고 있을까? 바로 class 키워드를 통해 지원하고 있다. 꼭 기억하자.

추상화 = 모델링 = 자바의 class 키워드


그럼 클래스와 객체 관계를 자바에서는 어떻게 표현할까? 바로 다음과 같이 표현하면 된다.


클래스 객체_참조_변수 = new 클래스();

새로운 객체를 하나 생성해 그 객체의 주소값(포인터)을 객체 참조 변수에 할당



# 상속 - 부모와 자식 관계가 아니다.

객체 지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속(특성 상속)하고 거기에 더해 필요한 특성을 추가, 즉 확장해서 사용할 수 있다는 의미이다. 즉, 확장해서 사용할 수 있다는 의미이다. 그런데 사람들은 클래스의 특성을 상속한다는 말에서 특성을 빼고 클래스를 상속한다는 뜻으로 오해를 하니 부모-자식 관계가 나와 버린 것이다. 객체 지향의 상속은 부모-자식 같은 계층도나 조직도가 아닌 동물-포유류 같은 분류도라는 사실을 꼭 기억하자.



객체 지향의 상속 - 집합(포함, 세분화, 분류) 벤 다이어그램


Source 01) Animal.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package inheritance;
 
public class Animal {
    String group;
 
    Animal() {
        group = "동물";
    }
 
    void showMe() {
        System.out.println(group);
    }
 
}
cs


Source 02) Mammal.java
1
2
3
4
5
6
7
package inheritance;
 
public class Mammal extends Animal {
    public Mammal() {
        group = "포유류";
    }
}
cs


Source 03) Birds.java
1
2
3
4
5
6
7
8
package inheritance;
 
public class Birds extends Animal {
    public Birds() {
        group = "조류";
    }
 
}
cs


Source 04) Bat.java
1
2
3
4
5
6
7
8
package inheritance;
 
public class Bat extends Mammal {
    public Bat() {
        group = "박쥐";
    }
}
 
cs


Source 05) Penguin.java

1
2
3
4
5
6
7
package inheritance
 
public class Penguin extends Birds {
    public Penguin() {
        group = "펭귄";
    }
}
cs


Source 06) Sparrow.java
1
2
3
4
5
6
7
8
package inheritance;
 
public class Sparrow extends Birds {
    public Sparrow() {
        group = "참새";
    }
 
}
cs


Source 07) Whale.java

1
2
3
4
5
6
7
8
package inheritance;
 
public class Whale extends Mammal {
    public Whale() {
        group = "고래";
    }
 
}
cs


Source 08) Driver02.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package inheritance;
 
public class Driver02 {
 
    public static void main(String[] args) {
 
        Animal[] animals = new Animal[7];
 
        animals[0= new Animal(); // 동물
        animals[1= new Mammal(); // 포유류
        animals[2= new Bat(); // 조류
        animals[3= new Whale(); // 고래
        animals[4= new Bat(); // 박쥐
        animals[5= new Sparrow(); // 참새
        animals[6= new Penguin(); // 팽귄
 
        for (int index = 0; index < animals.length; index++)
            animals[index].showMe();
    }
 
}
cs


Result)

1
2
3
4
5
6
7
동물
포유류
조류
고래
박쥐
참새
펭귄
cs

상속관계 표현 :: Kind of

- 하위 클래스 is a kind of 상위 클래스

- 펭귄 is a kind of 조류 : 펭귄은 조류의 한 분류이다.

- 펭귄 is a kind of 동물 : 펭귄은 동물의 한 분류이다.

- 고래 is a kind of 동물 : 고래는 동물의 한 분류이다.

- 조류 is a kind of 동물 : 조류는 동물의 한 분류이다.


* 객체 지향의 상속은 상위 클래스의 특성을 재사용하는 것이다.

* 객체 지향의 상속은 상위 클래스의 특성을 확장하는 것이다.

* 객체 지향의 상속은 is a kind of 관계를 만족해야 한다.



# 다형성 :-오버라이딩(Overriding) 오버로딩(Overloding)

객체지향에서 다형성이라고 하면 오버라이딩(overriding)과 오버로딩(overloading)이라고 할 수 있다. 물론 상위클래스와 하위클래스 사이에서도 다형성을 이야기할 수 있고, 인터페이스와 그것의 구현 클래스 사이에서도 다형성을 이야기할 수 있지만 가장 기본은 오버라이딩과 오버로딩이라고 할 수 있다.


- 오버라이딩 : 같은 메서드 이름, 같은 인자 목록으로 상위 클래스의 메서드를 재정의

- 오버로딩 : 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 중복 정의

  (참고 : ride = 올라타다, load = 적재하다)



오버라이딩은 하위 클래스가 재정의한 메서드를 알아서 호출해 줌으로써 형변환이나 instanceof 연산자를 써서 하위 클래스가 무엇인지 신경 쓰지 않아도 된다. 상위 클래서 타입의 객체 참조 변수에서 하위 클래스가 오버라이딩한 메서드를 자동으로 호출해 줌으로써 깔끔한 코드를 유지할 수 있게 된다.


오버로딩은 함수명 하나를 가지고 인자 목록만 달리하면 되니 얼마나 사용하기 편리한지 알 수 있다. 특히 자바 5에서 추가된 제네릭을 이용하면 하나의 함수만 구현해도 다수의 함수를 구현한 효과를 낼 수 있다. 다형성에 대해 사용 편의성이라고 정의한 이유는 바로 이 때문이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Driver {
    public static void main(String[] args) {
        동뮬[] 동물들 = new 동물[5];
 
        동물들[0= new 쥐();
        동물들[1= new 고양이();
        동물들[2= new 강아지();
        동물들[3= new 송아지();
 
        for (int i = 0; i < 동물들.length; i++) {
            동물들[i].울어보세요();
        }
    }
}
 
cs


위와같은 소스가 있다고 해보자. 상위 클래스인 동물 클래스에 울어보세요()라는 메서드를 정의해두고 하위 클래스인 쥐, 고양이, 강아지, 송아지 클래스에서 각각 울어보세요() 메서드를 오버라이딩 했다고 가정해 보자. 실행 결과는 각 동물들이 하위 클래스 타입에 맞게 울게 된다는 것이다. 예상 결과는 아래와 같을 것이다.


1
2
3
4
나는 쥐! 찍!!
나는 고양이! 야옹!야옹!
나는 강아지! 멍!!
나는 송아지!음메!음메!
cs


즉, 오버라이딩을 통한 메서드 재정의, 오버로딩을 통한 메서드 중복 정의를 통해 다형성을 제공하고 이 다형성이 개발자가 프로그램을 작성할 때 사용편의성을 준다.


# 캡슐화 - 정보은닉

자바에서 정보 은닉(information hiding)이라고 하면 접근 제어자인 private, [default], protected, public이 생각날 것이다.

protected가 자신과 상속 관계에 있는 서브 클래스만 접근 가능한 걸로 착각하는 경우가 많은데, 같은 패키지라면 한 집에 산다고 생각하기에 접근 가능하다는 사실도 꼭 기억해야 한다.



* 상속을 받지 않았다면 객체 멤버는 객체를 생성한 후 객체 참조 변수를 이용해 접근해야 한다.

* 정적 멤버는 클래스명.정적맴버 형식으로 접근하는 것을 권장한다.






- 출처 및 참고자료 : 스프링 입문을 위한 자바객체지향의 원리와 이해(김종민 저)

반응형

공유

댓글