오브젝트 파스칼
오브젝트 파스칼(Object Pascal)은 기존의 파스칼(Pascal) 언어에 객체 지향 개념을 포함하여 발전시킨 프로그래밍 언어 이다. 주로 델파이(Delphi) 언어로도 잘 알려져 있다.
개요
오브젝트 파스칼은 애플 매킨토시의 전신인 애플 리자용으로 개발한 오브젝트 파스칼 컴파일러가 시초이며 가장 널리 알려진 오브젝트 파스칼의 변종은 볼랜드/코드기어 사의 델파이에서 사용되는 델파이 프로그래밍 언어가 있다. 델파이에서 사용된 오브젝트 파스칼은 표준 파스칼에 비해 많은 진보가 있는 언어이다. 파스칼은 최초의 탑,다운(top-down) 디자인과 구조적 프로그래밍을 가르치기 위해 개발된 언어이다. 그렇기 때문에 가장 많은 수의 대학에서 프로그래밍 언어의 표준으로 이를 이용해 강의하곤 했다. 그러던 중 볼랜드가 터보 파스칼을 발표하게 되었고 이해하기 어려운 C 코드에 비해 직관적이면서도 깨끗한 터보 파스칼은 당시에 상당한 반향을 일으키며 터보 C 와 함께 시장의 양대 언어로 자리 잡았다. 파스칼이 객체지향형 프로그래밍 언어의 기능을 추가하게 된 것은 터보 파스칼 5.5버전으로, 이때부터 조금씩 진보된 환경에서 변화를 시도했다. 이후 델파이 1.0이 발표되면서 명실상부한 객체지향형 파스칼로서 세상에 모습을 드러내게 된다.[1] [2]
특징
- 클래스 및 객체
클래스는 일종의 데이터형이며, 객체는 클래스가 실제로 메모리에서 인스턴스(instance)화 된 것이다. 오브젝트 파스칼과 씨플플(C++), 자바(Java)는 모두 클래스에 바탕을 둔 언어다. 각각의 객체들은 직접 정의되지 않고, 일단 클래스로 정의된 후 객체는 클래스에 대한 한의 인스턴스(instance)로 나타나는 형태를 가지고 있다. 클래스는 객체와 일 대 엔(1:n)의 관계를 맺게 된다. 클래스는 코드를 메소드의 형태로 저장하며, 여러 객체들과 이를 공유하게 된다. 각 객체는 자신의 데이터 필드를 저장하게 되며, 이것으로 클래스와 객체가 구별된다. 객체 내의 필드는 원시적인 데이터형이거나 객체일 수 있다. 정상적으로 각 객체는 클래스에서 선언된 데이터 필드의 복사본을 자신의 것으로 가지고 있다. 오브젝트 파스칼은 동적(dynamic) 객체만을 지원한다. 로컬, 전역 객체가 선언될 수 있지만, 이들은 단지 레퍼런스로서 데이터 세그먼트나 스택에 저장된다. 객체 자체는 반드시 직접 생성해서 항상 힙에 저장해야 한다. 오브젝트 파스칼은 기본적으로 사용자 정의 메모리 할당 루틴을 제공하지는 않는다. 그렇지만, 자동 garbage cllection 은 지원하지 않으므로, 프로그래머가 각 개체를 동적으로 생성한 경우 이를 제거할 필요가 있다.[3]
- 생성자
프로그래밍 언어에서 생성자(Constructors)는 객체를 초기화하게 된다. 오브젝트 파스칼에서는 콘스트럭터(constructor)라는 키워드를 사용해서 생성자를 정의한다. 메소드 오버 로딩(overloading)을 지원하지 않지만, 생성자가 여러 가지 이름을 가질 수 있어서 여러 개의 생성자를 가질 수 있다. 오브젝트 파스칼에서는 각각의 클래스가 디폴드 크리에이트(Create) 생성자를 가지고 있게 되는데, 이 생성자는 기본적인 기초 클래스에서 상속받게 된다.[3]
- 파괴자
파괴자(Destructor)는 생성자와 반대되는 일을 한다. 즉, 객체가 메모리에서 해제될 때 호출되며 생성자에 의해 할당된 리소스를 해제하는 역할을 하게 된다. 오브젝트 파스칼의 파괴자는 표준 가상 파괴자인 디스트로이(Destroy)를 이용하는데, 이 파괴자는 자유(Free) 메소드에 의해 호출된다. 모든 객체가 동적으로 처리되기 때문에, 일단 객체가 생성되면 그 객체의 소유주(owner) 객체가 파괴될 때 자동으로 자유 메소드가 호출된다. 이론적으로 여러 개의 파괴자를 선언할 수 있다.[3]
- 클래스 캡슐화
클래스 캡슐화의 레벨을 지정하는 지시어로 프라이베이트(private), 프로텍티드(protected), 퍼블릭(public)이 사용된다. 프라이베이트, 프로텍티드 키워드는 다른 유닛일 경우에는 접근할 수 없지만 같은 유닛(같은 소스 코드 파일)에 있으면 접근이 가능하다. 그밖에, 디자인 시에 필드의 값을 보고, 편집할 수 있는 프로퍼티를 제공한다. 프로퍼티는 간접적으로 객체의 필드에 접근하기 때문에, 캡슐화 개념을 충실하게 지키고 있다. 프로퍼티는 데이터 필드에 대한 단순한 레퍼런스일 수도 있고, 참조 무결성을 유지하는 등의 보다 여러 가지 조작을 가할 수 있는 함수를 호출하는 것일 수도 있다.[3]
- 유닛 패키지
오브젝트 파스칼의 경우에는 각각의 소스 코드 파일을 유닛이라고 한다. 이러한 유닛은 크게 나누어 인터페이스(interface), 임플러먼테이션(implementation) 이라는 2개의 파트로 이루어져 있다. 인터페이스는 클래스의 정의와 메소드에 대한 선언 부분을 포함하며, 임플러먼테이션은 인터페이스에서 선언한 메소드의 구현 부분이 위치하게 된다. 다른 파일에서 선언된 인터페이스 부분을 유즈(uses) 키워드를 통해 접근할 수 있다.[3]
- 메소드 및 데이터
객체지향 언어는 일반적으로 특정 객체에만 해당하지 않고, 클래스에 전반적으로 적용할 수 있는 메소드와 데이터를 허용한다. 클래스 메소드는 클래스의 객체와 클래스 자체에서 호출할 수 있으며, 클래스 데이터는 각각의 객체에 의해 복제되지 않고, 공통으로 사용되는 데이터를 말한다. 이들은 다른 말로 정적 메소드(static method), 정적 데이터(static data)라고도 한다. 오브젝트 파스칼은 클래스 메소드만 지원한다. 클래스 메소드는 클래스(class) 키워드에 의해 지정될 수 있다. 클래스 데이터는 직접 지원하지 않고, 대신 클래스를 정의한 유닛에 프라이베이트 전역 변수를 추가해서 이 기능을 대치한다.[3]
- 전체 클래스
일부 객체지향 언어에서는 최소한 하나의 기초 클래스를 가지는 경우가 있다. 이러한 클래스는 모든 클래스에서 동일하게 가져야 하는 기본적인 특징 들을 가지고 있다. 즉, 모든 클래스는 가장 기본적인 기초 클래스를 상속받는 것이다. 이러한 개념은 스몰토크에서부터 시작된 것으로 비교적 많은 객체지향 언어에서 채택되고 있는 방식이다. 오브젝트 파스칼은 티오피젝트(TObject) 클래스를 공통의 조상으로 가진다. 오브젝트 파스칼은 기본적으로 다중 상속을 지원하지 않기 때문에, 상당히 커다란 상속 트리를 가지게 된다. 티오피젝트 클래스는 알티티아이(RTTI)를 사용할 수 있으며, 그 밖에 몇 가지 기본적인 특징을 가진다.[3]
- 하위형 호환형
오브젝트 파스칼은 비교적 형 검사가 엄격한 편이다. 이는 기본적으로 서로 다른 클래스의 객체들간의 형-호환성(type-compatibility)이 보장되지 않는다는 것이다. 이러한 규칙의 예외가 있는데, 특정 클래스를 상속한 클래스의 객체는 부모 클래스와 데이터형의 호환성이 인정된다. (역은 성립하지 않는다.),이러한 하위형 호환성은 다형성(polymorphism)과 레이트 바인딩(late binding)을 지원하는 데 중요한 역할을 한다. 오브젝트 파스칼은 모든 객체에 대해서 하위형 호환성을 지원한다. 이것이 가능한 이유는 객체 참조 모델을 사용하기 때문이다. 오브젝트 파스칼의 예를 들면, 모든 객체는 티오비젝트 클래스와 호환된다. 또 한 메소드를 디스패치할 때 정적, 동적 바인딩을 모두 지원한다. 정적 바인딩은 다형성을 지원하지 않으며, 컴파일 시에 동작하며 전통적인 함수 호출에서 사용되는 방식이다. 정적 메소드의 주소는 링커에 의해 코드 세그먼트에 직접 저장된다. 이에 비해 동적 바인딩 또는 가상 메소드는 다형성을 지원한다. 이를 위해 객체의 정확한 데이터형을 모르는 런타임에서 동작하게 된다. 오브젝트 파스칼은 가상 메모리 테이블(VMT)을 통해 가상 메소드의 주소를 저장한다. 각 클래스는 자신의 가상 메모리 테이블을 가지게 되며, 가상 메모리 테이블에 있는 함수 주소의 배열을 이용한다. 가상 메소드는 이 주소를 직접 이용하므로 동작하는 속도는 그렇게 느리지 않다. 오브젝트 파스칼은 명시적으로 가상으로 선언한 메소드만 다형성을 지원한다. 이는 하이브리드 언어라면 조상 언어의 호환성을 유지해야 하며, 성능상의 문제가 있다. 부모 클래스의 메소드를 새롭게 정의한 클래스가 있을 때, 일반적인 객체에 대하여 그 메소드를 호출할 때 적절한 클래스의 메소드가 호출되는 특징을 다형성이라고 한다. 이를 지원하려면 지원한 하위형 호환성이 매우 중요한 역할을 하게 된다. 컴파일러는 다형성을 지원하기 위해서 레이트 바인딩이라는 기법을 사용하게 되는데, 이것은 특정 함수를 호출하지 않고 런타임에서 객체가 실제로 어떤 클래스의 함수를 호출하게 될지를 알아낸 후에 호출된 함수를 결정하는 방식이다. 오브젝트는 파스칼의 경우에는 디폴트는 일리 바인딩(early binding)이다. 그런데, 오브젝트 파스칼은 버추얼(virtual) 키워드로 지정하는 가상 함수 외에 동적(dynamic) 키워드로 지정하는 동적 함수가 지원된다. 오버라이드(override) 키워드를 사용해야만 이들 가상 함수를 재정의 할 수 있다. 이러한 오버라이드 키워드의 의미는 지정한 메소드만 컴파일러가 다시 검사하게 되는 것이다. 이런 방법으로 비교적 효율적인 퍼포먼스를 유지할 수 있다. 또한, 오브젝트 파스칼에서는 가상 생성자(virtual constructor)를 정의할 수 있다. 오브젝트 파스칼은 가상 메소드 이외에 동적 메소드를 지원한다. 이 메소드는 원래 윈도의 메시지를 사용하기 위해 고안된 것이다. 즉, 수백 개가 넘는 윈도 메시지를 처리할 때에는 이들 각각에 대한 가상 메모리 테이블을 관리한다는 것은 메모리 공간의 낭비가 될 수 있음으로, 동적 메소드 테이블(Dynamic method table, DMT)을 통해 오버 라이드된 메시지 핸들러에 대한 주소만 관리함으로써 이러한 오버헤드를 줄일 수 있다. 그렇지만, 아무래도 수행능력이라는 측면에서는 다소 핸디캡을 가지고 있다고 본다.[3]
- 추상 메소드
비교적 복잡한 클래스 구조를 만들 때에는, 프로그래머가 다형성을 지원하는데 유리하도록 실제로 구현되지 않는 메소드를 선언할 필요가 있을 수 있다. 이러한 메소드를 추상 메소드(abstract method)라고 하며, 이러한 추상 메소드를 하나 이상 가지고 있는 클래스를 추상 클래스라고 한다. 오브젝트 파스칼은 추상 메소드를 가지고 있는 추상 클래스의 인스턴스(instance)를 생성하는 것이 가능하다. 그렇기 때문에, 프로그램이 추상 메소드를 호출할 가능성도 있는데 이렇게 되면 런타임 에러가 발생하게 된다.[3]
- 다중상속
일부의 객체지향 언어는 하나 이상의 기초 클래스를 상속 받을 수 있다. 이를 다중상속(multiple inheritance) 이라고 한다. 그에 비해 다른 언어에서는 오직 하나의 클래스만 상속받을 수 있지만, 옵션으로 다중 인터페이스나 순수한 추상 클래스(클래스의 순수한 추상 함수로만 이루어진 경우)들을 상속 받아 다중상속의 기능을 대치한다. 오브젝트 파스칼은 다중상속을 지원하지 않고, 다중 인터페이스를 지원한다. 이를 이용해서 다형성을 구현할 수 있으며, 이런 특징을 바탕으로 COM 모델에 적합한 언어환경이 지원된다. 오브젝트 파스칼은 자바보다 더욱 씨오엠(COM)에 가까운 인터페이스 모델을 가지고 있다.[3]
- 알티티아이(RTTI)
런타임 타입 아이덴티피케이션/인폴메이션(Runtime Type Identification/information), 형 검사가 엄격한 객체지향 언어는 컴파일러가 이러한 형 검사를 해주어야 한다. 그러므로, 실행 중인 프로그램에는 클래스와 데이터 형에 대한 정보가 벼로 필요없다. 그러나, 어떤 경우는 이러한 데이터 형에 대한 정보가 필요한 경우가 있는데, 이런 경우를 위해 각 언어들은 정도에 차이는 있지만 알티티아이를 지원하고 있다. 오브젝트 파스칼은 가장 광범위한 알티티아이 정보를 제공한다. 이를 이용해서 단순한 데이터형 검사와 다운캐스트(downcast)를 할 수 있으며 더 나아가서는 퍼빌리쉬드(published)로 선언된 요소들을 새로운 알티티아이 정보로 등록할 수도 있다. 프로퍼티와 스트리밍 메커니즘(폼 파일 등의)과 오브젝트 인스펙터로 표현되는 델파이의 환경은 기본적으로 이런 알티티아이가 있기에 가능한 것이다. 델파이 클래스의 기초 클래스인 티오피젝트 클래스에는 클래스네임(ClassName), 클래스타입(ClassType) 메소드가 있는데, 클래스타입 메소드를 사용해서 특정 객체의 클래스에 대한 참조 값을 돌려 받을 수 있다. 이 메소드를 통해서 반환되는 클래스 형은 티클래스(TClass)로 이 클래스는 티오비젝트의 클래스로 선언되어 있는데, 이는 이렇게 티클래스 형으로 반환된 클래스는 반드시 사용되기 전에 특정 클래스로 형 변환되어야 한다는 것을 의미한다.[3]
- 예외처리
예외처리란 프로그램의 에러 처리 부분을 보다 손쉽게 하기 위해, 언어에서 제공하는 표준 메커니즘을 말한다. 예외처리 방식은 언어들 마다 비슷하지만, 내부 동작에는 다소간의 차이가 존재한다. 오브젝트 파스칼은 레이즈, 트라이, 엑셉트(raise, try, except) 키워드를 사용한다. 씨플플(C++) 과의 차이점은 기본적으로 스택에 객체에 대한 메모리가 할당됭 있지 않기 때문에, 스택을 처리할 필요가 없다는 것이다. 또한, 파이널리(finally) 키워드를 지원하며 델파이의 모든 예외 클래스는 엑셉션(Exception) 클래스를 상속한다.[3]
- 그 밖의 특징
오브젝트 파스칼은 클래스 참조를 지원하기 때문에, 메소드 포인터를 아주 쉽게 사용할 수 있다. 이러한 메소드 포인터는 이벤트 모델의 기초가 되며, 이를 프로퍼티로 사용할 수 있다. 프로퍼티는 메소드가 데이터에 접근하는 방법을 숨겨주는 방법으로 사용되는데, 데이터를 직접 읽거나 쓸 수도 있고, 접근 메소드(access method)를 사용해서 데이터르 조작하는 방법도 가능하다. 데이터에 접근하는 방법을 바꾸더라도 코드를 호출하는 방법을 바꿀 필요가 없기 때문에, 재사용성이라는 측면에서 대단히 유용하다. 다르게 말하면, 다른 어떤 객체지향 언어보다도 강력한 캡슐화 방법을 지원하는 것이다. 또한, 델파이 4 에서는 그동안 지원하지 않았던 메소드 오버로딩과 파라미터의 디폴트 값도 지원하므로 보다 강력한 언어적 특성을 가지게 되었다.[3]
프로그래밍
문법
- 서식
서식은 선언부와 구현부, 유닛의 참조, 형 정의, 함수의 모양, 루틴의 시작과 끝 등과 같이 언어의 전반적인 골격 구조를 말한다. 아래는 파스칼 유닛의 최소한의 서식이다.
unit Unit1; //유닛의 종류와 이름이다. 이 부분과 인터페이스(interface) 사이에는 주석을 제외하면 아무것도 있어서는 안된다. Interface //선언부이다. 자료형과 변수, 상수를 선언하는 용도로 사용한다. 다른 유닛에서 참조가 가능하다. Implementation //구현부이다. 자료형 선언 및 실제 문장을 작성하는 용도이다. 다른 유닛에 공개하지 않는다. end. //유닛의 끝부분임을 나타낸다. 델파이의 컴파일러는 이 라인 뒷부분은 모두 무시한다.
선언부와 구현부에서는 다른 유닛에 있는 자료를 참조할 수 있는데 이때 유즈(uses)를 사용한다. 유즈는 선언부와 구현부의 가장 윗부분에 위치해야 하며 유즈의 다음 라인부터 실제 내용이 들어간다.[1]
- 문장
문장은 실제로 실행될 루틴(routine)을 말한다. 모든 문장은 문장의 끝을 알리기 위해 마지막에 세미콜론(;)을 붙이고 이것을 보통 한 라인이라고 부른다. 여러 코드 라인을 작성할 경우 필요에 따라 이들을 하나로 묶기 위해 비긴(begin) 과 엔드(end)를 사용한다. 문장은 선언부에는 사용될 수 없고 구현부에서만 사용될 수 있다.[1]
- 식별자
프로그래머가 프로젝트에 사용되는 자료 형, 변수, 상수, 프로시저, 함수 등을 정의할 때 사용하는 이름이다. 식별자의 명명 규칙에는 4가지가 있다. 영문 대소문자, 숫자, '_'만 사용할 수 있다. 그리고 첫 글자는 영문이나 '_'를 사용해야 한다. 길이 제한은 없으나 256자가 넘을 경우 256번째부터의 문자는 무시되며 대소문자를 구분하지 않는다.[1]
- 예약어와 지시어
예약어는 오브젝트 파스칼의 문법에서 사용하기 위해 미리 예약되어 있는 것으로, 예약어와 같은 이름의 선언은 불가하다. 지시어는 사용자가 정의한 식별자를 사용할 수 없는 위치에서 사용된다.[1]
- 숫자와 문자열 표현법
숫자는 소스 코드상에서 숫자는 별도의 예약어 같은 것 없이 그냥 숫자를 그대로 사용하면 되고, 16진수의 경우에는 앞에 달러($)를 붙여서 16진수임을 나타낸다. 실수인 경우는 소수점 이하의 값이 길어지면 지수형식(e)으로 자릿수를 표시한다. 문자열은 작은따옴표(')로 표현한다. 문자열 내에서 작은따옴표를 표기하려면 작은따옴표 두 개를 연속으로 써줘야 한다. 문자 한 글자를 10진수 또는 16진수로 나타내려면 샵(#)과 달러($)를 이용하여 아스키(ASCII)로 표현 할 수 있다.
#13#10 -> 16진수로 표현 -> #$D#$A, #255 -> 16진수로 표현 -> #$FF
문자열과 문자열을 하나로 연결할 때는 플러스(+) 연산자를 이용해서 하나로 이을 수 있다.
'델'+'파'+'이' == '델파이'(단, '-' 연산자는 사용할 수 없음)
문자열 내에서 표준 텍스트가 아닌 아스키 문자를 표현하려면 샵과 플러스를 이용해서 하나로 표현한다.[1]
'볼랜드' + #13#10 + '델파이' == '볼랜드#13#10'델파이
- 자료형
프로그래밍 하면서 다루게 될 자료들의 타입을 뜻한다. 숫자에 관련된 자료형은 정수형과 실수형으로 나눌 수 있다. 정수형인 인티저(Integer)와 카디날(Cardinal) 이 외의 형들은 펀다멘탈(fundamental) 타입이라고 하며 이것들은 중앙처리장치(CPU), 오에스(OS)와 관계없이 어느 시스템에서도 일정한 범위를 가지고 있다. 실수형은 부동 소수점 형식으로 표현할 수 있는 수치를 표현하는 자료형이다. 문자형도 일반 자료형과 기본자료형으로 구분 할 수 있다. 일반 자료형은 8비트(bit)의 차(char) 데이터형을 포함하며 기본 자료형은 안시차(AnsiChar)와 와이드차(WideChar)를 포함한다. 일반형 차는 기본형 안시차와 동일한 표현범위를 가진다. 열거형은 숫자나 문자 등과 같이 이미 정해져 있는 기본 식별자가 아닌 새로운 식별자를 괄호 안에 묶어서 표현하는 자료형이다. 일련의 식별자 순서를 가지고 나열함으로써 형성될 수 있다. 부범위형은 파스칼에서 가장 기본이 되는 자료형으로 최솟값과 최댓값을 지정하여 범위를 정하는 자료형이다. 또 한 다른 형의 범위 내에서 값의 범위를 정의한다. 집합형은 오디날(Ordinal) 타입의 256개 이하의 요소로 구성된 모음을 가질 수 있는 자료형이다. 일반 변수의 형이 컴파일 시에 확정되는 것과는 달리, 바리안트(Variant)형 변수는 형 정보까지도 유동적으로 유지하여 실행 중 자료형이 얼마든지 바뀔 수 있다. 일반 변수보다 조금 더 많은 메모리와 실행속도를 희생하는 대신 프로그래밍에 있어서 훨씬 큰 유연성을 제공한다. 반면에 컴파일 시, 형이 정해져 있는 다른 변수의 경우, 컴파일 시에 발견할 수 있었던 오류를 Variant형을 사용하면 미리 알아낼 수 없는 단점도 가지고 있다. 구조형은 하나 이상의 값을 가질 수 있는 자료형을 말한다. 집합형, 배열형, 레코드형, 파일형, 클래스형, 인터페이스형 등을 총칭하는 말이며 구조형을 선언할 때 팩키드(Packed)라는 예약어를 쓰면 메모리에 압축된 형태로 저장되게 된다. 이는 메모리를 적게 쓰는 효과가 있지만, 접근 속도는 저하 된다. 배열은 같은 자료형의 데이터를 한 단위로 묶어서 사용할 수 있도록 해주는 자료형이다. 배열 사용방식에 따라 정적 배열과 동적 배열로 나눌 수 있다.[1]
레코드형은 씨(C)와 씨플플(C++) 등에서 구조형과 매우 유사한 구조로서 여러 종류의 자료형으로 구성된 복합자료형이며 아래의 형식을 가진다.[1]
type 레코드형 이름 = record {예약어 record로써 레코드 선언을 시작한다.} 필드1 : 형1; {각각의 필드마다 다른 형을 줄 수 있다.} ... 필드n : 형n; end; {레코드 선언의 끝}
- 변수와 연산자
변수는 메모리상에 마련되는 일정 공간이며 자료형에 따른 값과 데이터를 저장 할 수 있다. 연산자는 데이터를 포함하고 있는 변수들에 대해 연산을 수행하기 위한 기호이다. 오브젝트 파스칼에서 가장 기본적인 연산자는 할당(대입) 연산자이다. ':=' 기호로 사용된다. 씨언어에서는 할당 연산자가 '='기호인데 오브젝트 파스칼에서는 '='기호가 단순히 같다(Equal)는 의미로 사용된다. 연산자는 크게 산술 연산자, 비교 연산자, 논리 연산자로 나눌 수 있다.[1]
- 포인터
포인터는 변수, 상수, 함수 등의 데이터가 있는 메모리 주소의 주소 값을 가리키는 자료형이다. 어떤 데이터의 주솟값을 가리킬 때는 골뱅이(@) 연산자를 사용한다. 델파이에서는 포인터는 인티저와 같은 정수형과는 다른 별도의 자료형이므로 포인터형과 정수형은 숫자라는 것은 같지만 사용 용도가 다르므로 그냥 호환되지는 않는다. 포인터가 가리키는 메모리의 값을 읽어올 때는 ^를 사용하며 포인터에 값을 할당하는 것은 다음과 같다.
procedure TForm1.Button2Click(Sender: TObject); var Address : ^integer; //인티저형 포인터를 선언한다. begin New(Address); //메모리를 할당한다. Address^ := 1234; //1234 값을 입력한다. ShowMessage(IntToStr(Address^)); Dispose(Address); // 메모리를 해제한다. end;
대부분 자료형을 선언할 때는 티(T)를 붙이는 것이 관행인 것과 같이 포인터형의 자료형을 선언할 때는 피(P)를 붙인다. 프로시저 타입은 말 그대로 프로시저나 함수를 자료형으로 정의한 것을 말한다. 사용되는 프로시저 타입에는 프로시저, 함수가 가리키는 주솟값을 말하게 된다. 그러므로 프로시저 타입도 포인터형이라 할 수 있다. 하지만 한 가지 다른 점은 일반 포인터형을 선언할 때는 '^'를 사용해서 어떤 자료형의 포인터형이라는 것을 가리키도록 한다.[1]
- 상수
상수는 프로그램 실행 중에 값이 변경되지 않는 값을 의미한다. 상수는 프로그램의 실행 중에 값이 변경되지 않는 것이 주요 목적이었지만, 조금 다른 목적을 갖는 상수도 있을 수 있다. 즉 초깃값을 가진 변수의 개념으로 사용되는 것이며, 이런 상수를 형 정의된 상수(Typed constant)라고 부르며 선언 방법은 다음과 같다.[1]
const 상수이름:형 이름 = 값; 예) const Max:integer = 100;
- 제어구조
비교문은 주어진 조건식의 값에 따라 선택적으로 코드를 실행하는 것을 말한다. "이프(if)...덴(then)...;" 과 "이프...덴...엘스(else)...;"의 두 가지 형태가 있다. 명령문 자리에는 하나의 명령문이 올 수 있지만, 오브젝트 파스칼에서는 복합문을 지원하여 조건이 부합하는 경우 명령문1이 수행되고, 그렇지 않은 경우(else)는 명령문2가 수행된다. 당일 형식과 마찬가지로 복합문의 사용이 가능하다.[1]
if 조건식 then 명령문1 elsd 명령문2;
"case"문은 여러 조건을 비교하여 선택할 때 사용한다.[1]
case...of 값1:명령문1; 값2:명령문2; ... else 명령문; end;
반복문 와일(While)은 반복 조건을 먼저 확인하고 조건을 만족시키는지 여부에 따라 명령문을 실행한다. 명령문 자리에는 "begin...end"로 묶인 복합문이 올 수 있다.[1]
While 조건식 do 명령문
리피트(Repeat)문은 와일문과 반대로 일단 한 번 루프(loop)를 수행한 후에 조건식을 비교하여 같은 루프를 다시 반복할 것인지를 결정하는 제어문이다. 주의할 점은 조건이 참이 될 때까지, 즉 명령문의 반복 실행을 위해서는 조건식이 거짓이 되어야 한다.[1]
Repeat 명령문; 명령문; ... until 조건;
포(For)문은 미리 반복할 회수를 정해두고 명령문을 반복 실행할 수 있는 제어문이다.[1]
for 제어변수 := 시작값 to 마지막값 do 명령문; 혹은 for 제어변수 := 시작값 downto 마지막값 do 명령문;
브레이크(break)와 컨티뉴(continue)는 루프(loop)를 중간에 빠져나오거나 새로 반복하고자 할 때 사용하는 명령문이다. 브레이크 문이 한 단계의 루프(For, While, Repeat)만을 빠져나오는데 비해서 엑시트(Exit)는 모든 루프를 다 빠져나와 해당 프로시저를 마치게 만드는 프로시저다. 처리가 중간에 완료될 경우 가장 간단하게 프로시저나 함수를 종료시킬 수 있다.[1]
클래스
- 선언
클래스의 선언은 레코드와 유사하나 프로시저 내부에서는 선언할 수 없다. 클래스(class) 예약어를 사용하며 클래스 예약어 뒤에는 부모 클래스를 표기한다. 오브젝트 파스칼에서는 부모클래스를 지정하지 않으면 그 클래스는 아무런 기능도 갖지 않는다. 생성자도 소멸자도 아무것도 없는 상태가 되지만 델파이에서는 모든 클래스의 조상을 티오비젝트로 하기 위해 부모 클래스를 지정 하지 않으면 그 부모가 티오비젝트인 것으로 간주한다.[1]
type TMyClass = class(부모클래스) Var1: Integer; end;
- 메소드
다음은 부모 클래스를 티마이클래스(TMyClass)로 하였고 메소드를 하나 추가한것이다.
type TTestClass = class(TMyClass) Var2: Integer; procedure Test; end;
메소드가 있는 경우에는 일반 함수, 프로시저와 같이 구현부가 필요하다. 다음은 구현부로 작성되 예이다.
procedure TTestClass.Test; begin ShowMessage(intToStr(Var1+Var2)); end
이 클래스를 사용하는 방법은 아래와 같이 선언 한 후에 그 다음 문장과 같이 호출 하여 사용한다.
var TestClass: TTestClass; TestClass.Test;
클래스는 자료형이고 오브젝트는 그 자료형으로 선언된 변수를 가리킨다. 위에서 선언된 테스트클래스(TestClass) 변수는 오브젝트이고 그것은 티테스트클래스(TTestClass) 형의 클래스이다.[1]
- 클래스,오브젝트 메소드
오브젝트 메소드는 오브젝트가 사용할 수 있는 메소드를 말하며 클래스 메소드는 사용할 수 있는 메소드이다. 오브젝트 메소드는 다음과 같이 사용된다.
변수.메소드 TestClass.Test;
클래스 메소드는 다음과 같이 사용된다.
타입.메소드 TTestClass.Create;
크리에이트(Create) 메소드는 티오피젝트의 클래스 메소드로써 대표적인 생성자이다. 이 메소드는 동적 메소드를 메모리에 올리는 일을 한다. 생성자를 제외한 클래스 메소드 앞에 클래스(class)지시자를 사용한다.[1]
- 정적 및 동적 메소드
정적 메소드는 오브젝트를 선언만 하면 곧바로 사용할 수 있는 메소드로 프로그램이 실행되면서 바로 메모리 상에 자리 잡는 메소드이다. 동적 메소드는 프로그램이 실행되어도 메모리에 올라가지 않아 그냥 사용하면 에러가 발생하게 되는데 이 동적 메소드를 사용하기 위해서는 메모리에 동적 메소드들을 올리는 작업을 해야 하는데 이 기능을 가진 메소드를 생성자라고 한다. 동적 메소드는 메소드의 뒷부분에 버추얼(virtual) 또는 동적(dynamic)을 붙여서 사용한다. 동적 메소드를 사용하는 이유는 메소드를 오버라이드(Override)하기 위함이다.[1]
- 생성자와 소멸자
생성자는 오브젠트 메소드가 아니고 클래스 메소드이다. 리턴값을 지정하지 않으나 기본적으로 자기 자신의 형으로 되어진 오브젝트를 리턴한다. 생성자는 다음과 같이 사용된다.
TestClass := TTestClass.Creat;
생성자는 함수(function)을 쓰지 않고 콘스트럭터(constructor) 지시자를 사용한다. 이런 방법으로 동적 메소드를 메모리에 올려서 사용한 후 이것들을 다시 메모리에서 제거해야 하는 데 이때는 소멸자를 사용한다. 대표적으로 디스트로이(Destroy)가 있으며 디스트럭터(destructor) 지시자를 사용한다. 소멸자는 오브젝트 메소드이므로 다음과 같이 사용된다.
TestClass.Destroy;
델파이에서는 소멸자를 직접 사용하기 보다는 자유메소드를 많이 사용한다. 이것은 정적 메소드이고 오브젝트 메소드이므로 "TestClass.Free;" 와 같이 사용한다. 프리(Free)는 자신이 닐(nil)인가를 확인해서 소멸자를 호출해주므로 오류가 발생할 확률이 낮아진다.[1]
- 프로퍼티
프로퍼티는 델파이에서 브이씨엘(VCL)을 구현하기 위해서 오브젝트 파스칼을 확장 한 것 중에 하나로 그 클래스가 가진 속성이다. 프로퍼티(property) 지시자를 사용해서 선언한다.[1]
- 클래스 가시성
클래스의 멤버들은 클래스 내부에서도 사용되고 외부에서도 사용된다. 이때 어느 구역에서 멤버들을 다룰 수 있게 하느냐를 지정할 수 있는데 크게 네 가지로 나눌 수 있다. 프라이베이트(private) 영역은 이클래스가 선언되어진 유닛에서만 사용할 수 있으며 외부에서는 사용하지 못한다. 프로텍티드(protected) 영역은 이 클래스가 선언되어진 유닛에서 사용될 수 있고 그렇지 않은 외부 유닛에서는 이 클래스를 상속 받은 클래스의 내부에서 사용할 수 있다. 퍼블릭(public) 영역은 모든 곳에서 사용 될 수 있다. 퍼빌리쉬드(published) 영역 역시 모든 곳에서 사용 될 수 있다. 퍼블릭과 다른 점은 퍼블릭은 컴파일 단계에서만 사용이 되나 퍼빌리쉬드는 디자인 타임에서도 사용이 된다. 그러므로 이 영역에 있는 프로퍼티들은 오브젝트 인스펙터에 나타나게 된다.[1]
- 클래스 연산자
클래스 연산자에는 이즈(is)와 에스(as)가 있다. 이즈 연산자는 오브젝트의 형과 클래스 형을 비교하는 연산자이다. 에스 연산자는 오브젝트를 다른 클래스형의 오브젝트로 형 변환 할 때 사용한다. 하지만 이것은 엄밀한 의미에서 형 변환이 아니다. 오브젝트의 형 변환은 다음과 같이 한다.
TTestClass(MyClass).Test;
에스 연산자는 형을 변환하는 것이 아니고 오브젝트를 그 오브젝트가 가지고 있는 부모 클래스형의 오브젝트로 바꾸어 주는 역할을 한다. 즉, 형 변환은 컴파일 단계에서 이루어지며 에스 연산자는 런타임에 이루어지는 일이다. 하지만 그 기능은 거의 돌일해서 같은 용도로 쓰인다. 에스연산자와 형변환은 객체링크장비(OLE Interface)를 사용할 때는 그 기능을 확실히 구분해야 한다.[1]
평가
오브젝트 파스칼은 언어는 특장점을 많이 가진 언어이다. 하지만 실제 세계에서 사용되는 개발환경을 좌우하지는 않는다. 실제로 중요한 것은 운영체제와 최근에 불어닥치는 인터넷 세계, 액티브엑스(active x) 등의 모든 주변환경들과 이들의 관계, 개발자 들이 선택한 마켓 쉐어 등이라고 할 수 있다. 아무리 훌륭한 언어라도 실제로 사용되지 않는 경우는 부지기수이다. 오브젝트 파스칼의 경우 대단히 훌륭한 객체지향 언어이지만 대학에서나 학문적으로 사용될 뿐 실제 시장에서는 외면받고 있는 언어이다.[3]
각주
- ↑ 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 1.24 , 〈[PASCAL 오브젝트 파스칼이란...]〉, 《티스토리》, 2008-12-23
- ↑ 오브젝트 파스칼 위키백과 - https://ko.wikipedia.org/wiki/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8_%ED%8C%8C%EC%8A%A4%EC%B9%BC
- ↑ 3.00 3.01 3.02 3.03 3.04 3.05 3.06 3.07 3.08 3.09 3.10 3.11 3.12 3.13 , 〈오브젝트 파스칼, C++ 그리고 자바의 특징〉, 《델파이포럼》
참고자료
- devWANI, 〈(PASCAL)오브젝트 파스칼이란...〉, 《티스토리》, 2008-12-23
- 델파이포럼 공식 홈페이지 - http://delphi.borlandforum.com/
같이 보기
이 문서는 로고가 필요합니다.