2013년 10월 31일 목요일

자바 추상 클래스와 추상 메쏘드(Java Abstract Class, Abstract Method)


자바 추상 클래스와 추상 메쏘드(Java Abstract Class, Abstract Method)
 
Abstract 클래스

객체를 생성할 수 없다
어떠한 클래스를 만들기 위해 미리 정의해 둔 클래스의 틀.
 앞에서 작성한 Employee(직원)클래스와 직원의 하위 클래스를 예로 든다면 직원이라는 클래스는 프로그래머(Programmer), 디자이너(Designer) 등을 만들기 위해 작성된 클래스라고 할 수 있다. 사실 직원이라는 클래스는 실제 회사의 프로그램을 개발한다고 했을 때 사용해서는 안 되는 클래스라고 할 수 있다. 왜냐하면 A라는 회사에 직원 중 어느 부서에 해당되지 않고 자기 마음대로 회사를 출근하고 퇴근하는 직원은 존재하지 않을 것이기 때문이다. 하지만 Employee 라는 클래스가 존재하는 이상 일반 사용자에게 메뉴얼을 작성해 “Employee 클래스는 다른 특정직원 클래스를 만들기 위한 클래스입니다.”라고 하기 전에는 Employee의 본래의미를 모르고 Employee 의 객체를 생성하여 사용할 수 있다. 즉 다음과 같은 소스 코딩을 막을 수 없다.
         Employee e = new Employee("홍길동", “12345");        
         s1.gotoTheOffice();

만약 Employee 클래스는 사용하기 보다는 다른 클래스에 상속하여 새로운 직원 클래스를 만드는 것이 바람직하다는 의미를 소스 코드에 부여한다면 개발자의 Employee 클래스 개발 의도를 사용자가 쉽게 알 수 있게 될 것이다. 이 때 사용되는 키워드가 abstract 키워드이다. 이 키워드가 클래스에 붙으면 이 클래스는 추상클래스라는 의미이다
앞서 작성한 Emplopyee 클래스에는 없지만 이를 상속받은 모든 클래스에서 정의하고 재정의하여 사용하고 있는 startJob 이라는 메소드를 Employee에서 추상메소드로 선언하여 정의할 수 있다
상속의 개념으로만 본다면 이러한 추상클래스는 굳이 만들 필요가 없다. 추상클래스가 아니더라도 위와 같은 상속과 메소드의 재정의는 얼마든지 가능하기 때문이다. 하지만 수퍼타입(super type)을 이용한 다형성(Polymorphism)의 측면에서 추상클래스(Abstract Class)는 유용하게 쓰일 수 있다.

A라는 직원이 회사에 입사했는데 처음에는 디자인팀에 있다가 얼마 후 프로그램개발팀로 소속을 옮기게 되었다. 그러다가 경력을 쌓아 프로그램개발팀장으로 까지 진급하게 되었다. 이렇게 한 사람의 직원은 시간에 따라 때로는 상황에 따라 여러가지 모습으로, 여러가지 업무를 담당하게 된다. 바로 이런 것을 가능하도록 객체를 설계하는 것이 바로 다형성의 구현이다. 즉 실생활의 회사 직원처럼 상황과 시간에 따라 여러가지 모습을 지니는 다형성을 구현할 수 있게 되는 것이다. 모든 직원의 하위클래스들을 수퍼 타입(상위클래스)로 형변환하면 가능하다.
적어도 하나의 추상 메소드(abstract method)를 가진다.
추상 메소드란 메소드 이름은 정의되어 있는데 본체는 구현되어 있지 않은 것이다.
클래스가 추상 메소드를 가지면 그 클래스는 abstract 로 선언되어야 한다.
객체가 가지는 특성들을 추상화 했을 뿐 아직 구체화 시키지 못한 클래스 이므로 이 추상 클래스를 상속하는 하위클래스에서 구체화 시키도록 하는 것이다.
만약 어떤 추상 클래스를 상속한 클래스에서 상위 클래스의 추상 메소드를 완전히 구현하지 못했다면 하위 클래스 역시 추상 클래스 이다.
 
[추상 클래스를 이용한 다형성 구현 예제]
 
package onj;
//Employee.java
abstract class Employee {
  String name, id;
  public Employee(String name, String id) {
      this.name = name;   
      this.id = id;
  }
  public void gotoOffice() {
      System.out.println(name+"님 출근하였습니다...");
  }
  public void gotoHome() {
      System.out.println(name+"님 퇴근하였습니다...");
  }
  abstract public void startJob();
}
 
//Programmer.java
class Programmer extends Employee {  
  private int techGrade; //기술자 등급 1, 2, 3, 4
  public Programmer(String newName,String newID, int newTechGrade) {
         super(newName, newID);       this.techGrade = newTechGrade;
  }
  public void startJob() {
 System.out.println(super.name + " 님이 S/W개발업무를 시작합니다.");
  }
 public void dispGrade() {
 System.out.println(super.name + " 님 기술자 등급 : " + techGrade);
 }
}
 
//Designer.java
class Designer extends Employee {   
  private String majorTech; //주 사용기술
  public Designer(String newName,String newID, String newMajorTech) {
      super(newName, newID);      this.majorTech = newMajorTech;
  }
  public void startJob() {
      System.out.println(super.name + " 님이 디자인 업무를 시작 합니다.");
  }
 public void dispMajorTech() {
      System.out.println(super.name + " 님의 주 사용기술은 : " + majorTech );
 }
}

//Polymorphism.java
class PolymorphismTest {
  public static void main(String args[]) {          
    Employee p = new Programmer("오엔제이","028514790",1);
    Employee d = new Designer("오라클자바커뮤니티","028514790","오라클자바");
    p.gotoOffice(); p.startJob();
    p.gotoHome(); ((Programmer)p).dispGrade();
    d.gotoOffice(); d.startJob();
    d.gotoHome(); ((Designer)d).dispMajorTech();
  }
}

[결과]

오엔제이님 출근하였습니다...
오엔제이 님이 S/W개발업무를 시작합니다.
오엔제이님 퇴근하였습니다...
오엔제이 님 기술자 등급 : 1
오라클자바커뮤니티님 출근하였습니다...
오라클자바커뮤니티 님이 디자인 업무를 시작 합니다.
오라클자바커뮤니티님 퇴근하였습니다...
오라클자바커뮤니티 님의 주 사용기술은 : 오라클자바

댓글 없음:

댓글 쓰기