PHP에서 두 개 이상의 클래스를 사용하여 클래스를 확장 할 수 있습니까?
PHPPHP에서 두 개 이상의 클래스를 사용하여 클래스를 확장 할 수 있습니까?
필요한 기능을 가진 여러 클래스가 있지만 조직을 위해 별도로 저장하려는 경우 클래스를 확장하여 둘 다 가질 수 있습니까?
즉 클래스 a는 b 확장 c
편집 : 클래스를 한 번에 하나씩 확장하는 방법을 알고 있지만 즉시 여러 기본 클래스를 사용하여 클래스를 확장 할 수있는 메서드를 찾고 있어요 - AFAIK PHP에서는이 작업을 수행 할 수 없지만 주위에 방법이 있어야합니다. 클래스 c는 b를, 클래스 b는
해결법
-
==============================
1.귀하의 편집 답변 :
귀하의 편집 답변 :
정말로 다중 상속을 가짜로 만들고 싶다면 마술 함수 __call ()을 사용할 수 있습니다.
이것은 클래스 A 사용자의 관점에서 작동하지만 추악합니다.
class B { public function method_from_b($s) { echo $s; } } class C { public function method_from_c($s) { echo $s; } } class A extends B { private $c; public function __construct() { $this->c = new C; } // fake "extends C" using magic function public function __call($method, $args) { $this->c->$method($args[0]); } } $a = new A; $a->method_from_b("abc"); $a->method_from_c("def");
"abcdef"를 인쇄합니다.
-
==============================
2.두 개의 기본 클래스를 확장하는 클래스는 가질 수 없습니다. 당신은 가질 수 없었습니다.
두 개의 기본 클래스를 확장하는 클래스는 가질 수 없습니다. 당신은 가질 수 없었습니다.
// this is NOT allowed (for all you google speeders) Matron extends Nurse, HumanEntity
그러나 다음과 같은 계층 구조를 가질 수 있습니다 ...
Matron extends Nurse Consultant extends Doctor Nurse extends HumanEntity Doctor extends HumanEntity HumanEntity extends DatabaseTable DatabaseTable extends AbstractTable
등등.
-
==============================
3.PHP 5.4에서 사용할 수있는 특성을 사용할 수 있습니다.
PHP 5.4에서 사용할 수있는 특성을 사용할 수 있습니다.
특성은 PHP와 같은 단일 상속 언어에서 코드 재사용을위한 메커니즘입니다. 특성은 개발자가 다른 클래스 계층에있는 여러 개의 독립적 인 클래스에서 메서드 집합을 자유롭게 다시 사용할 수있게하여 단일 상속의 일부 제한을 줄이기위한 것입니다. 특성과 클래스의 조합의 의미는 복잡성을 줄이고 다중 상속 및 Mixins과 관련된 일반적인 문제를 피하는 방식으로 정의됩니다.
그들은 Perl 6, Squeak, Scala, Slate 및 Fortress와 같은 최신 버전의 언어로 통합하여 더 나은 구성 및 재사용을 지원할 수있는 잠재력으로 인정 받고 있습니다. 형질 또한 자바와 C #으로 이식되었습니다.
추가 정보 : https://wiki.php.net/rfc/traits
-
==============================
4.클래스는 메서드 모음 일뿐입니다. 클래스는 상태를 변경하는 상태 (필드)와 동작 (메서드)을 모두 가진 추상 개념을 나타냅니다. 상속을 사용하여 원하는 OO 디자인과 같은 몇 가지 원하는 동작을 얻으십시오. 많은 언어가 다중 상속을 허용하지 않는 이유는 정확히 "스파게티 상속"을 방지하기 위해서입니다. 즉, 각각 필요한 메서드가 있기 때문에 3 개의 클래스를 확장하고 100 개의 메서드와 20 개의 필드를 상속하는 클래스이며, 5 개만 사용합니다.
클래스는 메서드 모음 일뿐입니다. 클래스는 상태를 변경하는 상태 (필드)와 동작 (메서드)을 모두 가진 추상 개념을 나타냅니다. 상속을 사용하여 원하는 OO 디자인과 같은 몇 가지 원하는 동작을 얻으십시오. 많은 언어가 다중 상속을 허용하지 않는 이유는 정확히 "스파게티 상속"을 방지하기 위해서입니다. 즉, 각각 필요한 메서드가 있기 때문에 3 개의 클래스를 확장하고 100 개의 메서드와 20 개의 필드를 상속하는 클래스이며, 5 개만 사용합니다.
-
==============================
5.곧 믹스 인을 추가 할 계획이 있다고 믿습니다.
곧 믹스 인을 추가 할 계획이 있다고 믿습니다.
그러나 그때까지 받아 들여진 대답으로 가십시오. "확장 가능"클래스를 만들기 위해 조금 추상화 할 수 있습니다.
class Extendable{ private $extender=array(); public function addExtender(Extender $obj){ $this->extenders[] = $obj; $obj->setExtendee($this); } public function __call($name, $params){ foreach($this->extenders as $extender){ //do reflection to see if extender has this method with this argument count if (method_exists($extender, $name)){ return call_user_func_array(array($extender, $name), $params); } } } } $foo = new Extendable(); $foo->addExtender(new OtherClass()); $foo->other_class_method();
이 모델에서 "OtherClass"는 $ foo에 대해 '알아'옵니다. OtherClass에는이 관계를 설정하기 위해 "setExtendee"라는 public 함수가 있어야합니다. 그런 다음 메서드가 $ foo에서 호출되면 내부적으로 $ foo에 액세스 할 수 있습니다. 그러나 실제 확장 클래스처럼 개인 / 보호 된 메소드 / 변수에 액세스 할 수는 없습니다.
-
==============================
6.필자는 라이브러리 / 프레임 워크와 달리 프로젝트에서 상속을 방해하는 몇 가지 기사를 읽었으며 구현에 반대하여 agaisnt 인터페이스를 프로그래밍하도록 권장했습니다. 그들은 또한 작곡을 통해 OO를지지합니다 : 클래스 a와 b에서 함수가 필요한 경우이 유형의 멤버 / 필드가있는 c를 만듭니다.
필자는 라이브러리 / 프레임 워크와 달리 프로젝트에서 상속을 방해하는 몇 가지 기사를 읽었으며 구현에 반대하여 agaisnt 인터페이스를 프로그래밍하도록 권장했습니다. 그들은 또한 작곡을 통해 OO를지지합니다 : 클래스 a와 b에서 함수가 필요한 경우이 유형의 멤버 / 필드가있는 c를 만듭니다.
class C { private $a, $b; public function __construct($x, $y) { $this->a = new A(42, $x); $this->b = new B($y); } protected function DoSomething() { $this->a->Act(); $this->b->Do(); } }
-
==============================
7.@Franck에 의해 현재 받아 들여지는 대답은 작동하지만 실제로는 다중 상속이 아니라 범위에서 정의 된 클래스의 자식 인스턴스이며 __call () 약식도 있습니다 - $ this-> childInstance-> method (args) 어디서나 "확장 된"클래스에서 ExternalClass 클래스 메서드가 필요합니다.
@Franck에 의해 현재 받아 들여지는 대답은 작동하지만 실제로는 다중 상속이 아니라 범위에서 정의 된 클래스의 자식 인스턴스이며 __call () 약식도 있습니다 - $ this-> childInstance-> method (args) 어디서나 "확장 된"클래스에서 ExternalClass 클래스 메서드가 필요합니다.
아니, 당신은 할 수 없다 각각, 실제로, 확장 키워드의 설명서로 말합니다 :
그러나 @adam이 올바르게 제안 했으므로 다중 계층 상속을 사용하는 것이 금지되지 않습니다.
당신은 하나의 클래스를 다른 클래스와 다른 클래스로 확장 할 수 있습니다.
이것에 대한 아주 간단한 예제는 다음과 같습니다.
class firstInheritance{} class secondInheritance extends firstInheritance{} class someFinalClass extends secondInheritance{} //...and so on...
이미 알고 계시 겠지만, 프로세스에 포함 된 모든 클래스를 제어 할 수 있다면 계층별로 여러 가지 (2+ 개)의 intehritance 만 수행 할 수 있습니다. 즉,이 솔루션을 적용 할 수 없습니다. 빌트인 클래스 나 단순히 편집 할 수없는 클래스가 있습니다. 그렇게하고 싶다면 @Franck 솔루션 - 하위 인스턴스가 있습니다.
... 그리고 마지막으로 몇 가지 출력 예제 :
class A{ function a_hi(){ echo "I am a of A".PHP_EOL."<br>".PHP_EOL; } } class B extends A{ function b_hi(){ echo "I am b of B".PHP_EOL."<br>".PHP_EOL; } } class C extends B{ function c_hi(){ echo "I am c of C".PHP_EOL."<br>".PHP_EOL; } } $myTestInstance = new C(); $myTestInstance->a_hi(); $myTestInstance->b_hi(); $myTestInstance->c_hi();
어느 출력
I am a of A I am b of B I am c of C
-
==============================
8.
<?php // what if we want to extend more then one class? Abstract class ExtensionBridge { // array containing all the extended classes private $_exts = array(); public $_this; function __construct(){$_this = $this;} public function addExt($object) { $this->_exts[]=$object; } public function __get($varname) { foreach($this->_exts as $ext) { if(property_exists($ext,$varname)) return $ext->$varname; } } public function __call($method,$args) { foreach($this->_exts as $ext) { if(method_exists($ext,$method)) return call_user_method_array($method,$ext,$args); } throw new Exception("This Method {$method} doesn't exists"); } } class Ext1{ private $name=""; private $id=""; public function setID($id){$this->id = $id;} public function setName($name){$this->name = $name;} public function getID(){return $this->id;} public function getName(){return $this->name;} } class Ext2{ private $address=""; private $country=""; public function setAddress($address){$this->address = $address;} public function setCountry($country){$this->country = $country;} public function getAddress(){return $this->address;} public function getCountry(){return $this->country;} } class Extender extends ExtensionBridge { function __construct() { parent::addExt(new Ext1()); parent::addExt(new Ext2()); } public function __toString() { return $this->getName().', from: '.$this->getCountry(); } } $o = new Extender(); $o->setName("Mahdi"); $o->setCountry("Al-Ahwaz"); echo $o; ?>
-
==============================
9.특성을 기본 클래스로 사용하십시오. 그런 다음 상위 클래스에서 사용하십시오. 그것을 확장하십시오.
특성을 기본 클래스로 사용하십시오. 그런 다음 상위 클래스에서 사용하십시오. 그것을 확장하십시오.
trait business{ function sell(){ } function buy(){ } function collectMoney(){ } } trait human{ function think(){ } function speak(){ } } class BusinessPerson{ use business; use human; // If you have more traits bring more } class BusinessWoman extends BusinessPerson{ function getPregnant(){ } } $bw = new BusinessWoman(); $bw ->speak(); $bw->getPregnant();
지금보십시오 비즈니스 여성은 논리적으로 상속 된 비즈니스 및 인간 모두입니다.
-
==============================
10.다중 상속은 인터페이스 수준에서 작동하는 것 같습니다. 나는 PHP 5.6.1에서 테스트를했다.
다중 상속은 인터페이스 수준에서 작동하는 것 같습니다. 나는 PHP 5.6.1에서 테스트를했다.
다음은 작동하는 코드입니다.
<?php interface Animal { public function sayHello(); } interface HairyThing { public function plush(); } interface Dog extends Animal, HairyThing { public function bark(); } class Puppy implements Dog { public function bark() { echo "ouaf"; } public function sayHello() { echo "hello"; } public function plush() { echo "plush"; } } echo PHP_VERSION; // 5.6.1 $o = new Puppy(); $o->bark(); $o->plush(); $o->sayHello(); // displays: 5.6.16ouafplushhello
가능하다고 생각하지는 않았지만 SwiftMailer 소스 코드 Swift_Transport_IoBuffer 클래스에서 다음과 같은 정의가 있습니다.
interface Swift_Transport_IoBuffer extends Swift_InputByteStream, Swift_OutputByteStream
나는 아직 그걸 가지고 놀지 못했지만, 나는 그것을 나누는 것이 재미있을 것이라고 생각했습니다.
-
==============================
11.방금 "다중 상속"문제를 해결했습니다.
방금 "다중 상속"문제를 해결했습니다.
class Session { public $username; } class MyServiceResponsetype { protected $only_avaliable_in_response; } class SessionResponse extends MyServiceResponsetype { /** has shared $only_avaliable_in_response */ public $session; public function __construct(Session $session) { $this->session = $session; } }
이 방법으로 MyServiceResponsetype을 확장 한 SessionResponse 내부에서 세션을 조작 할 수있는 능력이 있으며 여전히 Session을 자체적으로 처리 할 수 있습니다.
-
==============================
12.PHP 5.4에서 발표 된 PHP의 특성을 사용하여이를 수행 할 수 있습니다.
PHP 5.4에서 발표 된 PHP의 특성을 사용하여이를 수행 할 수 있습니다.
다음은 빠른 자습서입니다. http://culttt.com/2014/06/25/php-traits/
-
==============================
13.PHP는 아직 다중 클래스 상속을 지원하지 않지만 다중 인터페이스 상속을 지원합니다.
PHP는 아직 다중 클래스 상속을 지원하지 않지만 다중 인터페이스 상속을 지원합니다.
몇 가지 예를 보려면 http://www.hudzilla.org/php/6_17_0.php를 참조하십시오.
-
==============================
14.PHP는 다중 상속을 허용하지 않지만, 다중 인터페이스를 구현하는 것으로 할 수 있습니다. 구현이 "무거운"경우 별도의 클래스에있는 각 인터페이스에 골격 구현을 제공하십시오. 그런 다음 모든 객체 클래스를 객체 포함을 통해 이러한 스켈 레탈 구현에 위임 할 수 있습니다.
PHP는 다중 상속을 허용하지 않지만, 다중 인터페이스를 구현하는 것으로 할 수 있습니다. 구현이 "무거운"경우 별도의 클래스에있는 각 인터페이스에 골격 구현을 제공하십시오. 그런 다음 모든 객체 클래스를 객체 포함을 통해 이러한 스켈 레탈 구현에 위임 할 수 있습니다.
-
==============================
15.당신이 달성하고자하는 것을 정확히 알지 못한다면,이 경우에는 상속이 아닌 구성을 사용하도록 응용 프로그램을 재 설계 할 가능성을 조사하는 것이 좋습니다.
당신이 달성하고자하는 것을 정확히 알지 못한다면,이 경우에는 상속이 아닌 구성을 사용하도록 응용 프로그램을 재 설계 할 가능성을 조사하는 것이 좋습니다.
-
==============================
16.항상 좋은 아이디어는 기능을 가진 부모 클래스를 만드는 것입니다. 즉 부모에게이 모든 기능을 추가하는 것입니다.
항상 좋은 아이디어는 기능을 가진 부모 클래스를 만드는 것입니다. 즉 부모에게이 모든 기능을 추가하는 것입니다.
이 계층을 사용하는 모든 클래스를 "이동"합니다. 필자는 특정 기능을 다시 작성해야합니다.
-
==============================
17.함수가 공개되어 있는지 확인하려면이 항목을 참조하십시오. https://stackoverflow.com/a/4160928/2226755
함수가 공개되어 있는지 확인하려면이 항목을 참조하십시오. https://stackoverflow.com/a/4160928/2226755
그리고 많은 인수에 대해 call_user_func_array (...) 메소드를 사용하십시오.
이렇게 :
class B { public function method_from_b($s) { echo $s; } } class C { public function method_from_c($l, $l1, $l2) { echo $l.$l1.$l2; } } class A extends B { private $c; public function __construct() { $this->c = new C; } public function __call($method, $args) { if (method_exists($this->c, $method)) { $reflection = new ReflectionMethod($this->c, $method); if (!$reflection->isPublic()) { throw new RuntimeException("Call to not public method ".get_class($this)."::$method()"); } return call_user_func_array(array($this->c, $method), $args); } else { throw new RuntimeException("Call to undefined method ".get_class($this)."::$method()"); } } } $a = new A; $a->method_from_b("abc"); $a->method_from_c("d", "e", "f");
-
==============================
18.프로그래밍 언어로서의 PHP의 문제점 중 하나는 하나의 상속만을 가질 수 있다는 것입니다. 즉, 클래스는 하나의 다른 클래스에서만 상속받을 수 있습니다.
프로그래밍 언어로서의 PHP의 문제점 중 하나는 하나의 상속만을 가질 수 있다는 것입니다. 즉, 클래스는 하나의 다른 클래스에서만 상속받을 수 있습니다.
그러나 많은 시간을 여러 클래스에서 상속하는 것이 유익 할 것입니다. 예를 들어, 코드 중복을 방지하기 위해 여러 클래스의 메소드를 상속하는 것이 바람직 할 수 있습니다.
이 문제는 종종 합리적이지 않은 상속에 대한 가족력이 긴 클래스로 이어질 수 있습니다.
PHP 5.4에서 새로운 언어 기능이 Traits로 추가되었습니다. Trait은 Trait 클래스를 기존 클래스에 혼합 할 수있는 Mixin과 비슷합니다. 즉, 다중 상속 문제를 피하면서 코드 중복을 줄이고 이점을 얻을 수 있습니다.
형질
-
==============================
19.인터페이스는 실제로 나를 똑같은 방식으로 다시 구현하도록 강요하고 다시 알림 또는 TODO 주석으로 사용하기 때문에 논리적 의미를 형성하는 데 무의미합니다. 그것은 나쁘지 않다고 말하지만 논리적 인면은 파이썬이 아마이 문제에 대한 최상의 해결책이라고 생각하는 다이아몬드 문제를 피하는 것입니다. 함수 본문을 계속해서 다시 작성할 필요는 없습니다. 실행할 상위 호출자를 선택할 수 있습니다.
인터페이스는 실제로 나를 똑같은 방식으로 다시 구현하도록 강요하고 다시 알림 또는 TODO 주석으로 사용하기 때문에 논리적 의미를 형성하는 데 무의미합니다. 그것은 나쁘지 않다고 말하지만 논리적 인면은 파이썬이 아마이 문제에 대한 최상의 해결책이라고 생각하는 다이아몬드 문제를 피하는 것입니다. 함수 본문을 계속해서 다시 작성할 필요는 없습니다. 실행할 상위 호출자를 선택할 수 있습니다.
예를 들어 Herbivore 클래스와 Carnivore 클래스와 Omnivore 클래스 모두 param 음식을 먹는 함수를 먹는다면,이 경우 Omnivore에서 먹기를 다시 먹어야합니다. Herbivore 먹거나 Carnivore 먹는 잡식 동물 먹는 것보다 .
class Herbivore: def eat(self, food): print("Food is supposed to be vegan") class Carnivore: def eat(self, food): print("Food is supposed to be meaty") class Omnivore(Carnivore, Herbivore): def eat(self, food): #Test the food type and call function for either #Carnivore.eat(food) #Herbivore.eat(food) #There is no actual re-implementation of the action print("Food has to either bee meaty or vegan")
-
==============================
20.클래스 A는 B {}를 확장합니다.
클래스 A는 B {}를 확장합니다.
클래스 B는 C {}를 확장합니다.
그런 다음 A가 B와 C를 모두 확장했습니다.
from https://stackoverflow.com/questions/356128/can-i-extend-a-class-using-more-than-1-class-in-php by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
배열 요소를 제거한 다음 배열의 색인을 다시 생성하는 방법 (0) | 2018.09.20 |
---|---|
PHPMailer - SMTP 오류 : 서버에서 메일을 보낼 때 비밀번호 명령이 실패했습니다. (0) | 2018.09.20 |
cURL을 사용하여 jSON 데이터를 얻고 데이터를 디코딩하는 방법 (0) | 2018.09.20 |
PHP와 fgetcsv 함수를 사용하여 CSV 파일에서 배열을 만드는 법 (0) | 2018.09.20 |
새 줄로 PHP 문자열 분해 (0) | 2018.09.20 |