상위 클래스인 추상클래스는 하위에 구현된 여러클래스를 하나의 자료형(상위 클래스 자료형)으로 선언하거나 대입할 수 있다. 추상 클래스에 선언된 메서드를 호출하면 가상 메서드에 의해 각 클래스에 구현된 기능이 호출된다. 즉 하나의 코드가 다양한 자료형을 대상으로 동작하는 다형성을 활용 할 수 있다.

 

아래는 추상클래스는 아니지만 다형성을 보여주는 예이다.

public class ShapeTest {

	public static void main(String[] args) {
		Shape1 s1,s2,s3; //s1, s2, s3은 모두 부모클래스인 Shape1 클래스 형을 갖는다
		s1 = new Shape1(); // s1, s2, s3 참조변수 모두에 Shape1 인스턴스가 부여된다.
		s2 = new Shape1();
		s3 = new Shape1();
		
		s1.draw();                //Shape Draw 출력
		s2.draw();                //Shape Draw 출력
		s3.draw();                //Shape Draw 출력
		
		s1 = new Rectangle1(); // s1, s2, s3 에 각각 Rectangle1(), Triangle1(), Circle1() 인스턴스가 부여된다.
		s2 = new Triangle1();
		s3 = new Circle1();    // 따라서 각 인스턴스의 클래스에 있는 메소드가 아래와 같이 출력이 된다.
		
		s1.draw();                //Rectangle Draw 출력
		s2.draw();                //Triangle Draw Draw 출력
		s3.draw();                //Circle Draw 출력
	}
}

class Shape1{
	protected int x, y;
	
	public void draw() {
		System.out.println("Shape Draw");
	}
}

class Rectangle1 extends Shape1 {
	private int width, height;
	
	public void draw() {
		System.out.println("Rectangle Draw");
	}
}

class Triangle1 extends Shape1{
	private int base, heigth;
	
	public void draw() {
		System.out.println("Triangle Draw");
	}
}

class Circle1 extends Shape1{
	private int radius;
	
	public void draw() {
		System.out.println("Circle Draw");
	}

 

그렇다면 자료형이 클래스 이름이라는 말은 무슨 뜻일까?

아래 소스를 통해 확인해보자

public class MyCounterTest {

    public static void main(String[] args) {
        MyCounter obj = new MyCounter(); 
        obj = new YourCounter();  /*참조변수 obj가 YourCounter 클래스를 참조할 수있게 변경하였지만 
                                    obj는 계속 MyCounter 형이기 때문에*/
        
        System.out.println("obj.value = " + obj.value);
        obj.inc(obj);              /*여기서 MyCounter형의 참조변수만 받는 MyCounter클래스의 inc메소드에
                                     들어가 작동한다.*/
        
        /*obj.incc(obj); <- 오류  // obj는 YourCounter 인스턴스로 변경되었어도 MyCounter클래스 형이기 
                                     때문에 YourCounter형의 참조변수만 받는 incc에는 접근 불가*/
       
        System.out.println("o3bj.value = " + obj.value);
    }
}

class MyCounter {
    int value;
    void inc(MyCounter ctr) {
        ctr.value = ctr.value + 1;
    }
}

class YourCounter extends MyCounter{
	void incc(YourCounter ctr) {
        ctr.value = ctr.value + 2;
    }
}

 

YourCounter는 MyCounter를 상속 받았으므로 상위 클래스인 MyCounter형으로 객체(참조변수)를 선언하여 사용할 수 있다.

 

참고로, 인스턴스 변환하여 메소드에 대입하는 과정을 간결하게 표현하는 방법이 있다. 방법은 아래와 같다.

class Human extends Animal {}

public class Animal{
	public static void main(String[] args) {
		Animal ani = new Animal();
		ani = new Human();
		ani.moveAnimal(ani);
		//ani.moveAnimal(new Human());  //<-- 바로 위 두줄을 이렇게 간단히 줄여 사용할 수 있다.
	}

	public void moveAnimal(Animal animal) {}
}
반응형

'JAVA > 개념' 카테고리의 다른 글

[자바] set함수, get함수  (0) 2021.03.30
[자바] 생성자  (0) 2021.03.30

+ Recent posts