~~Title:PHP 클래스~~
{{page>language:php:php_문서_목차&noheader&nofooter&noeditbtn&firstseconly}}
====== OO PHP ======
===== 클래스 선언 =====
class MySample
{
public $var1;
function func1() {}
}
// ';' 는 필요 없나? -> 없어도 된다.
===== 생성자,소멸자 =====
class MySample
{
public $var = 'class attribute';
//생성자
function __construct( /* param if need */ )
{ echo 'construct'.'
'; }
//소멸자
function __destruct()
{ echo 'destruct' . '
'; }
}
===== 인스턴스 =====
$mySamp = new MySample;
이름으로 생성 할 수도 있다. 변수 이름을 대입해서 사용하는 변수로서.
$MySample = 'MySample';
$mySamp2 = new $MySample;
===== 클래스 속성(Attribute) 사용 =====
클래스 속성을 사용하려면,
class MySample
{
public $var = 'class attribute';
//...
function foo()
{
echo $this->var;
}
}
$a = new MySample;
echo $a->var;
__get(), __set()을 사용해서, 속성을 사용할 때 데이터를 캡슐화 할 수 있다.
class MySample {
public $var2 = 'a';
function __get( $name )
{
return $this->$name;
}
function __set( $name, $value )
{
$this->$name = $value;
}
}
어디에 쓸 것인가, 각 속성이 사용되는 시점에 데이터의 정합성을 확인하는 용도가 있다라고 하는데..
익숙하지 않은 개념이라 잘 모르겠다.
===== 클래스 연산(operator) =====
따로 적을 필요 있나..
(class instance)->(operator(...));
===== 상속 =====
키워드 : extends 로 상속 받는다.
class MySample2 extends MySample {
public $var3;
}
===== 오버라이딩 =====
연산자(operator) 이름이 같다면, 오버라이딩은 기본이다.
자식 클래스 쪽의 오버라이딩된 함수에서 부모의 함수를 호출하려면 parent::를 붙여서 호출하면 된다.
class A {
function operA() { echo 'from a'; }
}
class B {
function operA() { echo 'from b'; parent::operA(); }
}
==== final ====
연산자에 final을 붙이면, 오버라이딩이 되지 않는다.
class MySample {
final function operA() {}
}
class 에 final을 붙이면 상속이 되지 않는다.
final class MySample {
//...
}
이 두 경우 모두 실행하면 에러가 발생된다.
===== 다중 상속 =====
지원하지 않는다.
===== 인터페이스 =====
자바의 인터페이스와 같다. 클래스의 인터페이스를 만든다.
interface Displayable
{
function display();
}
사용하려면,
class SomePage implements Displayable
{
function display()
{
// ..
}
}
===== php 고급 객체 지향 기능 =====
==== 클래스당 상수 ====
class Math {
const pi = 3.14;
}
echo Math::pi . '
';
==== 정적(static) 메소드 ====
static 을 붙이면 인스턴스를 만들지 않아도 호출이 가능하다.
class Math {
static function squared( $input ) {
return $input * $input;
}
}
// 사용하기
echo Math::squared(2);
==== 클래스 타입검사와 hinting ====
instanceof
* 특정 클래스의 인스턴스인가
* 특정 클래스를 상속 받았는가?
* 인터페이스를 구현한 것인가?
판단하는 키워드.
if( $b instanceof A ) // $b는 A의 무엇인가에 따라 리턴 값이 true , false가 나온다.
=== 힌팅 ===
// if class B가 있다면
function check_hint( B $someclass ) {
//...
}
함수 파라미터에 클래스 이름을 적어서, 다른 종류의 클래스 인스턴스를 받는 것을 막는다.
==== 정적 바인딩 ====
정적 함수에 대한 오버라이딩 기능이 적용된다. php v5.3 부터 적용.
class A {
public static function who() { echo __CLASS__; }
public static function test() { static::who(); }
}
class B extends A {
public static function who() { echo __CLASS__; }
}
B::test(); // 결과는 B
==== 객체복사 ====
clone 명령어로 복사
$c = clone $b;
직접 복사하는 기능을 추가하는 경우, __clone()함수를 정의하여 필요한 부분을 넣는다.
clone 을 실행해도 , 완전히 똑같이 복사본을 만드는 기본 행동 뒤에 __clone()가 호출되므로, 전체를 다시 복사하지 않아도 된다.
==== 추상 클래스 ====
인터페이스 클래스가 있는데 이건 왜 만들었을까? abstract와 같이 사용해서 추상 클래스를 만든다. 내부 메소드도 추상 여부에 대한 키워드를 추가할 수 있다.
abstract class A {
abstract function operationX( $param1, $param2 );
}
==== __call() 메소드 오버로딩 ====
흥미로운 기능이다. 오버로딩 기능 중에 유용하게 쓸 수 있을 것 같다.
첫번째 파라미터는 호출되는 메소드 이름.
두번째는 호출되는 메소드에 넘어갈 파라미터의 배열이다.
//예제함수
public function __call( $methodName, $param )
{
if( $methodName == 'display' ) {
if( is_object($param[0]) )
$this->displayObject( $param[0] );
else if( is_array($param[0]) )
$this->displayArray( $param[0] );
else
$this->displayScala( $param[0] );
}
}
//사용 예
$ov = new overload;
$ov->display( array(1,2,3) ); // call displayArray()
$ov->display( 'cat' ); // call displayObject()
display()라는 메소드를 호출하면 __call() 메소드가 실행 되고, __call() 내부에서는 display() 메소드가 호출되는 경우에 대한 코드가 실행 된다.
그 코드에서는 파라미터에 따라 각각 다른 함수를 부르는 부분이 실행된다. 약간의 오버로드는 예상되지만.. 복잡한 실행 구조를 감추는 편의 함수를 작성할때 요긴할 것 같다.
display()는 구현할 필요가 없다.
==== __autoload ====
클래스에서 사용하는 함수가 아니라 독립된 함수로서, __autoload()를 구현하면 클래스를 생성하려고 할때 자동으로 호출된다.
new 연산자를 오버로딩한 것 같은 효과?
필요한 클래스의 인스턴스를 만들때, 클래스가 선언된 파일을 불러 오는 용도로 주로 사용한다고 한다.
function __autoload( $name )
{
include_once $name . ".php";
}
==== Iterator와 반복 구현하기 ====
배열처럼 클래스 속성에 접근할 수 있다? (정말로?)
class myClass {
public $a = '5';
public $b = '3';
public $c = '3';
}
$x = new myClass;
foreach( $x as $attribute ) { echo $attribute . '
'; }
이것보다 복잡한 방식이라면, iterator를 만들어야 한다.
예제코드가 길기때문에 패스. 필요하면 인터넷 검색.
==== 클래스를 문자열로 ====
$p = new someclass;
echo $p;
__toString() 함수를 클래스에 구현하면, 클래스를 출력할때 (위의 코드) 이 함수가 호출 된다.
class Printable {
public $test1;
public $test2;
public function __toString()
{
return (var_export($this, TRUE));
}
}
==== reflection API ====
디버깅용인가?
' . $nc . '';
?>
해당 클래스, 여기에서는 Page,의 상세 정보가 쭈욱 출력된다.
====== 7장 - 예외처리 ======
try {
//code
throw new Exception('msg',code);
}
catch( Exception $e ) {
//예외처리
}
===== Exception Class =====
Exception class의 기본 메소드
* getCode()
* getMessage()
* getFile()
* getLine()
* getTrace()
* getTraceAsString()
* __toString() : 이 함수를 구현하면, Exception 클래스를 바로 출력할때, 필요한 정보만 줄 수 있다.
디버깅 클래스를 따로 만드는 것이 낫지 않나?