본문 바로가기
JAVA 기초 정리

JAVA 객체지향과 다형성

by kjwkjw 2020. 3. 6.

다형성은 하나의 심볼(이름)이 여러 실체에 매핑될 수 있다는 의미다.

 

JAVA에서 다형성을 구현하기 위해 abstract 클래스와 Interface를 사용한다.

 

1. abstract

 

abstract 클래스란 abstract 메소드를 하나라고 갖고 있는 클래스를 말한다.

 

abstract class A{
	public abstract int cal(int a, int b);
	public void print() {
		System.out.println("print D");
	}
}

class B extends A{
	@Override
	public int cal(int a, int b) {
		return a+b;
	}
}

public class Test015 {
	public static void main(String[] args) {
		B f = new B();
		f.print(); // print D
		System.out.println(f.cal(10, 5)); // 15
	}
}

abstract 클래스가 갖는 메소드는 모두 abstract메소드일 필요가 없다.

일반적인 메소드의 리턴 타입 앞에 abstract를 적으면 abstract 메소드가 된다.

abstract 메소드는 말 그대로 추상화된 메소드다. 따라서 메소드의 기능을 구현하지 않은 상태로 둔다.

 

abstract의 body를 구현한다면 다음과 같이 오류가 발생한다.

abstract 클래스를 상속 받은 클래스는 반드시 모든 abstract 메소드를 overriding해야한다.

 

따라서 클래스 B는 반드시 cal 메소드를 overriding을 해야하기 때문에 더하기로 구현을 했고, print함수는 abtract메소드가 아니다. 따라서 overriding을 할 필요가 없기 때문에 상속받은 그대로 사용할 수 있다.

 

2. interface 

 

interface는  특별한 예외를 제외하고 interface가 갖고 있는 메소드는 모두 추상화된 메소드여야 한다.

 

interface를 상속받은 클래스는 필수적으로 interface의 모든 메소드를 overriding해야 한다는 점에서 abstract클래스를

상속받은 클래스와 차이가 있다.

 

interface를 상속받은 클래스는 일반적인 클래스를 상속받은 클래스와 달리 extends 대신 implements를 써야 한다.

 

interface CalI{
	public int cal(int a, int b);
	public void print();
}

class CalA implements CalI{

	@Override
	public int cal(int a, int b) {
		return a + b;
	}

	@Override
	public void print() {
		System.out.println("print CalA");
	}
	
}

class CalB implements CalI{

	@Override
	public int cal(int a, int b) {
		return a - b;
	}

	@Override
	public void print() {
		System.out.println("print CalB");
	}
	
}


public class Test015 {
	public static void main(String[] args) {
		CalA calA = new CalA();
		CalB calB = new CalB();
		
		calA.print(); // print CalA
		System.out.println(calA.cal(10, 5)); // 15
		
		calB.print(); // print CalB
		System.out.println(calB.cal(10, 5)); // 5
	}
}

 

CalA와 CalB는 CalI interface를 상속받았다. 각 클래스는 interface의 메소드를 모두 overriding해야 하기 때문에 

cal과 print 메소드를 자신의 클래스에서 재정의했다.

 

즉 CalI는 계산기를 구현할 수 있는 뼈대만 제공하고 상속받은 클래스에서 클래스의 의도에 따라 메소드를 재정의하여

사용할 수 있게 한다.

 

interface로 다형성을 구현한 간단한 예시

 

interface Vehicle{
	public void move();
	public void back();
	public void getDistance();
}

class SportsCar implements Vehicle{
	private int distance = 0;
	@Override
	public void move() {
		distance = distance + 6; 
	}

	@Override
	public void back() {
		distance = distance - 6; 
	}
	
	public void getDistance() {
		System.out.println(distance);
	}
}

class Car implements Vehicle{
	private int distance = 0;
	@Override
	public void move() {
		distance = distance + 4; 
	}

	@Override
	public void back() {
		distance = distance - 4; 
	}
	
	public void getDistance() {
		System.out.println(distance);
	}
}

class Bike implements Vehicle{
	private int distance = 0;
	@Override
	public void move() {
		distance = distance + 2; 
	}

	@Override
	public void back() {
		distance = distance - 2; 
	}
	
	public void getDistance() {
		System.out.println(distance);
	}
}



public class Test015 {
	public static void main(String[] args) {
		SportsCar sc = new SportsCar();
		sc.move();
		sc.move();
		sc.getDistance();
	}
}

 

Vehicle  interface는 이동수단이라는 공통된 목적을 갖는 SportsCar, Car, Bike 클래스에게 구현의 뼈대를 제공하고 각각의 클래스는 능력에 맞게 메소드를 재정의 하여 다형성을 구현했다. 

 

즉 하나의 심볼(Vehicle)이 여러 실체(SportsCar, Car, Bike)에 매핑된 것이다.

 

public class Test015 {
	public static void main(String[] args) {
		Bike sc = new Bike();
		sc.move();
		sc.move();
		sc.getDistance();
	}
}

때에 따라서 다른 이동수단으로 변경하고 싶다면 인스턴스의 클래스만 변경하여 선택된 이동수단을 이용할 때 정확한 이동거리를 알 수 있다.

댓글