phpclass/객체정보2008. 8. 11. 12:37
작성: 2008.08.11
이름지정규칙(Name resolution rules)
네임스페이스 지원으로 이름(클래스명, 함수명 등)은 동일하지만 서로 다른 네임스페이스에 소속될 수 있기 때문에 각 이름이 소속된 네임스페이스를 명확히 지정할 필요가 있습니다. 이름을 지정하는 방법으로는 크게 4가지로 나눌 수 있습니다.
▶ 다른 네임스페이스에 있는 이름을 참조할 때는 Fully Qualified Name 사용
▶ 현재 네임스페이스에 있는 이름을 참조할 때는 Unqualified Name 사용
▶ use 연산자를 이용하여 다른 네임스페이스를 현재 네임스페이스로 가져옴(import)
▶ 전역 네임스페이스에 있는 이름을 참조할 때는 네임스페이스 이름없이 :: 연산자로 시작함
Fully Qualified Name은 네임스페이스의 완전한 이름으로 아래의 예에서 볼 때 MyProject::Connection::NS_CONST, MyProject::Connection::my_function을 의미합니다.
[code php;gutter:true] <?php namespace MyProject::Connection; const NS_CONST = 'namespace constant NS_CONST'; function my_function() { print "namespace function my_function()\n"; } print MyProject::Connection::NS_CONST . "\n"; MyProject::Connection::my_function(); ?> [/code]
다른 네임스페이스에 있는 이름을 참조할 때는 완전한 네임스페이스 이름을 가진 Fully Qualified Name을 사용하여야 하나 현재 네임스페이스에 있는 이름을 참조할 때는 네임스페이스 이름을 생략한 Unqualified Name을 사용할 수 있습니다. 위의 예에서 10, 11번행의 현재 네임스페이스가 MyProject::Connection이므로 아래와 같이 Fully Qualified Name 대신에 Unqualified Name을 사용할 수 있습니다.
[code php;gutter:false] print NS_CONST . "\n"; my_function(); [/code]
전역 네임스페이스(global namespace)는 그 이름을 가지고 있지 않으므로 네임스페이스 이름을 지정할 수 없습니다. 이런 이유로 전역 네임스페이스에 소속된 이름을 참조할 때는 네임스페이스 이름없이 :: 연산자로 시작하는 이름을 사용합니다.
[code php;gutter:false] <?php namespace A::B::C; /* This function is A::B::C::fopen */ function fopen() { /* ... */ $f = ::fopen(...); // call global fopen return $f; } ?> [/code]
use 연산자를 이용하면 스크립트 실행시 다른 네임스페이스를 현재 네임스페이스로 임포트할 수 있습니다. 따라서 소스를 작성하거나 보기에 불편한 긴 Fully Qualified Name 대신에 짧은 별명(alias)을 사용할 수 있습니다. PHP에서 벤치마킹한 것으로 보이는 C++에서는 짧은 이름을 사용하기 위한 방법으로 별명을 이용하는 것 말고도 using 지시자(directive)와 using 선언자(declaration)를 이용하는 방법이 있습니다만 PHP에서는 이러한 방법까지는 제공하지 않습니다.
[code php;gutter:false] <?php namespace MyProject::Connection; function my_class() { /* code */ } ?> [/code]
< inc.php >
[code php;gutter:false] <?php require_once('inc.php'); use MyProject::Connection as Connection; $my = new Connection::my_class(); ?> [/code]
Unqualified 함수 호출
네임스페이스 내에서 Unqualified 함수를 호출하면 아래와 같은 규칙에 따라 해당 함수를 호출합니다.
① 현재 네임스페이스에 정의된 함수를 호출
② PHP 내장(internal; built-in) 함수를 호출
[code php;gutter:true] <?php namespace A::B; $a = ucfirst("testing 'name resolution rules'"); echo($a); function ucfirst($str) { return '<span style="font-size:32pt;color:steelblue">' . ::ucfirst(substr($str, 0, 1)) . '</span>' . substr($str, 1); } ?> [/code]
위 소스의 4번행을 실행하면 7번행에 정의된 현재 네임스페이스의 ucfirst 함수를 호출합니다. 따라서 위 소스를 실행하면 아래와 같은 결과를 얻을 수 있습니다.
Testing 'name resolution rules'
만약 7번행부터 12번행에서와 같이 현재 네임스페이스에 정의된 ucfirst() 함수가 없었다면 PHP 내장함수인 ucfirst()를 바로 호출하였을 것이고 그 결과는 아래와 같았을 것입니다.
Testing 'name resolution rules'
Unqualified 클래스 호출
현재 네임스페이스가 A::B::C일 때, new C()는 A::B::C()로 변환됩니다. 현재 네임스페이스가 A::B일 때, new C()의 호출은 아래와 같은 규칙에 따릅니다.
① 네임스페이스 A::B 내에 정의된 클래스 C에 대한 객체 생성
② PHP 내장(internal; built-in) 클래스에 대한 객체 생성
Qualified 함수 호출
A::B::foo() 함수의 호출은 아래와 같은 규칙에 따릅니다.
① 네임스페이스 A::B 내에 정의된 함수 foo()를 호출
② 클래스 A::B의 정적 멤버 함수 foo()를 호출
[code php;gutter:false] <?php namespace A; // static methods/namespace functions of current namespace A::foo(); // first tries to call function "foo" from namespace "A::A" // then tries to call method "foo" of class "A" from namespace "A" // then tries to call function "foo" from namespace "A" // then calls method "foo" of internal class "A" ?> [/code]
< 출처:php.net >
Qualified 클래스 호출
new A::B::C()는 네임스페이스 A::B의 클래스 C를 참조합니다.
 

Posted by 방글24
phpclass/객체정보2008. 8. 9. 12:36
작성: 2008.08.09
네임스페이스 다루기
임의의 네임스페이스 내에 있는 모든 심볼(클래스명, 함수명, 변수명, 상수명 등)은 네임스페이스_식별자::심볼과 같은 식으로 다루어집니다.
namespaced_idenfitier::symbol;
[code php;gutter:false] <?php namespace MyProject::Connection; function my_class() { /* code */ } ?> [/code]
< inc.php >
[code php;gutter:false] <?php require_once('inc.php'); $my = new MyProject::Connection::my_class(); ?> [/code]
use 연산자(use operator)
use namespaced_name as othername;
use 연산자를 사용하면 원래 네임스페이스 이름 대신에 별명으로 임포트(import)할 수 있기 때문에 긴 이름 대신에 더 짧은 이름을 사용할 수 있어 문서를 단순화 시킬 수 있습니다. 짧은 이름의 othername은 스크립트 문서가 실행될 때 원래의 이름인 namespaced_name으로 변환됩니다.
위의 예제에서 보았듯이 use 연산자를 사용하지 않을 경우에는 MyProject::Connection::my_class()와 같은 전체 이름으로 참조해야 합니다. 그러나 use 연산자를 사용할 경우에는 아래와 같이 Connection::my_class()와 같이 더 짧은 이름을 사용할 수 있습니다.
[code php;gutter:false] <?php require_once('inc.php'); use MyProject::Connection as Connection; $my = new Connection::my_class(); ?> [/code]
또한 use MyProject::Connection as Connection; 에서 Connection과 같이 동일한 이름의 별명을 사용할 경우에는 아래와 같이 as 이하의 구문을 생략할 수 있습니다.
[code php;gutter:false] <?php require_once('inc.php'); use MyProject::Connection; $my = new Connection::my_class(); ?> [/code]
use 연산자는 전역 범위(global scopr)에서만 사용할 수 있으며 함수 또는 클래스 내에서는 사용할 수 없습니다. use 연산자에 의해 임포트된 이름은 임포트된 부분부터 현재 파일의 끝까지 영향을 미칩니다.
상수 __NAMESPACE__(constants __NAMESPACE__)
컴파일-타임 상수인 __NAMESPACE__ 에는 현재 네임스페이스 이름을 가지고 있습니다. 네임스페이스를 벗어나면 빈문자열(empty string)을 값으로 할당됩니다. 따라서 전역 네임스페이스(global namespace)에서 __NAMESPACE__의 값은 빈문자열입니다.
[code php;gutter:false] <?php namespace A::B::C; function foo() { // do stuff } set_error_handler(__NAMESPACE__ . "::foo"); ?> [/code]
< 출처:php.net >

Posted by 방글24
phpclass/객체정보2008. 8. 9. 12:35
작성: 2008.08.09
내장 네임스페이스
php v5.3 이전의 네임스페이스
php v5.3 이전에도 내장된 네임스페이스가 존재하고 있었습니다.
[code php;gutter:false] <?php $str = "전역 네임스페이스(global namespace)의 변수"; function test() { $str = "지역 네임스페이스(local namespace)의 변수"; print "$str<BR>\n"; global $str; print "$str<BR>\n"; } test(); ?> [/code]
test() 함수 내에서 동일한 변수이름 $str이 두 번 사용되고 있지만 하나는 지역 네임스페이스에서, 다른 하나는 전역 네임스페이스의 이름을 참조합니다. 따라서 이 소스를 실행하면 아래와 같이 나타날 것입니다.
전역 네임스페이스 - 함수(또는 클래스) 바깥쪽에서 정의된 이름
지역 네임스페이스 - 함수(또는 메소드) 안에서 정의된 이름 또는 클래스 안에서 정의된 이름
이와 같이 php v5.3 이전에도 내장된 네임스페이스가 존재하고 있어서 묵시적(implicit)으로 사용하여 왔으나, php v5.3 부터는 프로그래머가 새로운 네임스페이스를 직접 명시적(explicit)으로 정의하여 사용할 수 있도록 하였습니다.
전역 네임스페이스(Global namespace; Global space)
네임스페이스를 지원하는 php v5.3에서 네임스페이스가 정의되지않은 클래스 및 함수는 전역 네임스페이스에 존재합니다. 전역 네임스페이스는 특정한 이름(identifier)을 가지고 있지 않기 때문에 네임스페이스_식별자::함수명과 같은 식으로 호출할 수가 없으므로 이 때는 네임스페이스_식별자없이 범위지정자 ::로 시작되는, 즉 ::함수명과 같은 식으로 전역 네임스페이스에 존재하는 함수를 호출합니다.
[code php;gutter:false] <?php namespace A::B::C; /* This function is A::B::C::fopen */ function fopen() { /* ... */ $f = ::fopen(...); // call global fopen return $f; } ?> [/code]
< 출처:php.net >
 

Posted by 방글24
phpclass/객체정보2008. 8. 9. 12:34
작성: 2008.08.09
네임스페이스의 정의
이 문서에서 기술된 모든 소스는 2008년 8월 6일자 php-5.3.0 알파2 개발버전(php5.3-win32-200808062030.zip)으로 테스트하였습니다.
네임스페이스의 정의는 namespace 키워드에 이어 네임스페이스 식별자(identifier)를 지정합니다.
namespace identifier;
스크립트 문서 단위로 이루어지는 네임스페이스
C++과 같은 다른 언어와 달리 php v5.3에서 제공하는 이름공간 기능은 스크립트 문서 단위로 이루어진다는 것입니다. 그리고 네임스페이스의 지정은 다른 실행코드에 앞서 정의되어야 합니다. 그렇지 않고 네임스페이스를 정의하기 전에 다른 실행코드가 문서에 나타나면 아래와 같은 에러를 발생시킵니다.
Fatal error: Namespace declaration statement has to be the very first statement in the script in test.php on line xx
A_SPACE와 B_SPACE 네임스페이스 각각에 존재하는 동일한 이름의 함수 my_function()가 어떻게 동작하는지에 대한 간단한 예를 살펴보겠습니다.
[code php;gutter:false] <?php namespace A_SPACE; function my_function() { print "A_SPACE에서 정의한 함수\n"; } ?> [/code]
< inc1.php >
[code php;gutter:false] <?php namespace B_SPACE; function my_function() { print "B_SPACE에서 정의한 함수\n"; } ?> [/code]
< inc2.php >
[code php;gutter:false] <?php require_once('inc1.php'); require_once('inc2.php'); A_SPACE::my_function(); B_SPACE::my_function(); ?> [/code]
< test.php >
test.php를 실행하게 되면 아래와 같은 결과를 얻을 수 있습니다.
A_SPACE에서 정의한 함수
B_SPACE에서 정의한 함수
여러 개의 파일이 동일한 네임스페이스를 사용하는 예
동일한 명칭의 네임스페이스를 여러 파일에서 사용할 수 있기 때문에 동일한 네임스페이스 내에서 여러 파일로 나누어 작업할 수 있습니다.
[code php;gutter:false] <?php namespace MyProject::Connection; const NS_CONST = 'namespace constant NS_CONST'; class my_class { const MY_CONST = 'my_class::MY_CONST'; public static $public_var = "my_class::public_var"; public function my_function() { print "my_class::my_function()\n"; } } function my_function() { print "namespace function my_function()\n"; } ?> [/code]
< inc1.php >
[code php;gutter:false] <?php namespace MyProject::Connection; class my_class2 extends my_class { public function my_function() { my_class::my_function(); print "my_class2::my_function()\n"; } } ?> [/code]
< inc2.php >
[code php;gutter:false] <?php require_once('inc1.php'); require_once('inc2.php'); print MyProject::Connection::NS_CONST . "\n"; MyProject::Connection::my_function(); print MyProject::Connection::my_class2::MY_CONST . "\n"; print MyProject::Connection::my_class2::$public_var . "\n"; MyProject::Connection::my_class2::my_function(); ?> [/code]
< test.php >
test.php를 실행하게 되면 아래와 같은 결과를 얻을 수 있습니다.
[code php;gutter:false] namespace constant NS_CONST namespace function my_function() my_class::MY_CONST my_class::public_var my_class::my_function() my_class2::my_function() [/code]

Posted by 방글24
phpclass/객체정보2008. 8. 9. 12:32
작성: 2008.08.09
네임스페이스의 필요성
PHP로 프로그래밍할 때 보통 일인체제하에 소규모로 만들어지는 경우가 많다 보니 함수명, 클래스명과 같은 이름이 중복되어 충돌되는 것을 쉽게(?) 피할 수 있었습니다. 그러나 이제 PHP도 여러 사람이 공동 작업하는 경우도 많게 되고 제작되는 프로그램 덩치도 커지고 복잡해지다보니 이름의 중복으로 발생하는 충돌을 피하기가 쉽지 않게 되었습니다.
이러한 이유로 PHP의 미래 버전인 v6에서는 처음부터 네임스페이스를 지원하도록 설계/제작되고 있습니다. 이러한 와중에 그동안의 알려진 바와 같이 php v5.3에 네임스페이스 기능이 이식되어 2008년 8월 1일에 php 5.3 알파1 버전으로 정식으로 공개되었습니다.
객체지향언어 중에는 네임스페이스를 지원하지 않는 언어도 있는 이유로 혹자는 네임스페이스가 꼭 필요한 것이냐고 반문하는 분도 계시지만 네임스페이스가 객체화 도구가 아니고 모듈화 도구이기 때문에 객체지향언어와 무관하게 좀 더 개선된 모듈화 프로그래밍을 할 수 있는 좋은 도구라고 이해하면 될 것 같습니다.
사실 클래스를 이용하면 네임스페이스 지원없이도 함수명, 변수명, 상수명 등의 중복으로 발생하는 충돌을 잘 피할 수 있습니다. 그러나 클래스명의 경우는 그렇지 않습니다. PHP v5 버전이 공개되면서 새로 개발되는 거의 대부분의 PHP 코드들이 클래스를 이용하게 된 현실로 볼 때 모듈화 도구로서 자연스럽게 네임스페이스을 지원하게 된 것 같습니다.
"클래스를 사용해야하나?"라는 문서를 통해 모듈화에서 네임스페이스(namespace; 이름공간)의 역할에 대하여 설명드렸던 것처럼 갈수록 점점 복잡해지고 덩치가 커져가는 PHP 라이브러리와 같은 프로그램에서 함수명, 클래스명, 변수명 등의 이름 충돌 문제를 자주 접하게 됩니다. 그동안 대부분의 프로그래머들은 이러한 문제를 피하기 위하여 이름 앞에 해당 프로그램의 특징을 나타내는 접두어를 붙이는 방법을 주로 사용하여 왔으나 이러한 방법은 이름의 길이를 길게 만들기 때문에 소스를 복잡하게 만드는 등 좋지않은 요인으로 작용하였습니다.
예를 들어 후키템플릿 라이브러리에서 정의된 클래스명을 보면 아래와 같이 대부분의 클래스명에는 접두어로 hTemplate가 붙습니다. 이것은 다른 라이브러이 등과 함께 사용할 때 이름이 충돌되는 것을 피하기 위한 한 방편으로 사용된 것입니다.
[code php;gutter:false] <?php class hTemplateCache { /* code */ } class hTemplateCompile { /* code */ } class hTemplateDebug { /* code */ } class hTemplateFile { /* code */ } class hTemplateFilter { /* code */ } class hTemplateFunction { /* code */ } class hTemplateStructure { /* code */ } class hTemplateAssign { /* code */ } class hTemplate extends hTemplateAssign { /* code */ } $tpl = new hTemplate(); ?> [/code]
만약 PHP 5.3.0 버전부터 제공되는 namespace 키워드를 이용한다면 아래와 같이 클래스명에 접두어 hTemplate를 붙이지 않더라도 다른 프로그램과 이름이 충돌하는 것을 피할 수 있을 것입니다.
[code php;gutter:false] <?php namespace hTemplate; class Cache { /* code */ } class Compile { /* code */ } class Debug { /* code */ } class File { /* code */ } class Filter { /* code */ } class Function { /* code */ } class Structure { /* code */ } class Assign { /* code */ } class main extends Assign { /* code */ } $tpl = new hTemplate::main(); ?> [/code]
또 다른 예로 PEAR의 HTTTP 패키지를 살펴보면 아래와 같은 "HTTP", "HTTP_Downlod", "HTTP_Request"와 같은 특정 접두어를 붙인 클래스명을 사용하여 클래스명이 다름 프로그램과 충돌될 가능성을 사전에 피하려고 한 것을 볼 수 있습니다.
HTTP_Download
HTTP_Client
HTTP_Header
HTTP_Request
HTTP_Download_PgLOB
HTTP_Download_Archive
HTTP_Header_Cache
HTTP_Request_Listener
< PEAR HTTP 패키지에서 사용된 클래스명 >
PEAR2 Coding Standards(pear.php.net/manual/en/pear2cs.php)의 Rule을 보면 PEAR2의 모든 클래스와 함수는 아래와 같이 반드시 PEAR2의 네임스페이스를 정의하도록 하고 있습니다. (아래의 세번째 예는 설명을 위해 추가하였음)
[code php;gutter:false] <?php namespace PEAR2; class MyClass { /* code */ } ?> [/code]
[code php;gutter:false] <? namespace PEAR2::HTTP; class Request { /* code */ } ?> [/code]
[code php;gutter:false] <? namespace PEAR2::HTTP::Request; class Listener { /* code */ } ?> [/code]
이와 같이 네임스페이스를 이용하면 클래스명에 더 이상 접두어를 붙일 필요가 없습니다.
Download
Client
Header
Request
PgLOB
Archive
Cache
Listener
< 네임스페이스 지원으로 간략화된 클래스명 >
이와 같이 네임스페이스의 지원으로 간단명료한 클래스명을 사용하여 프로그래밍할 수 있게 되었으며 단지 각 클래스들이 어느 네임스페이스에 속해 있는지만 명확히 지정해주면 됩니다.

Posted by 방글24
phpclass/객체정보2008. 8. 9. 12:28
작성: 2008.08.09
네임스페이스란?
많은 사람들이 네임스페이스(namespace; 이름공간) 개념을 이해하는데 어려움을 겪는 것 같습니다. 2008년 8월 1일 php.net에 정식 릴리즈된 5.3.0 알파1 버전부터 네임스페이스를 지원한다기에 네임스페이스를 이곳에서 다시 한 번 정리하게 되었습니다.
프로그램 소스의 여러 가지 구성요소 중에는 클래스명, 함수명, 변수명, 상수명과 같이 이름(identifier)들이 포함되어 있는데 이러한 이름들이 동일한 이름으로 중복하여 사용하더라도 서로 충돌되지 않도록 해주는 기능이 네임스페이스입니다.
초등학교 교실
예를 들어, 어떤 초등학교 6학년 1반에 홍길동이란 이름을 가진 어린이가 3명 있다고 하면 이 반 담임선생님은 출석을 부를 때마다 곤혹을 치를 것입니다.
키큰 홍길동~
키작은 홍길동~
뚱뚱한 홍길동~
< 6학년 1반에 편성된 3명의 홍길동 어린이 >
그렇다고 아이들보고 이름 바꾸라고 할 수 있습니까? 불편하지만 홍길동 앞에 "키큰", "키작은", "뚱뚱한"과 같은 접두어를 붙일 수 밖에 없겠지요.
사실 이 문제를 근본적으로 해결하려고 했다면 학년초 반편성할 때 3명의 홍길동 어린이를 서로 다른 반으로 편성했을 것입니다.
< 각 반으로 편성되어 관리되고 있는 3명의 홍길동 >
이제는 "키큰", "키작은", "뚱뚱한"이라는 괴상망칙한 수식어를 붙이지 않아도 됩니다. 각 반에서는 모두 수식어 없이 그냥 홍길동이라고 부르면 되고, 같이 있을 때는 1반 홍길동, 2반 홍길동, 3반 홍길동 라고 부르면 되지요.
네임스페이스(namespace; 이름공간)
네임스페이스란 그 이름이 뜻하는 바와 같이 서로 관련된 이름(함수명, 클래스명 ...)을 통합관리하기 위하여 지정하는 공간을 의미합니다. 초등학교 각 반 교실에 해당합니다. 키큰 홍길동은 1반에, 키작은 홍길동은 2반에, 뚱뚱한 홍길동은 3반에 소속시키는 것입니다. 이를 개념적으로 프로그래밍해보면 아래와 같습니다.
[code php;gutter:false] <?php namespace 1반; function 홍길동() { print "나는 키큰 홍길동이다.\n"; } ?> [/code]
[code php;gutter:false] <?php namespace 2반; function 홍길동() { print "나는 키작은 홍길동이다.\n"; } ?> [/code]
[code php;gutter:false] <?php namespace 3반; function 홍길동() { print "나는 뚱뚱한 홍길동이다.\n"; } ?> [/code]
홍길동을 부를 때 1반 홍길동, 2반 홍길동, 3반 홍길동 라고 부르듯이 프로그램 소스에서는 아래와 같이 1반::홍길동(), 2반::홍길동(), 3반::홍길동() 라는 식으로 호출하면 됩니다.
[code php;gutter:false] <?php 1반::홍길동(); 2반::홍길동(); 3반::홍길동(); ?> [/code]
각 반에서 반에 소속된 어린이의 이름을 출석부에 기록하여 관리하는 것처럼 각 네임스페이스에 소속된 이름을 심볼 테이블(symbol table)에 기록하여 관리합니다.

'phpclass > 객체정보' 카테고리의 다른 글

{네임스페이스}3.네임스페이스의 정의  (0) 2008.08.09
{네임스페이스}2.네임스페이스의 필요성  (0) 2008.08.09
What Is an Interface?  (0) 2005.10.25
{참조}5.참조 삭제  (0) 2001.03.02
{참조}4.참조 반환  (0) 2001.03.02
Posted by 방글24
phpclass/객체정보2005. 10. 25. 22:57

What Is an Interface?

(출처)

   http://java.sun.com/docs/books/tutorial/java/concepts/interface.html

현재 이 웹사이트 주소에 접속할 수 없어서 해당자료를 임시로 이곳에 올립니다.

현재 이 웹사이트의 자료가 새롭게 업데이트되었습니다.

수정되기 전의 문서(2005년 10월 이전 자료)를 임시로 이곳에 올립니다.


 

 

The JavaTM Tutorial

 

 


Trail: Learning the Java Language
Lesson: Object-Oriented Programming Concepts

 

What Is an Interface?

In general, an interface is a device or a system that unrelated entities use to interact. According to this definition, a remote control is an interface between you and a television set, the English language is an interface between two people, and the protocol of behavior enforced in the military is the interface between people of different ranks.

 

Within the Java programming language, an interface is a type, just as a class is a type. Like a class, an interface defines methods. Unlike a class, an interface never implements methods; instead, classes that implement the interface implement the methods defined by the interface. A class can implement multiple interfaces.

 

The bicycle class and its class hierarchy define what a bicycle can and cannot do in terms of its "bicycleness." But bicycles interact with the world on other terms. For example, a bicycle in a store could be managed by an inventory program. An inventory program doesn’t care what class of items it manages, as long as each item provides certain information, such as price and tracking number. Instead of forcing class relationships on otherwise unrelated items, the inventory program sets up a protocol of communication. This protocol comes in the form of a set of method definitions contained within an interface. The inventory interface would define, but not implement, methods that set and get the retail price, assign a tracking number, and so on.

 

To work in the inventory program, the bicycle class must agree to this protocol by implementing the interface. When a class implements an interface, the class agrees to implement all the methods defined in the interface. Thus, the bicycle class would provide the implementations for the methods that set and get retail price, assign a tracking number, and so on.

 

You use an interface to define a protocol of behavior that can be implemented by any class anywhere in the class hierarchy. Interfaces are useful for the following:

 

  • Capturing similarities among unrelated classes without artificially forcing a class relationship
  • Declaring methods that one or more classes are expected to implement
  • Revealing an object's programming interface without revealing its class
  • Modelling multiple inheritance, a feature that some object-oriented languages support that allows a class to have more than one superclass

 

 

 

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.


Posted by 방글24
phpclass/객체정보2001. 3. 2. 14:34
참조 삭제 동작 원리
참조 삭제(unsetting references)하는 것은 변수명과 변수 내용의 연결을 끊어줄 뿐이지 변수 내용 자체를 삭제하지는 않습니다. 따라서 아래와 같이 $a 변수를 삭제하더라도 그 내용은 남아 있기 때문에 $b 변수를 계속 사용할 수 있습니다.
[code php;gutter:false] $a = 1000;
$b = &$a;
unset ($a); [/code]
< 참조와 삭제 >
< 심볼 테이블(unset전) >
변수명 변수값이 저장된 메모리 주소 설명
$a 0x6000 원본
$b 0x6000 참조
< 심볼 테이블(unset후) >
변수명 변수값이 저장된 메모리 주소 설명
$b 0x6000 참조
global References
전역변수를 선언하면 이 변수는 자동으로 전역배열 $GLOBALS[]에 참조됩니다. 이것은 마치 아래와 같은 문장를 수행한 것과 같습니다.
[code php;gutter:false] $var = &$GLOBALS["var"]; [/code]
그런데 매뉴얼 설명과는 달리 unset으로 전역변수를 삭제하면 전역배열 $GLOBALS[]의 내용도 함께 삭제되는 것을 확인할 수 있었습니다. 아래의 예제를 참조바랍니다.
[code php;gutter:false] <?php

$a = "set variable";
$b = &$a;

echo "---------\n";
echo "[".$a."]\n";
echo "[".$GLOBALS["a"]."]\n";
echo "[".$b."]\n";

unset($b);

echo "---------\n";
echo "[".$a."]\n";
echo "[".$GLOBALS["a"]."]\n";
echo "[".$b."]\n";

unset($a);
//unset($GLOBALS["a"]);

echo "---------\n";
echo "[".$a."]\n";
echo "[".$GLOBALS["a"]."]\n";
echo "[".$b."]\n";

echo "---------\n";

?> [/code]
실행결과는 아래와 같습니다.
---------
[set variable]
[set variable]
[set variable]
---------
[set variable]
[set variable]
[] <-- unset($b)로 삭제됨
---------
[] <-- unset($a)로 삭제됨
[] <-- unset($a)로 삭제됨
[]
---------

'phpclass > 객체정보' 카테고리의 다른 글

{네임스페이스}1.네임스페이스란?  (0) 2008.08.09
What Is an Interface?  (0) 2005.10.25
{참조}4.참조 반환  (0) 2001.03.02
{참조}3.참조에 의한 전달  (0) 2001.03.02
{참조}2.객체생성에서의 참조  (0) 2001.03.02
Posted by 방글24
phpclass/객체정보2001. 3. 2. 14:32
함수의 참조 반환
함수에서 참조 반환(returning references)할 수 있습니다. 참조 반환하기 위해서는 함수 정의에서 함수명 앞에 참조연산자(reference operator) &를 붙입니다.
[code php;gutter:false] function &bar() {
$a = 5;
return $a;
}
foo(bar()); [/code]
함수에서 참조가 아닌 값으로 반환하게 되면 호출측에서 받게 되는 것은 함수 내의 반환값의 복사본을 받게 될 것입니다.
[code php;gutter:false] <?php

class test {
var $mb;

function test($mb="default") {
$this->mb = $mb;
}
}

function foo(&$obj) {
$obj->mb = "in foo()";
return $obj;
}

$a = &new test;
$b = &foo($a);
$b->mb = "object b";
echo $a->mb."\n";
echo $b->mb."\n";

?> [/code]
위와 같이 참조가 아닌 값으로 반환하게 되면 객체 $a와 객체 $b는 완전히 별개의 객체입니다. 따라서 실행결과를 보면 아래와 같이 객체의 멤버변수 $mb의 값은 틀립니다.
in foo()
object b
그러나 참조를 반환하기 위해 함수정의를 function &foo(&$obj)와 같이 수정한다면 객체 $b는 객체 $a의 참조(별명)이 되어 $a와 $b 모두 동일한 객체 내용을 나타내게 됩니다. 즉, $a를 가지고 멤버를 다루더라도 $b의 멤버가 수정되게 되지요. 아래는 수정하였을 때의 실행 결과입니다.
object b
object b
위에서 한가지 더 주의할 것이 있습니다. $b = &foo($a) 에서 대입연산자로 $b를 할당할 때 반드시 참조로 할당하여야 한다는 것입니다. 아무리 함수가 참조를 반환하더라도 $b = foo($a) 와 같이 하게 되면 $b는 $a의 객체가 참조되는 것이 아니라 대입되는 과정에 복사되는 것입니다. 따라서 함수로부터 참조를 반환할 때는 함수 정의 부분과 호출측의 대입 부분 모두 참조연산자 &를 붙여야 합니다.
[code php;gutter:false] function &returns_reference() {
return $someref;
}

$newref =&returns_reference(); [/code]

'phpclass > 객체정보' 카테고리의 다른 글

What Is an Interface?  (0) 2005.10.25
{참조}5.참조 삭제  (0) 2001.03.02
{참조}3.참조에 의한 전달  (0) 2001.03.02
{참조}2.객체생성에서의 참조  (0) 2001.03.02
{참조}1.참조변수의 생성  (0) 2001.03.02
Posted by 방글24
phpclass/객체정보2001. 3. 2. 14:23
매개변수 전달 방식
값에 의한 전달(call by value)
함수의 매개변수는 기본적으로 값에 의한 전달을 합니다. 이 방식으로 값을 전달하게 되면 함수 내에서 값을 변경하게되면 함수 밖에 있는 값을 변경하는 것을 불가능합니다. 값에 의한 전달은 대입연산자에 의한 할당에서와 마찬가지로 원본의 복사본을 함수 내로 전달하기 때문에 복사본을 아무리 변경해 보았자 원본의 내용은 그대로 남아있기 때문입니다.
참조에 의한 전달(passing by reference 또는 call by reference)
참조에 의한 전달을 하게 되면 원본의 별명을 함수 내로 전달하게 되며 이 별명은 원본의 내용을 그대로 나타내고 있습니다. 따라서 함수 내에서 별명에 의해 수정한 내용이 원본에 그대로 반영되는 것입니다. 따라서 매개변수(원본의 내용)를 수정하려면 참조에 의한 전달 방식을 사용하여야 합니다.
참조에 의한 전달
전달 방법
참조에 의해 함수의 매개변수를 전달하면 이러한 매개변수는 호출측의 사용범위를 갖는 동시에 함수 내에서 사용하는 지역변수로도 사용됩니다. 쉬운 말로 하면 호출측에서 사용하는 원본을 함수 내로 직접 보내는 것입니다. 예를 들어 아래와 같은 예제를 실행하면 $a가 6임을 알 수 있습니다.
[code php;gutter:false] function foo (&$var) { // $var은 전역변수 $a의 별명(참조)
$var++;
}

$a=5;
foo ($a);
echo "\$a=$a\n"; [/code]
이것은 함수 foo 내에 있는 변수 $var이 $a와 동일한 내용을 참조하기 때문입니다. 위에서 보면 함수를 호출할 때는 참조표시(reference sign) &(ampersand)가 없으며 단지 함수를 정의하는 부분에만 참조표시를 하고 있습니다. 이와 같이 함수 정의에서만 참조표시를 하더라도 참조에 의한 전달을 정확히 할 수 있습니다. 때에 따라서는 함수 정의에서 참조표시를 하지 않더라도 함수를 호출할 때 참조표시 &를 첨부하여 호출하면 참조에 의한 매개변수 전달을 할 수 있습니다.
기본적으로는 값에 의한 전달을 하고 특별한 경우에만 참조에 의한 전달을 할 필요가 있는 경우에만 이와 같이 호출측에서 참조표시 &를 붙일 수 있습니다. 그러나 이와 같은 방법은 특별한 이유가 없는 한 좋은 방법은 아닙니다. 함수를 정의할 때 매개변수를 참조로 받을 것인지 아니면 평상시와 같이 복사하여 받을 것인지를 결정하는 것이 바람직합니다.
[code php;gutter:false] function foo ($bar) {
$bar .= ' and something extra.';
}

$str = 'This is a string, ';
foo ($str);
echo $str; // outputs 'This is a string, '
foo (&$str);
echo $str; // outputs 'This is a string, and something extra.' [/code]
전달할 수 있는 요소
참조로 전달할 수 있는 요소로는 아래와 같이 "변수", "new문", "함수에서 반환되는 참조"가 있습니다.
▶변수 : foo($a)
▶new문 : foo(new foobar())
▶함수에서 반환되는 참조 :
[code php;gutter:false] function &bar() {
$a = 5;
return $a;
}

foo(bar()); [/code]
전달할 수 없는 요소
위에서 정의된 요소가 아닌, 예를 들어 함수의 반환값이 참조가 아닌 경우, 표현식(expression), 상수를 참조에 의한 매개변수로 전달할 수 없습니다.
[code php;gutter:false] function bar() { // &가 누락되어 함수의 반환값이 참조가 아님
$a = 5;
return $a;
}

foo(bar()); // 함수의 반환값이 참조가 아닌 경우
foo($a = 5) // 표현식
foo(5) // 상수 [/code]
참조는 포인터가 아님.
아래와 같은 예에서 여러분은 실행결과 $bar값이 "91"라고 생각할 지 모르겠으나 $bar값은 여전히 "1000"입니다.
[code php;gutter:false] function foo(&$var) {
$var = &$GLOBALS["baz"];
}

$bar = 1000;
$baz = 91;

foo($bar);
echo "$bar\n"; [/code]
foo 함수를 호출하면 foo 함수에 있는 $var은 $bar와 바인딩되어 있습니다. 그러나 이 때 $var이 $GLOBALS["baz"]와 다시 바인딩할 것입니다. 함수 내에서 참조 메커니즘을 이용하여 호출측 사용범위를 가지고 있는 $bar에 바인딩할 방법이 없습니다. $bar은 함수 foo에서는 사용할 수 없는 변수입니다. $var에 의해 표현되어지기는 하지만 $var은 단지 변수 내용만 가지고 있을 뿐입니다.
< 심볼 테이블 >
scope 변수명 변수값이 저장된
메모리 주소
설명
호출측 $bar 0x6000  
$baz 0x7000  
함수내 $var 0x6000 매개변수가 참조로 넘어갈 때
0x7000 $var = &$GLOBALS["baz"]를 실행한 직후
참조에 의한 객체 전달
생 성된 객체를 참조로 함수 내로 전달할 수 있습니다. 이 때 참조로 넘기지 않고 값으로 넘기게 되면 최초로 생성된 객체의 복사본을 함수 내로 전달하게 되며 이것은 원본과는 다른 별개의 객체입니다. 이것은 마치 앞장에서 $a = new test에 의해 객체가 복사되는냐 아느면 $a = &new test에 의해 객체가 참조되느냐와 같은 원리입니다.
[code php;gutter:false] <?php

class test {
var $mb;

function test($mb="default") {
$this->mb = $mb;
}
}

function foo(&$obj) {
$obj->mb = "in foo()";
}

$a = &new test;
foo($a);
echo $a->mb;

?> [/code]
아 래와 같이 new test로 객체를 생성하자 마자 함수로 전달할 수도 있습니다. 이 예만 가지고는 왜 이렇게 코딩하는지 이해가 되지 않을 것입니다. 이는 참조에 의한 반환과 함께 사용될 때 그 효과가 나타나게 됩니다. 그러니 다음장에 있는 참조에 의한 반환을 참조하세요.
[code php;gutter:false] <?php

class test {
var $mb;

function test($mb="default") {
$this->mb = $mb;
}
}

function foo(&$obj) {
echo $obj->mb;
}

foo(new test);

?> [/code]
$this의 동작 방식
객체 메소드에서 사용하는 $this는 호출측 객체에 대한 참조입니다. 따라서 $this를 가지고 수정한 내용은 호출측 객체의 내용에 그대로 반영됩니다.
[code php;gutter:false] <?php

class test {
var $mb;

function set($mb="default") {
$this->mb = $mb;
}
}

$a = &new test;
$a->set("set()");
echo $a->mb;

?> [/code]
$this가 참조가 아니고 복사였다면 echo $a->mb의 결과는 아무 값도 나타나지 않겠지요.

'phpclass > 객체정보' 카테고리의 다른 글

{참조}5.참조 삭제  (0) 2001.03.02
{참조}4.참조 반환  (0) 2001.03.02
{참조}2.객체생성에서의 참조  (0) 2001.03.02
{참조}1.참조변수의 생성  (0) 2001.03.02
{추상클래스}6.세셔너 확장  (0) 2000.12.28
Posted by 방글24