develop/Java

객체지향 다형성

마스카포네치즈 2021. 3. 15. 22:48

하.. 이거 놓치면 큰일

 

 객체지향의 종류중 다형성

다형성

 

= 하나의 참조변수로 여러 인스턴스를 참조하는 것.

= 인스턴스를 다양한 형태로 변환하는 것 

= 인스턴스를 업캐스팅하여 슈퍼클래스 타입으로 서브클래스 멤버 접근

 

1) 슈퍼클래스 타입 참조변수 선언을 통해 각각 다른 서브클래스의 인스턴스를 참조하는 형태로 사용하거나

(서브클래스의 인스턴스를 슈퍼클래스로 업캐스팅을 통해 참조변수를 통일함)

 

2)메서드 파라미터 선언 시 슈퍼클래스 타입 참조변수 선언을 통해 메서드 호출하여 

각각 다른 서브클래스의 인스턴스를 전달하거나

 

3)슈퍼클래스타입 배열 생성을 통해 각각 다른 서브클래스의 인스턴스를 배열에 저장하는 방법을 사용가능함.

 

class Shape{
//공통적으로 도형을 그리는 shape 클래스 생성
	public void draw(){
    	System.out.println("도형 그리기");
    }
}

class Circle extends Shape{
	public void circlerDraw(){
    	System.out.println("원 그리기");
        
       @Oveeride
     public void draw(){
    	System.out.println("원 그리기");
    }
}

class Rectangle extends Shape{
	public void rectangleDraw(){
    	System.out.println("사각형 그리기");
        
        @Oveeride
      public void draw(){
    	System.out.println("사각형 그리기");
    }
}

==> 원과 사각형을 그리는 메서드 이름이 각각 달라서 다형성으로 코드의 통일을 주려고 함
	메서드 오버라이딩 실시
    
    //메인 메서드에서 인스턴스 생성 후 메서드 호출하면
    c.draw();
    r.draw();
    //처럼 하나의 메서드 이름으로 각각의 인스턴스의 다른 메서드가 실행되므로 코드의 통일성이 향상된다
    //단, 오버라이딩을 하지 않으면 동일한 기능이 수행됨. 



 

이것보다 코드의 통일성을 더욱 향상시키기 위해 업캐스팅 활용할 수 있다!

circle과 rectangle 클래스의 공통 슈퍼클래스인 shape로 변환해서 사용한다. 

변환 후 shape의 draw()메서드로 호출하면 실제 인스턴스가 누구냐에 따라 다른 도형이 그려짐 = 동적 바인딩

Shape = s;

s = c;
s = draw(); 

s = r;
s = draw();

 

 

 

public static void drawShape(Circle c){

   c.draw();

}

메서드 파라미터가 Circle 타입일 경우 Circle 인스턴스만 전달 가능함.

 

 

 

메서드 파라미터에 대한 다형성 활용 시 

메서드 파라미터가 Circle, Rectangle 처럼 여러 타입일 때 하나의 공통된 타입으로 

매개변수를 선언하기 위해서는 그들의 슈퍼클래스인 Shape 타입 변수가 필요함.

Circle, Rectangle의 인스턴스를 Shape인스턴스로 업캐스팅함

public static void polymorphismDrawShape(Shape s){
	s.draw();
}

Shapel 타입 변수 s를 통해 각 도형의 인스턴스에 접근하면

동일한 코드 한 줄로 각각의 도형을 그릴 수 있다!

=> 파라미터로 전달되는 인스턴스에 따라 다른 도형이

 

		drawShape(new Circle()); // 전달 가능함
//		drawShape(new Rectangle()); // 오류 발생! 파라미터 불일치!
//		drawShape(new Triangle()); // 오류 발생! 파라미터 불일치!
		
		System.out.println("-------------");
		
		polymorphismDrawShape(new Circle());
		polymorphismDrawShape(new Rectangle());
		polymorphismDrawShape(new Triangle());
		// 다형성을 배열에 적용시키는 경우
		// Circle, Rectangle, Triangle 을 하나의 배열로 관리하려면
		// Shape 타입 배열(sArr)을 생성해야한다!
		Shape[] sArr = new Shape[3];
		sArr[0] = new Circle(); // Circle -> Shape 업캐스팅
		sArr[1] = new Rectangle(); // Circle -> Rectangle 업캐스팅
		sArr[2] = new Triangle(); // Circle -> Triangle 업캐스팅
		
//		sArr.draw(); // 배열에 접근하는 잘못된 문법!
		// 배열의 각 인덱스를 통해 각각의 객체에 접근해야한다!
		sArr[0].draw();
		sArr[1].draw();
		sArr[2].draw();
		
		// 반복문(for문)을 통해 sArr 배열의 각 인스턴스에 접근하여 draw() 호출
		for(int i = 0; i < sArr.length; i++) {
			sArr[i].draw();
		}