PHP 코드 재 활용 방법 traits 새로운 기능
PHP 5.4.0 부터 PHP 는 코드 를 재 활용 하 는 방법 을 실현 하여 traits 라 고 합 니 다.
Traits 는 PHP 와 유사 한 단일 계승 언어 를 위 한 코드 재 활용 메커니즘 이다.Trait 는 단일 계승 언어의 제한 을 줄 이기 위해 개발 자 들 이 서로 다른 차원 의 구조 에서 독립 된 유형 에서 자 유 롭 게 재 활용 방법 집 을 사용 할 수 있 도록 한다.Traits 와 클래스 조합의 의 미 는 복잡성 을 줄 이 고 전통 적 인 다 중 계승 과 혼합 류(Mixin)와 관련 된 전형 적 인 문 제 를 피 하 는 방식 을 정의 한 것 이다.
Trait 는 하나의 클래스 와 비슷 하지만 입자 와 일치 하 는 방식 으로 기능 을 조합 하 는 데 목적 을 둔다.Trait 는 그 자 체 를 통 해 예화 할 수 없습니다.그것 은 전통 적 인 계승 을 위해 수평 특성의 조합 을 증가 시 켰 다.애플 리 케 이 션 멤버 는 물 려 받 을 필요 가 없다 는 것 이다.
Trait 예제
<?php
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}
class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>
우선 순위기본 클래스 에서 물 려 받 은 멤버 는 trait 에 삽 입 된 멤버 로 덮 여 있 습 니 다.우선 순 위 는 현재 클래스 의 구성원 이 trait 를 덮어 쓰 는 방법 이 고,trait 는 계승 되 는 방법 을 덮어 씁 니 다.
우선 순위 예시
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
?>
이상 루틴 출력:Hello World!기본 클래스 에서 물 려 받 은 멤버 들 이 삽 입 된 Say World Trait 의 sayHello 방법 으로 덮 여 있 습 니 다.그 행동 은 MyHelloWorld 클래스 에서 정 의 된 방법 과 일치 합 니 다.우선 순 위 는 현재 클래스 의 방법 이 trait 방법 을 덮어 쓰 고 trait 방법 은 기본 클래스 의 방법 을 덮어 씁 니 다.
또 다른 우선 순위 의 예
<?php
trait HelloWorld {
public function sayHello() {
echo 'Hello World!';
}
}
class TheWorldIsNotEnough {
use HelloWorld;
public function sayHello() {
echo 'Hello Universe!';
}
}
$o = new TheWorldIsNotEnough();
$o->sayHello();
?>
이상 루틴 출력:Hello Universe!여러 trait
쉼표 로 구분 하여 use 성명 에 여러 개의 trait 를 표시 하면 하나의 클래스 에 삽입 할 수 있 습 니 다.
여러 traint 의 용법 의 예
<?php
trait Hello {
public function sayHello() {
echo 'Hello ';
}
}
trait World {
public function sayWorld() {
echo 'World';
}
}
class MyHelloWorld {
use Hello, World;
public function sayExclamationMark() {
echo '!';
}
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
?>
이상 루틴 출력:Hello World!충돌 의 해결
만약 두 trait 가 같은 이름 의 방법 을 삽입 했다 면 충돌 을 명확 하 게 해결 하지 않 으 면 치 명 적 인 오류 가 발생 할 것 이다.
여러 개의 trait 가 같은 클래스 에서 의 이름 충돌 을 해결 하기 위해 서 는 인 스 테 드 of 연산 자 를 사용 하여 충돌 방법 중 어느 것 을 사용 하 는 지 명확 하 게 지정 해 야 합 니 다.
이상 의 방식 은 다른 방법 만 제외 할 수 있 습 니 다.as 연산 자 는 충돌 하 는 방법 을 다른 이름 으로 도입 할 수 있 습 니 다.
충돌 해결 의 예
<?php
trait A {
public function smallTalk() {
echo 'a';
}
public function bigTalk() {
echo 'A';
}
}
trait B {
public function smallTalk() {
echo 'b';
}
public function bigTalk() {
echo 'B';
}
}
class Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
}
}
class Aliased_Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}
?>
이 사례 에서 토 커 는 trait A 와 B 를 사용 했다.A 와 B 가 충돌 하 는 방법 으로 trait B 의 smallTalk 와 trait A 의 bigTalk 를 사용 하 는 것 을 정의 했다.Aliased_토 커 는 as 연산 자 를 사용 해 토 크 를 B 의 빅 토 크 라 는 별명 으로 정의 했다.
수정 방법의 접근 제어
as 문법 을 사용 하면 방법의 접근 제어 도 조정 할 수 있다.
접근 제어 방법 을 수정 하 는 예
<?php
trait HelloWorld {
public function sayHello() {
echo 'Hello World!';
}
}
// sayHello
class MyClass1 {
use HelloWorld { sayHello as protected; }
}
//
// sayHello
class MyClass2 {
use HelloWorld { sayHello as private myPrivateHello; }
}
?>
trait 에서 trait 를 구성 합 니 다.클래스 가 trait 를 사용 할 수 있 듯 이 다른 trait 도 trait 를 사용 할 수 있 습 니 다.trait 정의 시 하나 이상 의 trait 를 사용 하여 다른 trait 의 일부 또는 모든 구성원 을 조합 할 수 있 습 니 다.
trait 에서 trait 를 구성 하 는 예
<?php
trait Hello {
public function sayHello() {
echo 'Hello ';
}
}
trait World {
public function sayWorld() {
echo 'World!';
}
}
trait HelloWorld {
use Hello, World;
}
class MyHelloWorld {
use HelloWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
?>
이상 루틴 출력:Hello World!Trait 의 추상 적 인 멤버.
사용 하 는 클래스 에 대한 강제 요 구 를 하기 위해 trait 는 추상 적 인 방법의 사용 을 지원 합 니 다.
추상 적 인 방법 을 통 해 강제 요 구 를 하 는 예 를 나타 낸다.
<?php
trait Hello {
public function sayHelloWorld() {
echo 'Hello'.$this->getWorld();
}
abstract public function getWorld();
}
class MyHelloWorld {
private $world;
use Hello;
public function getWorld() {
return $this->world;
}
public function setWorld($val) {
$this->world = $val;
}
}
?>
Trait 의 정적 멤버Traits 는 정적 구성원 의 정적 방법 에 의 해 정 의 될 수 있 습 니 다.
정적 변수의 예
<?php
trait Counter {
public function inc() {
static $c = 0;
$c = $c + 1;
echo "$c
";
}
}
class C1 {
use Counter;
}
class C2 {
use Counter;
}
$o = new C1(); $o->inc(); // echo 1
$p = new C2(); $p->inc(); // echo 1
?>
정적 방법의 예
<?php
trait StaticExample {
public static function doSomething() {
return 'Doing something';
}
}
class Example {
use StaticExample;
}
Example::doSomething();
?>
정적 변수 와 정적 방법의 예
<?php
trait Counter {
public static $c = 0;
public static function inc() {
self::$c = self::$c + 1;
echo self::$c . "
";
}
}
class C1 {
use Counter;
}
class C2 {
use Counter;
}
C1::inc(); // echo 1
C2::inc(); // echo 1
?>
속성Trait 역시 속성 을 정의 할 수 있 습 니 다.
속성 을 정의 하 는 예
<?php
trait PropertiesTrait {
public $x = 1;
}
class PropertiesExample {
use PropertiesTrait;
}
$example = new PropertiesExample;
$example->x;
?>
trait 가 속성 을 정의 하면 같은 이름 의 속성 을 정의 할 수 없습니다.그렇지 않 으 면 오류 가 발생 할 수 있 습 니 다.이 속성 이 클래스 에서 정의 되 고 trait 에서 정의 되 는 것 과 호 환 된다 면 잘못된 단 계 는 E 입 니 다.STRCT,그렇지 않 으 면 치 명 적 인 오류 입 니 다.충돌 의 예
<?php
trait PropertiesTrait {
public $same = true;
public $different = false;
}
class PropertiesExample {
use PropertiesTrait;
public $same = true; // Strict Standards
public $different = true; //
}
?>
Use 의 차이다른 use 의 예
<?php
namespace Foo\Bar;
use Foo\Test; // means \Foo\Test - the initial \ is optional
?>
<?php
namespace Foo\Bar;
class SomeClass {
use Foo\Test; // means \Foo\Bar\Foo\Test
}
?>
첫 번 째 use 는 namespace 에 사용 되 는 use Foo\Test 입 니 다.찾 은 것 은\Foo\Test 이 고,두 번 째 use 는 trait 를 사용 합 니 다.찾 은 것 은\Foo\Bar\Foo\Test 입 니 다.__CLASS__와TRAIT__
__CLASS__ use trait 의 class name 을 되 돌려 줍 니 다.TRAIT__돌아 가기 trait name
예 는 아래 와 같다.
<?php
trait TestTrait {
public function testMethod() {
echo "Class: " . __CLASS__ . PHP_EOL;
echo "Trait: " . __TRAIT__ . PHP_EOL;
}
}
class BaseClass {
use TestTrait;
}
class TestClass extends BaseClass {
}
$t = new TestClass();
$t->testMethod();
//Class: BaseClass
//Trait: TestTrait
Trait실례 는 아래 와 같다
<?php
trait singleton {
/**
* private construct, generally defined by using class
*/
//private function __construct() {}
public static function getInstance() {
static $_instance = NULL;
$class = __CLASS__;
return $_instance ?: $_instance = new $class;
}
public function __clone() {
trigger_error('Cloning '.__CLASS__.' is not allowed.',E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Unserializing '.__CLASS__.' is not allowed.',E_USER_ERROR);
}
}
/**
* Example Usage
*/
class foo {
use singleton;
private function __construct() {
$this->name = 'foo';
}
}
class bar {
use singleton;
private function __construct() {
$this->name = 'bar';
}
}
$foo = foo::getInstance();
echo $foo->name;
$bar = bar::getInstance();
echo $bar->name;
trait 방법 호출뚜렷 하 지 는 않 지만 Trait 방법 이 일반 클래스 의 정적 방법 으로 정의 되면 호출 될 수 있 습 니 다.
실례 는 아래 와 같다
<?php
trait Foo {
function bar() {
return 'baz';
}
}
echo Foo::bar(),"\
";
?>
젊은이 들 은 traits 의 새로운 특성 에 대해 잘 알 고 있 습 니까?본 고 는 여러분 에 게 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
laravel에 yo에서 angularJs&coffeescript를 사용할 수 있도록 한다.먼저 yo 명령을 사용할 수 있어야하므로 아래에서 설치 global에 설치한 곳에서 laravel의 프로젝트 루트로 이동. 클라이언트 코드를 관리하는 디렉토리를 만들고 이동합니다. 클라이언트 환경 만들기 이것으로 히...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.