추상화

haribo·2021년 2월 27일
0

Java

목록 보기
7/17

Why?

육군, 공군, 해군이 나오는 K전투 게임개발을 하고 있던 개발자 A씨. 군인들은 모두 공격을 수행하니까 attack이라는 부모클래스의 메서드를 상속받아 오버라이드한 뒤 처리하는 것이 옳다고 우린 앞의 상속에서 배웠다. 하지만 A씨는 상속을 그냥 잊고 본인 마음대로 클래스의 메서드 이름을 att, attn, atta 이런식으로 지정하여 만들었다. 그리고 A씨는 몇달 뒤 자유를 찾은 도비가 되었고, 다른 개발자인 B씨가 입사하게 되었다.

A씨의 코드를 보니 B씨는 심란하다. 뭘 이렇게 해놓은거지? 메서드 이름들은 대체 뭘 뜻하는거지? 알수 없는 코드들을 보며 B씨는 유지보수 및 사이드 이펙트에 대해 심각하게 고민하게 된다.

개발자로 일한다는 것은 협업을 한다는 것이다. 나 혼자 만들어서 프로그램을 뚝딱 만들면 좋겠지만 이건 빌딩을 혼자서 공구리질 해가며 짓겠다는 것과 유사한 무모한 느낌을 준다. 혼자 만들땐 가독성따위 필요없다. 그냥 내 눈에만 잘 보이고, 내 머릿속에서만 잘 돌아가면 되는 것이다. 하지만 여러명과 함께 만들면 우린 규칙이 필요하다. 누가 봐도 읽기 쉽고(다형성), 유지보수(상속성)하기도 쉽게끔 코드를 짜는 것이 옳다는 말이다.

  • 상속성 : 객체간의 공통적인 기능을 관리하기 위한 기법이다. (ex Q&A와 자료실의 게시판 기능을 묶어 부모 클래스로 정의) 짜놓은 코드를 언급하여 재사용하므로 프로그램의 유지보수가 편리해진다. (공통되게 묶어서 정의해놓았기 때문에 기능을 개편할때 부모클래스만 바꿔주면 되니까.)
  • 다형성(오버라이드, 오버로드) : 서로 다른 기능이지만 메서드의 이름을 공통되게 처리함으로써 전체 프로그램의 일관성을 유지하게 한다. (unit의 공격에서 받아온 navy의 공격이 재정의 된것, 파라미터의 자료형이 다 다른 메서드를 여러개 생성하여 그냥 메서드 이름을 치고 넣으면 되게 만든 것 처럼)

<Override와 문제 발생>

  • 오타가 나서 전혀 다른 메서드로 정의되는 것을 방지하기 위해 자식클래스에서 부모클래스의 메서드를 재정의할때 우린 @Override 라는 것을 붙여 방지하기로 했다.
  • 하지만 @Override라는 키워드를 쓴다 하더라도 부모클래스의 메서드를 재정의하지 않았다면 다형성의 구현은 이루어지지 않는다. 사람이니까 깜빡하고 안에 내용을 안채워넣을 수도 있지않은가.

추상화의 이해

기획서를 쓸 때를 생각해보자. 부장님이 자유롭게 써와~ 라고 해서 진짜 자유롭게 써간 신입사원 A씨, 마인드맵도 그리고 보노보노 배경도 넣고 심각한 혼종을 만들어 왔다고 치자. 보고서를 받아든 부장님의 얼굴이 덩달아 심각해진다. 음... 진짜 자유롭게 써왔네? 하고 눈치를 주며 다시 써오라며 재지시를 받은 A씨는 대체 부장님이 원하는게 뭘까 궁금하고 답답해진다.

하지만 여기서 기획서 양식이 있다고 하면 어떨까? 구체적인 가이드라인이 있으니 A씨 입장에서도 채워넣기 한결 쉽고 부장님 입장에서도 내용이 적절하게 들어갔는지 체크할 수 있으니 일석이조다.

추상화는 가이드라인이다. 양식 자체에는 효력이 없지만 내용을 기입하면 효력이 생긴다. 양식에다가 데이터 값을 적어서 배부하는 경우는 없다. 추상화도 마찬가지다. 자체적으로 내용을 생성하는 것은 없이 양식만 준다고 보면 되겠다.

<상속 처리 시 Override를 강제하기>

  • 추상화 기법은 특정 클래스를 상속받은 경우, 부모의 특정 메서드들을 무조건 재정의하도록 강제하는 기법이다. 특정 메서드를 재정의하도록 강제함으로써, 자식 클래스들을 작성하기 위한 가이드 역할, 즉 양식 역할을 할 수 있다.
  • 추상화 기법은 Java 클래스를 작성하기 위한 설계도를 소스코드 형태로 제시하는 역할을 한다. (건축물을 지을때 설계도를 그리지만, 설계도는 건축법에 따라 만들어서 정부의 통과가 되어야 지을 수 있는것처럼. 추상화는 건축법이라고 봐도 무방하겠다.)

<추상 메서드 만들기>

// 선언만 가능하고, 구현부를 위한 블록이 존재하지 않는다.
public abstract void sayHello();
  • 추상 메서드를 하나 이상 포함하고 있는 클래스는 반드시 '추상 클래스'로 정의되어야한다.
// 추상 클래스 정의
public abstract class Hello {

	// 선언만 가능하고, 구현부를 위한 블록이 존재하지 않는다.
	public abstract void sayHello();
}
  • 추상 클래스는 객체를 생성할 수 없다. (양식에 데이터 값을 다 써놓고 주는 것이나 마찬가지) 반드시 상속을 통해서만 사용할 수 있다. 자식 클래스의 가이드라인이다.
  • 추상 클래스는 생성자, 멤버변수, 일반 메서드등을 포함할 수 있다.
  • 즉 공통 기능과 가이드라인을 모두 정의하여 다른 클래스에게 상속된다.

<실습 01>

public abstract class Unit {
	private String name;
	
	public Unit(String name) {
		super();
		this.name = name;
	}
	
	/** getter, setter */
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	// 자식들이 재정의할 메서드를 추상으로 명시
	public abstract void attack();
	
	public abstract void move();
	
}
/**
 * 추상 클래스를 상속받으면 자식은 부모의 모든 추상 메서드를
 * 재정의 해야 한다.
 */

public class Army extends Unit {

	public Army(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void attack() {
		System.out.println(this.getName() + " >> 육상공격");
		
	}

	@Override
	public void move() {
		System.out.println(this.getName() + " >> 육상이동");
		
	}

}
public class Navy extends Unit {

	public Navy(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println(this.getName() + " >> 해상공격");

		
	}

	@Override
	public void move() {
		System.out.println(this.getName() + " >> 해상이동");

		
	}
	

}
public class AirForce extends Unit {

	public AirForce(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println(this.getName() + " >> 공중공격");

		
	}

	@Override
	public void move() {
		System.out.println(this.getName() + " >> 공중이동");

		
	}
	

}
public class Main01 {
	public static void main(String[] args) {
		Army army = new Army("육군");
		Navy navy = new Navy("해군");
		AirForce air = new AirForce("공군");
		
		// 다형성이란, 객체의 이름이 서로 다르더라도 -
		// 객체의 메서드를 호출할 때 고민하지 않기 위한 기법이다.
		// 추상화는 다형성을 강제하는 것으로 -
		// 객체를 사용하는 개발자의 편의를 위한 클래스 작성 규칙이다.
		
		army.move();
		army.attack();
		
		navy.move();
		navy.attack();
		
		air.move();
		air.attack();
		
	}

}
이 포스트는 itpaper.co.kr에서 제공되는 강의자료를 바탕으로 작성되었습니다.
profile
그림 그리는 백엔드 개발자

0개의 댓글