본문 바로가기
JAVA SE/이론 및 개념

[20.07.20/Day_09] Java SE / Polymorphism 다형성, Object down casting 다운캐스팅, instance of 연산자

by 파프리카_ 2020. 7. 20.
728x90
반응형

[ Review 복습 ]

// UML (통합 모델링 언어) - Class Diaram의 relation 중 현재까지 공부한 것 정리

  1. generalization (일반화) - is a relationship (상속관계)
     ex) 사람은 동물이다. 개는 동물이다.  / 매니저는 사원이다. 엔지니어는 사원이다.
  2. association (연관) - use a relationship
    ex) 사람이 렌트카를 이용하다.
  3. aggregation (집합) - has a relationship
    ex) 사람이 스마트폰을 소유하고 이용(사용)하다.
  4. composition (구성) - consist of relationship
    ex) 자동차는 엔진을 반드시 필요로 한다.

// OOP

 : 객체 지향 분석 설계 기법

 - Object를 기본 단위로 두며, object끼리의 관계를 중심으로 분석 설계하는 기법

 - object : 속성 / 기능으로 구성

 

Class : 틀, 설계도 -> object : 틀로 만들어진 것

 

// OOP 특성 

1.  Encapsultation

  " interface 를 공개하고, 구현부 implementation를 숨긴다."

     - 장점 :   1) 인터페이스를 알면 구현부를 몰라도 된다 -> 사용자 편의성

                     2)  보안성이 높아진다.

                     3) 유지보수가 쉽다.

2. Inheritance

   : 부모의  멤버(속성과 기능)을 물려받을 수 있다.

     - 장점 :   1) 재사용성이 좋다.

                      * 자식 클래스는 자신의 독자적인 속성과 기능만을 정의하면 되므로 생산성이 향상된다.

                     2)  계층구조 형성을 통한 다형성 적용 환경을 제공한다.
                      * 이 부분은 다형성 polymorphism과 관련이 된다.

 

3. Polymorphism

 


[ Polymorphism 다형성 ] 

: 다양한 형태를 가지는 성질  |  poly(다양한) + morph(형태)

 

위 재생 버튼을 보면 우리는 인지적으로 "재생"의 의미를 가짐을 알 수있다. 하지만 재생 버튼은 유튜브에서의 재생이 될 수도있고, 왓챠에서의 재생이 될 수 있고, CD player에서의 재생이 될 수 있다. 이처럼 재생 버튼(단일한 메세지 방식)을 누르면, 다양한 객체들(유튜브, 왓챠, CD 플레이어 등)이 각자의 방식으로 동작한다.(동영상 재생, 영화/드라마 재생, CD 음원 재생)

여기서 위 재생버튼과 같이 단일한 메세지 방식은 interface, 메서드 명으로 불리기도 한다.

 

"One Interface, Multiple Implements"

즉, polymorphism 다형성 이란, 하나의 메세지 방식으로 다양한 객체들이 각자의 방식으로 동작하는 성질을 뜻한다.

 

 

다형성 오버라이딩 예제

1. 상속을 이용한 다형성이 적용된 매개변수

//super class
class Animal{
	public void eat() {
		System.out.println("먹다");
	}
}

//sub class 1
class Person extends Animal{
	//메서드 오버라이딩 : 부모메서드를 자신에 맞게 재정의
	public void eat() {
		System.out.println("사람이 두부김치를 먹다");
	}
}

//sub class 2
class Monkey extends Animal{
	public void eat() {
		System.out.println("원숭이가 바나나를 먹다");
	}
}

class Car{}

//실행 class
public class TestPolymorphism1 {
	public static void main(String[] args) {
		// new Person()으로 객체 생성하고, 
		// 반환되는 주소값을 Animal 타입의 a변수에 할당한다.
		// 부모 타입의 변수에 자식 객체를 참조시킬 수 있다.
		Animal a = new Person();
		a.eat(); //자식의 오버라이드 된 메서드가 실행된다.
		
		// 부모타입 Animal 변수에 Monkey 자식 객체를 참조시킨다.
		Animal a2 = new Monkey();
		a2.eat();
		
		/* 출력값 : 
		 * 사람이 두부김치를 먹다
		 * 원숭이가 바나나를 먹다
		 */
		
		// error // Car는 Animal의 자식이 아니므로 complie error
		//Animal a3 = new Car();
	}
}

 

2. 다형성을 이용하지 않을 때,

class Zoo{
	public void pass(Person p) {
		p.eat();
	}

	public void pass(Monkey monkey) {
		monkey.eat();
	}
}


public class TestPolymorphism2 {
	public static void main(String[] args) {
		Zoo zoo = new Zoo();
		zoo.pass(new Person());
		zoo.pass(new Monkey());
	}
}

 

> 1번의 경우 상속을 통한 다형성을 통해, 다형성이 적용된 매개변수로 처리하면, 

Animal 자식 객체의 종류 수와 관계없이 하나의 메서드(메세지 방식)에서 모두 처리할 수 있다.

 

> 2번처럼 개체의 종류가 새로 생성될 경우, 이에 대응하는 처리 메서드는 계속 생성되어야한다.

이는 시스템의 결합도가 높아 유지보수성이 좋지 않다.

 

2번 예제를 다형성을 적용할 수 있는 형태로 바꾼다면, 아래와 같이 하면 된다.

class Zoo{
	public void pass(Animal a) {
		a.eat();
	}
}


public class TestPolymorphism2 {
	public static void main(String[] args) {
		Zoo zoo = new Zoo();
		zoo.pass(new Person());
		zoo.pass(new Monkey());	
	}
}

 

* 좋은 시스템은 응집도(cohesion)은 높고, 결합도(coupling)는 낮아야한다.

높은 응집도란 시스템 모듈이 자신의 역할에 충실한 것을 의미하며,

낮은 결합도란 시스템 모듈간에 의존도를 최소화하는 것을 의미한다.

 

(참고 : https://ko.wikipedia.org/wiki/%EA%B2%B0%ED%95%A9%EB%8F%84 )

 

결합도 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 소프트웨어 공학에서, 결합도(coupling) 또는 의존도는 어떤 모듈이 다른 모듈에 의존하는 정도를 나타내는 것이다. 결합도는 보통 응집도(cohesion)과 대비된다. 낮

ko.wikipedia.org

 


[ Object Casting (Object down Casting) ]

부모타입의 변수에 자식 객체를 참조할 경우, 

1) 상속받은 부모 속성과 기능을 사용할 수 있고 2) 오버라이딩된 자식의 메서드도 사용가능하다.

 

단, 자식의 독자적 멤버(속성과 기능)에 접근할 경우에는 Object Down Casting 절차가 필요하다.

 

# Animal class

// super class
class Animal {
	public void sleep() {
		System.out.println("자다");
	}

	public void eat() {
		System.out.println("먹다");
	}
}

# Person class

// sub class
class Person extends Animal {
	// eat메서드 오버라이딩 : 부모 메서드를 자신에 맞게 재정의
	public void eat() {
		System.out.println("사람이 수저로 먹다");
	}

	// 자식 class의 독자적인 멤버(메서드)
	public void study() {
		System.out.println("사람이 공부하다");
	}
}

# 실행 class

public class TestPolymorphism5 {
	public static void main(String[] args) {
		// 부모타입의 변수에, 자식 객체를 참조시킬 수 있다.
		Animal a = new Person();
		
		// 이 경우 접근하여 사용가능한 것은, 
		// 1. 부모로부터 상속받은 멤버(변수, 메서드)와
		// 2. 오버라이딩한 메서드이다.
		
		// 1번 사례 - 상속
		a.sleep(); 
		
		// 2번 사례 - 오버라이딩
		a.eat();
		
		// error - 자식의 독자적인 멤버
		// a.study(); //a는 Animal 부모 타입이므로
		// 접근하기 위해서는 Object down casting 필요
		((Person) a).study();
	}
}

 


[ Instance of 연산자 ]

: 객체의 타입을 비교한다.

is a 관계면 true를 반환. *"같으면"이 아니다 !

* == 와의 차이점은 instanceof 는 객체가 그 부모까지 포함하는지도 확인할 수 있다.

 

 

예제

class Employee{}
class Engineer extends Employee{}
class Manager extends Employee{}
class Secretary extends Employee{}


public class TestInstanceof {
	public static void main(String[] args) {
		// instanceof 연산자 : is a 관계가 성립되면 true를 반환
		Employee e = new Manager();
		if (e instanceof Manager) { //true 반환
			System.out.println("관리자");
		}
		if (e instanceof Secretary) { //false 반환
			System.out.println("비서");
		}
		if (e instanceof Employee) {//true 반환
			// Manager is a Employee
			System.out.println("사원");
		}	
	}//main
}//class

 

 

728x90
반응형