3.1 객체지향언어

작성자 : 진은영 ( 2004-07-07)

[메인] [목록]

목차

3.1.1 객체지향언어란

① 객체란
자바가 객체지향언어라는 것은 앞 강좌에서 말을 했을 것이다. 객체지향 언어를 이해하기 위해서는 먼저 객체에 대해 알아야 한다.
우리 주변을 둘러보면 여러가지 물건들이 보일것이다. 여러분이 사용하고 있는 컴퓨터, 또는 옆에 펼쳐져 있는 여러 책들, 마우스 , 스피커등등 이 모든것들을 객체라고 할 수 있다.

이러한 실세계에 존재하는 객체는 다음과 같은 두 가지 구성요소를 갖는다.

  • 상태(state): 객체가 가지고 있는 속성 또는 특성
  • 행동(behavior): 객체가 가지고 있는 기능 또는 할 수 있는 행동

예를 들어,
실생활에 존재하는 자동차 객체는 색, 네 개의 바퀴, 핸들, 배기량, 현재 속도, 현재 기어 위치 등등의 상태를 갖고, 달린다, 멈춘다, 기어를 바꾼다, 속도를 높이거나 낮춘다, 경적을 울린다 등과 같은 행동을 할 수 있다.

② 객체지향언어란
이러한 실세계의 객체를 소프트웨어적으로 표현하기 위한 방법 중의 하나가 객체지향 방법이다.
따라서, 소프트웨어 객체는 실세계의 객체가 갖는 구성요소를 모두 표현할 수 있어야 한다.

이를 위해 객체지향 방법을 이용하여 실세계의 객체가 갖는 상태(state)와 행동(behavior)을 소프트웨어 객체의 변수(variable)와 메소드(method 또는 function)로 모델링하게 된다. 그리고, 이 상태를 나타내는 변수들과 상태를 변경해 주는 행동을 구현한 메소드(또는 함수)를 하나로 어줌으로써 실세계의 객체를 소프트웨어 객체로 모델링하고 구현할 수 있다.

이러한 객체지향 방법에서 나타나는 중요한 특징 3가지가 있다.

  • 캡슐화(Encapsulation)
  • 상속(Inheritance)
  • 다형성(Polymorphism)

위의 특징들과 형태를 문법적으로 표기한 것을 클래스라고 한다.

② 객체지향언어를 생성하기 위해서는
객체지향 언어를 생성하기 위해서는 아래와 같은 순서로 작성한다.



3.1.2 클래스란

클래스는 객체의 상태와 행동들을 정의한 문서이다. 또한 클래스는 자바의 객체지향 프로그래밍의 기초를 형성한다.
클래스의 형식은 아래와 같다.


① package
클래스를 사용하다보면 워낙 많기 때문에 서로 관련이 있는 것끼리 묶어야 할 필요가 있다. 패키지는 클래스들의 묶음이라고 생각하면 된다. 클래스를 선언할 때 패키지를 맨 처음에 넣는것은 생성할 클래스의 위치를 어디에 놓겠는가를 결정하기 위해서이다.
또한 현 디렉토리에 클래스를 선언하고 싶다면 패키지는 생략해도 상관없다.
package kr.co.a ;

패키지는 트리형태의 계층적 구조를 가진다. 예를 들어 패키지 명이 kr.co.a 라면 아래와 같은 구조를 가진다.


  • 패키지는 전부 소문자로 기입한다.
  • 유일한 값(ex. 도메인)을 넣어야 나중에 참조할 때 충돌할 염려가 없다.

② import
클래스에 다른 클래스를 참조하고 싶을때 사용하며, 현 클래스가 저장하는 폴더(패키지)에 없는 클래스라면 해당 클래스가 있는 패키지명을 입력해줘야 참조할 수 있다.
import java.io.*;
여기에서 "*" 기호는 java.io 패키지안에 있는 모든 클래스를 참조한다는 뜻이다.
혹은 아래와 같이 참조할 수 도 있다.
import java.io.FileInputStream ;
java.io 패키지에 있는 FileInputStream 클래스만 참조한다는 뜻이다. * 를 쓰는것 보다 참조하려는 클래스를 바로 import 하는것이 성능면에서는 더 좋다.
여러 패키지를 참조하려면 아래와 같이 기입한다.
import java.util.Vector ;
import java.io.FileInputStream ;
참조할 패키지가 없으면 생략할 수 있다.

③ class
클래스 선언의 기본적인 형태는 아래와 같다. [] 는 생략가능하다는 뜻이다.


  1. 접근제한자 : 외부에서 이 클래스에 접근할 수 있는 권한을 부여한다. 클래스에서 사용되는 접근제한자는 아래와 같다.
    • public : 어느 클래스에서라도 접근할 수 있다.
    • abstract : 불완전한 클래스로 직접 객체를 생성할 수 없는 클래스이다.
    • final : 상속을 할 수 없는 클래스이다.
    • default : 접근제한자를 생략할 수 있으며 같은 패키지에서만 접근할 수 있다.
      public class A{}
      abstract class B{}
      final class C{}
      class D{}

  2. 클래스이름 : 이 클래스을 지칭하는 이름을 부여한다. (강좌 2_1 Identifier 참조)
    • 첫자는 대문자로 시작하고 한단어 이상 나열되는 경우 시작하는 첫자를 대문자로 기입한다.
      class Account{}
      class AddressBook{}
      class StockAccountManager{}
      반드시 위와 같이 작성해야 하는것은 아니고 권장사항이다.

  3. extends : 상속받는 클래스가 있다면 클래스 이름을 나열한다. (나중에 자세히 설명)
      class StockAccountManager extends AccountManager {}

  4. implements : 참조할 인터페이스가 있다면 인터페이스 이름을 나열한다. (나중에 자세히 설명)
      class StockAccountManager implements Account {}

④ 멤버변수
추상화를 거쳐 생성된 속성은 클래스 정의에서 멤버번수(member variable)로 표현된다. 멤버변수란 클래스 안에서 속성을 정의하기 위해 선언되는 변수이다.


  1. 접근제한자 : 멤버변수에 접근할 수 있는 권한을 부여한다.
    • public : 모든 클래스 및 패키지에서 접근이 가능하다.
    • private : 해당 클래스내에서만 접근이 가능한다. 가장 제한적인 방법이다.
    • protected : 같은 패키지 내에서는 접근이 가능하며 상속을 받았을 경우 다른 패키지에서도 접근이 가능하다.
    • default : 같은 패키지 내에서는 접근이 가능하다.
    • static : 클래스 단위로 존재하는 변수로 모든 객체가 공동으로 사용한다.
    • final : 값을 변경할 수 없다.
      class StockAccount {
          //멤버변수 선언
          private String accountNum ; 
          int age ;
          public static String name ; 
          public final int num =10 ;
      }
      

  2. 데이터 타입 : 강좌 2-2 Data Type에서 지정한 모든 타입이 올 수 있다.
      이름속성: 문자 => String
      나이속성 : 숫자 => int

  3. 변수명 : 변수(속성)에 해당하는 이름을 부여한다. (강좌 2_1 Identifier 참조)
    • 첫자는 소문자로 시작하고 한단어 이상 나열되는 경우 두번째 시작하는 첫자를 대문자로 기입한다.
      이름속성 : name
      계좌번호속성 : accountNum
      자동차이름 : carName

  4. 변수값 : 멤버변수는 값을 따로 넣지 않아도 default값이 채워진다.
    default값은 강좌 2-2 Data Type를 참조한다.
    primitive type을 제외한 나머지의 default값은 null이다.

⑤ 생성자
생성자는 객체를 생성하기 위한 역할을 한다. 나중에 다시 자세히 설명하겠다. 생성자는 생략가능하며 생략하면 default생성자를 자동으로 생성해준다.

⑥ 메소드
객체의 상태를 검색하고 변경하는 작업 , 그리고 특정한 행동을 처리하는 프로그램 코드를 포함하고 있는 함수의 형태를 말한다. 메소드의 형식은 아래와 같다.


  1. 접근제한자 : 메소드에 접근할 수 있는 권한을 부여한다.
    • public : 모든 클래스 및 패키지에서 접근이 가능하다.
    • private : 해당 클래스내에서만 접근이 가능한다. 가장 제한적인 방법이다.
    • protected : 같은 패키지 내에서는 접근이 가능하며 상속을 받았을 경우 다른 패키지에서도 접근이 가능하다.
    • default : 같은 패키지 내에서는 접근이 가능하다.
    • static : 클래스 단위로 존재하는 메소드로 모든 객체가 공동으로 사용한다.
    • final : 상속할 수 없다.
    • synchronized : 하나의 스레드만을 접근할 수 있도록 허용 (나중에 다시 설명)
    • abstract : 추상메소드로 중요한 역할을 한다. 불완전한 메소드를 body가 없이 선언부만 있다. 상속을 받은 클래스는 반드시 재 정의해서 사용해야 한다.(나중에 다시 설명)
      public void a(){}
      public final void b(){}
      public abstract void a ;

  2. 리턴타입 : 반환되는 자료형은 이 메소드를 그냥 실행만 할 것인가 그렇지 않으면 실행한 후 호출한 곳으로 값을 전달한것인가를 결정한다.
    • 리턴타입이 없는 경우 : void
    • 리턴타입이 있는 경우 : 보내려는 값의 Data Type을 기입한다. 그리고 받드시 메소드의 끝에 return구문이 나오며 보내려는 값을 기입한다.
      public void a(){}
      public int b(){
         return 1 ;
      }
      public String b(){
         return "이름" ;
      }


  • 메소드 이름을 신중하게 결정해야 한다. 이해하기 쉽고, 같은 패키지에 있는 다른 클래스나 인터페이스들과 일관성 있는 이름을 짓도록 우선 노력해야 한다. 그 다음으로 좀 더 넒은 세계에서 공감을 얻을 수 있게 이름을 짓도록 노력해야 한다.
  • 매개변수는 적을수록 좋다. 현실적으로 인자 개수가 세 개를 넘으면 문제가 있다고 본다. 특히 동일한 타입의 인자가 죽 이어져 있으면 훨씬 더 위험하다.

3.1.3 회사 사원 클래스 생성 예제

① 추상화
"잘팔자" 회사의 회원관리 프로젝트 의뢰를 받았다. 회원들을 관리하기 위해서는 회원객체를 생성해야 한다. 회원객체를 생성하기 위해서는 추상화를 거쳐야 한다. 추상화란 회원객체에 필요한 속성과 행동 (멤버변수 , 메소드)를 추출하는 것이라고 했다.
멤버변수 : 사번 , 이름 , 직위 , 기본급
멤버메소드 : 회원내용출력 , 급여계산
위와 같은 것을 필요로 하겠다. 물론 더 많은 내용이 있겠지만 여기에서는 간단하게 이것만 사용하겠다.

② 클래스 구현
위의 내용을 클래스로 구현해 보자
public class Employees {
        
        //멤버변수 선언
        private String empID ; 
        private String name ; 
        private String position ; 
        private int salary ; 

        //메소드 선언
        public void print(){}

        public int calSalary(){}
}
  1. 클래스명을 Employees라 선언하고 접근제한자를 public을 주었다. : 어디에서나 접근이 가능하게 하겠다
  2. 변수를 각각 선언하고 값을 대입하지 않았다. : 디폴트값이 묵시적으로 적용된다.
  3. 변수의 접근제한자를 private으로 선언했다. : 같은 클래스내에서만 접근이 가능하다.
  4. 생성자가 없다 : 생성자를 생략하면 default생성자를 컴파일시에 만들어준다.
  5. print()에서 리턴타입이 void이다. : print()메소드를 호출해서 실행만 하겠다.
  6. calSalary()에서 리턴타입이 int이다. : calSalary()를 호출하여 실행한후 다시 호출한 곳으로 결과값을 보내겠다.
참고문헌
  • JAVA Programming [아이티씨]
  • 클릭하세요 자바 2 [대림]
  • Effective Java [대웅미디어]