PHP 추상 속성
PHP에서 추상 클래스 속성을 정의하는 방법이 있습니까?
abstract class Foo_Abstract {
abstract public $tablename;
}
class Foo extends Foo_Abstract {
//Foo must 'implement' $property
public $tablename = 'users';
}
속성을 정의하는 것은 없습니다.
속성은 초기화 시 메모리에 예약된 데이터 컨테이너이므로 선언만 할 수 있습니다.
한편 함수는 정의되지 않고(함수 본문 누락) 선언(종류, 이름, 파라미터)할 수 있으므로 추상화할 수 있다.
"추상"은 선언된 것일 뿐 정의되지 않았음을 나타냅니다.따라서 사용하기 전에 정의하지 않으면 무용지물이 됩니다.
에서는 ( 시 체크를 컴파일러를 사용하면 (컨스트럭터에서) 실행 시 체크(예를 들어)를 강제할 방법은 없습니다.$tablename
★★★★★★★★★★★★★★★★:
class Foo_Abstract {
public final function __construct(/*whatever*/) {
if(!isset($this->tablename))
throw new LogicException(get_class($this) . ' must have a $tablename');
}
}
의 모든 하려면 Foo_Abstract의 Foo_Abstract를 Foo_Abstract로 .final
덮어쓰기를 방지합니다.
대신 추상 getter를 선언할 수 있습니다.
abstract class Foo_Abstract {
abstract public function get_tablename();
}
class Foo extends Foo_Abstract {
protected $tablename = 'tablename';
public function get_tablename() {
return $this->tablename;
}
}
클래스에서 , 이 클래스는 .static
추상 객체 생성자 또는 setter/getter 메서드의 속성에 대한 키워드입니다.필요에 따라 를 사용하여 확장 클래스에서 메서드가 재정의되지 않도록 할 수 있습니다.
예: https://3v4l.org/WH5Xl
abstract class AbstractFoo
{
public $bar;
final public function __construct()
{
$this->bar = static::BAR;
}
}
class Foo extends AbstractFoo
{
//const BAR = 'foobar'; //uncomment to prevent exception
}
$foo = new Foo();
//Fatal Error: Undefined class constant 'BAR'
그러나 확장 클래스는 재정의된 경우 부모 클래스의 속성 및 메서드를 재정의합니다.
를 들어,이 ""로 protected
부모로 정의되어 있습니다.public
클래스에서는 이 확장클클음음음음음음음음음음음 in in in in in in in in in in in in이다.public
않은 경우 로 private
private
확장 클래스에서는 사용할 수 없습니다.
http://www.php.net/ / manual / en / language . oop 5 . static . http://http://www.php.net/
위와 같이 정확한 정의는 없습니다.단, 다음 간단한 회피책을 사용하여 자녀 클래스가 "추상" 속성을 정의하도록 강제합니다.
abstract class Father
{
public $name;
abstract protected function setName(); // now every child class must declare this
// function and thus declare the property
public function __construct()
{
$this->setName();
}
}
class Son extends Father
{
protected function setName()
{
$this->name = "son";
}
function __construct(){
parent::__construct();
}
}
추상적 속성이 필요한 것은 설계상의 문제를 나타낼 수 있습니다.많은 답변이 템플릿 방식 패턴을 구현하고 작동하지만 항상 이상하게 보입니다.
원래의 예를 보겠습니다.
abstract class Foo_Abstract {
abstract public $tablename;
}
class Foo extends Foo_Abstract {
//Foo must 'implement' $property
public $tablename = 'users';
}
를 하다abstract
필수품임을 나타내는 것입니다.필수 값(이 경우)은 필수 종속성이므로 인스턴스화 중에 생성자에게 전달해야 합니다.
class Table
{
private $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function name(): string
{
return $this->name;
}
}
그런 다음 보다 구체적인 이름의 클래스를 원하는 경우 다음과 같이 상속할 수 있습니다.
final class UsersTable extends Table
{
public function __construct()
{
parent::__construct('users');
}
}
이 기능은 DI 컨테이너를 사용하는 경우 개체마다 다른 테이블을 전달해야 하는 경우에 유용합니다.
저는 오늘 같은 질문을 스스로에게 했습니다. 그리고 제 의견을 덧붙이고 싶습니다.
우리가 원하는 이유는abstract
속성은 하위 클래스가 해당 속성을 정의하고 정의되지 않은 경우 예외를 발생시키는 것입니다.제 경우엔, 제가 할 수 있는 일이 필요했어요.static
동맹.
이상적으로는 다음과 같은 것을 원합니다.
abstract class A {
abstract protected static $prop;
}
class B extends A {
protected static $prop = 'B prop'; // $prop defined, B loads successfully
}
class C extends A {
// throws an exception when loading C for the first time because $prop
// is not defined.
}
결국 이 실장을 하게 되었습니다.
abstract class A
{
// no $prop definition in A!
public static final function getProp()
{
return static::$prop;
}
}
class B extends A
{
protected static $prop = 'B prop';
}
class C extends A
{
}
보시는 바와 같이A
정의하지 않습니다.$prop
, 하지만 나는 그것을static
겟터따라서 다음 코드가 작동합니다.
B::getProp();
// => 'B prop'
$b = new B();
$b->getProp();
// => 'B prop'
인C
한편, 저는 이 명령어를 정의하지 않습니다.$prop
예외는 다음과 같습니다.
C::getProp();
// => Exception!
$c = new C();
$c->getProp();
// => Exception!
에 전화해야 합니다.getProp()
예외 취득 방법 및 클래스 로딩에서는 취득할 수 없지만 적어도 내 경우에는 원하는 동작에 매우 가깝습니다.
나는 정의한다getProp()
~하듯이final
어떤 똑똑한 남자(일명 6개월 후의 나)가 유혹을 받지 않도록 하기 위해서
class D extends A {
public static function getProp() {
// really smart
}
}
D::getProp();
// => no exception...
코드를 테스트하는 것만으로 알 수 있듯이:
치명적 오류: 속성을 추상이라고 선언할 수 없습니다...3호선
아니, 없어.PHP에서 속성을 추상이라고 선언할 수 없습니다.
단, getter/setter 함수 추상화를 구현할 수 있습니다.이것이 당신이 찾고 있는 것일 수 있습니다.
속성은 구현되지 않고(특히 공용 자산) 존재하거나 존재하지 않습니다.
$foo = new Foo;
$foo->publicProperty = 'Bar';
PHP 7은 추상적인 "속성"을 만드는 것을 매우 쉽게 합니다.위와 같이 추상 함수를 만들어 만들지만, PHP 7에서는 해당 함수의 반환 유형을 정의할 수 있기 때문에 누구나 확장할 수 있는 기본 클래스를 구축할 때 훨씬 쉬워집니다.
<?php
abstract class FooBase {
abstract public function FooProp(): string;
abstract public function BarProp(): BarClass;
public function foo() {
return $this->FooProp();
}
public function bar() {
return $this->BarProp()->name();
}
}
class BarClass {
public function name() {
return 'Bar!';
}
}
class FooClass extends FooBase {
public function FooProp(): string {
return 'Foo!';
}
public function BarProp(): BarClass {
// This would not work:
// return 'not working';
// But this will!
return new BarClass();
}
}
$test = new FooClass();
echo $test->foo() . PHP_EOL;
echo $test->bar() . PHP_EOL;
tablename 값이 개체의 수명 동안 변경되지 않는 경우, 다음은 간단하지만 안전한 구현입니다.
abstract class Foo_Abstract {
abstract protected function getTablename();
public function showTableName()
{
echo 'my table name is '.$this->getTablename();
}
}
class Foo extends Foo_Abstract {
//Foo must 'implement' getTablename()
protected function getTablename()
{
return 'users';
}
}
여기서 중요한 것은 문자열 값 'users'가 지정되고 자녀 클래스 구현에서 getTablename()으로 직접 반환되는 것입니다.이 함수는 "읽기 전용" 속성을 모방합니다.
이는 가 추가 변수를 사용하는 앞서 게시한 솔루션과 매우 유사합니다.마르코의 해결책도 조금 더 복잡할 수 있지만 마음에 들어요.
추상 클래스에서 정적 속성을 정의할 수 있습니다.
<?php
abstract class Foo {
private static $bar = "1234";
public static function func() {
echo self::$bar;
}
}
Foo::func(); // It will be printed 1234
늦었지만, 은 이 를 사용할 수 .self
★★★★★★★★★★★★★★★★★」static
과 같이
<?php
class A { // Base Class
protected static $name = 'ClassA';
public static function getSelfName() {
return self::$name;
}
public static function getStaticName() {
return static::$name;
}
}
class B extends A {
protected static $name = 'ClassB';
}
echo A::getSelfName(); // ClassA
echo A::getStaticName(); // ClassA
echo B::getSelfName(); // ClassA
echo B::getStaticName(); // ClassB
언급URL : https://stackoverflow.com/questions/7634970/php-abstract-properties
'programing' 카테고리의 다른 글
특정 길이까지 문자열 반복 (0) | 2022.11.07 |
---|---|
팬더는 열 이름만 사용하여 빈 데이터 프레임을 생성합니다. (0) | 2022.11.07 |
Apache HttpClient 4.3의 SSL 인증서 무시 (0) | 2022.11.07 |
PHP 페이지 리다이렉트 (0) | 2022.11.07 |
어레이를 JSON으로 변환 (0) | 2022.11.07 |