객체지향 다형성
하.. 이거 놓치면 큰일
객체지향의 종류중 다형성
다형성
= 하나의 참조변수로 여러 인스턴스를 참조하는 것.
= 인스턴스를 다양한 형태로 변환하는 것
= 인스턴스를 업캐스팅하여 슈퍼클래스 타입으로 서브클래스 멤버 접근
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();
}