2010-02-12 17 views
39

W PHP, czy mogę określić interfejs mieć pola, lub są interfejsy PHP ograniczone do funkcji?PHP: Czy mogę używać pól w interfejsach?

<?php 
interface IFoo 
{ 
    public $field; 
    public function DoSomething(); 
    public function DoSomethingElse(); 
} 
?> 

Jeśli nie, zdaję sobie sprawę, mogę narazić getter jako funkcji w interfejsie:

public GetField(); 
+0

Ostrzeżenie: jeśli uzyskasz głosowanie w dół za pytanie, nie należy się dziwić - zajrzyj do sekcji OOP podręcznika PHP. – Andreas

+3

Tak, szybkie skanowanie podręcznika pokazało, że używają tylko funkcji w interfejsach. Może właśnie przeskoczyłem tę część. W obu przypadkach chciałem tylko upewnić się. – Scott

Odpowiedz

11

Interfejsy są przeznaczone wyłącznie do wspierania metod.

Dzieje się tak dlatego, że interfejsy istnieją w celu udostępnienia publicznego interfejsu API, do którego mogą uzyskać dostęp inne obiekty.

Właściwości publicznie dostępne naruszyłyby hermetyzację danych w klasie implementującej interfejs.

5

nie można określić właściwości w interface: tylko metody są dozwolone (i sensu, jako cel interfejsu jest określenie API)


w PHP, próbując zdefiniować właściwości w interfejs powinien podnieść Fatal Error: ten fragment kodu:

interface A { 
    public $test; 
} 

da Ci:

Fatal error: Interfaces may not include member variables in... 
14

Późne odpowiedź, ale aby uzyskać funkcjonalność chciał tutaj, może warto rozważyć abstrakcyjną klasę zawierającą swoich pól. Abstrakcyjna klasa będzie wyglądać następująco:

abstract class Foo 
{ 
    public $member; 
} 

Chociaż można nadal mieć interfejs:

interface IFoo 
{ 
    public function someFunction(); 
} 

wtedy masz swoją klasę dziecko tak:

class bar extends Foo implements IFoo 
{ 
    public function __construct($memberValue = "") 
    { 
     // Set the value of the member from the abstract class 
     $this->member = $memberValue; 
    } 

    public function someFunction() 
    { 
     // Echo the member from the abstract class 
     echo $this->member; 
    } 
} 

istnieje alternatywne rozwiązanie dla osób wciąż ciekawych i zainteresowanych. :)

+3

Jestem ciekawy i zainteresowany. Jak zagwarantować obecność członka? :) – deb0rian

+0

Klasa 'Foo' powinna zaimplementować interfejs 'IFoo', jest abstrakcyjna i jasno pokazałaby cel' Foo': po prostu implementację interfejsu. –

+0

Uzgodnione, @PeterM. Klasa abstrakcyjna może równie dobrze implementować interfejs zamiast ostatniej klasy. W zależności od tego, czy zawsze chcesz być zmuszony do implementacji 'someFunction()'. –

11

Użyj programu ustawiającego. Ale może to być uciążliwe w implementowaniu wielu modułów pobierających i ustawiających w wielu klasach, a także zaśmiecać kod klasy. I you repeat yourself!

W PHP 5.4 można użyć traits zapewnienie pól i metod do klas, a mianowicie:

interface IFoo 
{ 
    public function DoSomething(); 
    public function DoSomethingElse(); 
    public function setField($value); 
    public function getField(); 
} 

trait WithField 
{ 
    private $_field; 
    public function setField($value) 
    { 
     $this->_field = $value; 
    } 
    public function getField() 
    { 
     return $this->field; 
    } 
} 

class Bar implements IFoo 
{ 
    use WithField; 

    public function DoSomething() 
    { 
     echo $this->getField(); 
    } 
    public function DoSomethingElse() 
    { 
     echo $this->setField('blah'); 
    } 
} 

Jest to szczególnie przydatne, jeśli masz dziedziczyć z jakiejś klasie bazowej i trzeba wdrożyć jakiś interfejs.

class CooCoo extends Bird implements IFoo 
{ 
    use WithField; 

    public function DoSomething() 
    { 
     echo $this->getField(); 
    } 
    public function DoSomethingElse() 
    { 
     echo $this->setField('blah'); 
    } 
} 
+0

OK, ale moim zdaniem klasa abstrakcyjna jest bardziej czytelna. –

+1

Ale z klasą abstrakcyjną można dziedziczyć tylko z tej klasy. Dzięki cechom i interfejsom masz rodzaj dziedziczenia mnogiego. Ill dodaj go, aby odpowiedzieć. –

Powiązane problemy