추상 클래스와 인터페이스

2022. 3. 14. 23:42JAVA

반응형
추상 클래스의 개념

 추상 클래스는 객체를 직접 생성 할 수 있는 실체 클래스들의 공통적인 특징들을 추출하여 선언한 클래스, 직접적인 객체 생성이 불가능

 

 추상 클래스는 실체 클래스들을 자식 클래스로 가지며, 이 실체 클래스들은 기본적으로 추상 클래스의 모든 특징을 가진다.

 

 사용 목적
  1.  추상 클래스를 사용함으로, 동일한 특성을 가지는 실체 클래스들의 메소드 명을 통일 할 수 있다.
  2.  또한 상속을 통하여, 실체 클래스의 작성 시간을 절약 할 수 있다

 

추상 클래스의 사용.

예를 들어, 게임의 몬스터 클래스를 생성한다고 가정하자.

A,B,C 3마리의 몬스터가 존재하고, 각각의 몬스터들을 모두, 체력, 공격력, 방어력을 가지고, 피격을 받으면, 데미지 많큼 체력이 줄어들며, 체력이 0이 되면 사망메시지를 출력한다고 가정하자.

그리고,

  1. A몬스터의 경우, 이동이 불가능한 개체이고 
  2. B몬스터의 경우, 이동은 가능하지만 평면에서의 이동만이 가능하고,
  3. C몬스터의 경우, 평면 이동은 물론, 비행까지 가능하다.
  체력 공격력 방어력 이동(평면) 이동(비행)
A x x
B x
C

위 정보를 토대로 이런 형태의 표를 만들 수 있을 것이고, 

 

먼저 몬스터라는 개체는 모두 체력, 공격력, 방어력을 공통으로 가지므로, 

public abstract class 몬스터{
	private int 체력;
    private int 공격력;
    private int 방어력;
    
    //생성자
    public 몬스터(int 체력, int 공격력, int 방어력){
    	this.체력 = 체력;
        .
        .
    }
    
    ...getter
    ...setter
    
    public void 피격(int 데미지){
    	this.체력 = this.체력 - 데미지;
        if(체력<=0)System.out.println('사망');
    }
    
}

체력과, 공격력, 방어력을 가지며, 체력이 0이되면 사망 메시지를 출력하는 추상 클래스를 먼저 정의 하고,

public class A몬스터 extends 몬스터{
	 //생성자
    public A몬스터(int 체력, int 공격력, int 방어력){
    	super(...);
    } 
}

A몬스터 클래스는, 추상 클래스 몬스터를 상속받아 작성한다.

public class B몬스터 extends 몬스터{
	 //생성자
    public B몬스터(int 체력, int 공격력, int 방어력){
    	super(...);
    } 
    
    public void move(){
    //move
    ..
    }
}

B몬스터의 경우도, 추상 클래스 몬스터로 부터 상속을 받은 후 필요한 기능인 평면 이동 기능을 추가하고

public class C몬스터 extends 몬스터{
	 //생성자
    public C몬스터(int 체력, int 공격력, int 방어력){
    	super(...);
    } 
    
    public void move(){
    //move
    ..
    }
    
    public void fly(){
    //fly
    ..
    }
}

C몬스터는 거기에 비행 기능을 추가한다.

 

추상 메소드와 오버라이딩

 

 위에서 추상 클래스 몬스터 클래스의 경우, 피격 메소드를 가지고 있는데, 이 경우, 모든 자식 클래스에서 동일한 내용을 수행하기 때문에 추상 클래스에 선언 하였다.

 

 만약 행동의 메소드명은 동일하지만, 내용이 다를 경우는 어떻게 해야 할까?

예시를 위해 모든 몬스터들은 스킬을 사용한다고 가정한다.

  1. A 몬스터는 불 스킬을
  2. B 몬스터는 얼음 스킬을
  3. C 몬스터는 번개 스킬을 사용한다고 가정하였을 때,

몬스터 클래스에는

public abstract void 스킬();

의 추상 메소드를 선언하여, 몬스터를 상속받는 클래스들에서, 스킬이라는 메소드를 정의 하도록 할 수 있다.

 

몬스터 클래스를 상속받는 자식 클래스들의 경우,

@Override
public void 스킬(){
	불 스킬		 //A몬스터
    얼음 스킬		//B몬스터
    번개 스킬		//C몬스터
}

메소드를 오버라이딩하여, 실행 내용을 각 개체의 특성에 맞춰 사용할 수 있다.

 

즉 추상 메소드는 부모되는 클래스에서 메소드의 이름, 리턴값, 매개변수만 정해두고, 자식 클래스에서는 그 메소드를 활용하여 실행내용을 각 객체에 맞춰 작성하여 사용하는 것이다.

 

 

인터페이스

자바에서 인터페이스는 객체의 사용 방법을 정의한다.

개발코드가 인터페이스의 메소드를 호출하면, 인터페이스는 객체의 메소드를 호출한다. 때문에 개발코드는 객체의 내부구조를 알 필요 없이 인터페이스만의 메소드를 이용하여, 객체를 변경 할 수 있다.

 

 인터페이스는 여러 객체들과의 사용이 가능하므로, 어떠한 객체를 사용하느냐에 따라, 실행 내용과 리턴되는 값이 달라 질 수 있다. 즉, 인터페이스를 활용하면, 개발 코드의 변경 없이 실행 내용과 리턴값이 변화가 가능하게 된다.

 

인터페이스 구조

인터페이스는

interface 인터페이스{
	//상수
    인터페이스는 데이터의 저장이 불가능 하기 때문에, 인스턴스 또는 정적 필드를 선언 할 수 없다.
	하지만 인터페이스의 모든 상수는 public static final 필드의 특징을 가지게 된다.
    
    //추상 메소드
    인터페이스를 통해 호출되는 메소드는 객체에서 재정의 되어 실행 되기 때문에 기본적으로
    인터페이스의 메소드는 리턴타입, 메소드명, 매개변수만 작성되고 {}없는 추상 메소드로 작성한다.
    
    //디폴트 메소드
    default 리턴타입, 메소드명, 매개변수 및 실행 블록까지 작성 
    생성자를 통해 실행되는 클래스의 인스턴스 메소드와 동일.
    
    //정적 메소드
    static 리턴타입, 메소드명, 매개변수 및 실행 블록까지 작성
    생성자없이 사용가능한 클래스의 정적 메소드와 동일.

}

들을 포함 할 수 있다.

static으로 선언된 필드는, 정적인 영역에 메모리를 할당하여 선언되기 때문에, 클래스의 로딩이 끝나면 바로 사용이 가능하며, 동일한 클래스로 생성된 객체들 사이에서도 독립적인 값을 같는 것이 아닌 동일한 값을 가지게 된다.
final으로 선언된 필드는, 필드 선언시 또는, 생생될 때 2가지 경우에만 초기값을 지정 할 수 있으며, 초기값을 지정하지 않은 final은 컴파일시 에러를 낸다. 

 

인터페이스의 사용

 인터페이스의 사용에 대해 설명하기 위에 위의 게임에 유저와 레벨 시스템을 추가 하고, 유저와 몬스터 모두 레벨 값을 가지게 되며, 레벨 업을 통해 능력치의 상승을 할 수 있다고 가정한다.

public class 유저{
	private int 레벨;
    private int 체력;
    private int 공격력; 
    private int 방어력;
}

먼저 유저 클래스에 대한 정의를 하고,

public interface 레벨{
	void 레벨업();
}

레벨 인터페이스를 정의 한다. 유저의 경우 레벨업을 통해, 모든 능력치가 상승 하도록, 몬스터는 랜덤한 능력치가 상승하도록 만들기로 한다.

public class 유저 implements 레벨{
	private int 레벨;
    private int 체력;
    private int 공격력; 
    private int 방어력;
    
    public void 레벨업(){
    	체력++;
        공격력++;
        방어력++;
    }
}
public abstract class 몬스터 implements 레벨{
	private int 레벨;
	private int 체력;
    private int 공격력;
    private int 방어력;
    
    //생성자
    public 몬스터(int 체력, int 공격력, int 방어력){
    	this.체력 = 체력;
        .
        .
    }
    
    ...getter
    ...setter
    
    public void 피격(int 데미지){
    	this.체력 = this.체력 - 데미지;
        if(체력<=0)System.out.println('사망');
    }
    
    public void 레벨업(){
    	랜덤 능력치 상승;
    }
    
}

몬스터의 경우는 상위 클래스인 추상 클래스에 인터페이스를 추가하여, 모든 몬스터에 레벨내용이 적용 될 수 있도록 수정 하였다.

 

추상 클래스와 인터페이스의 차이점

추상 클래스가 어떠한 객체들이 가지는 특성의 동일한 점을 모아 만든 상위 클래스의 개념이라면,

인터페이스는 각 객체들이 가질 수 있는 특성을 사용 할 수 있도록 정의 하는 개념이라고 볼 수 있을 것 같다.                               

'JAVA' 카테고리의 다른 글

[spring boot]이미지 업로드  (0) 2022.03.21
[JPA]REST API 만들기  (0) 2022.03.01
OracleDB - JAVA  (0) 2021.09.22
<Maven 라이브러리> apache.poi 이용해서 엑셀 파일 읽어오기  (0) 2021.09.14