2009-12-05 22 views
6

Ehi, ho abbastanza esperienza con PHP, ma non ho idea di cosa faccia la parola chiave abstract quando si tratta di programmazione orientata agli oggetti. Qualcuno può spiegare in inglese semplice su cosa può essere usato?Parola chiave astratta in PHP

In quali situazioni dovrei utilizzare la parola chiave astratta? Come cambia la classe/l'interfaccia?

risposta

15

(Spero che questo è abbastanza semplice - non penso che posso fare meglio ^^)

Una classe abstract non può essere istanziare: è possibile creare solo un'altra classe che eredita dalla classe abstract e instanziate quella classe bambino.

E se si dichiarano alcuni metodi come abstract, quelli devono essere definiti nella classe figlio, affinché quello sia instanciable.

7

Dichiarare un abstract di classe significa che deve essere sottoclasse per poter essere utilizzato. Una classe astratta non può essere istanziata. Si può vedere come un'interfaccia estesa che potrebbe includere il codice di implementazione (al contrario di un'interfaccia).

Dichiarando un metodo abstract, si forza la sottoclasse a implementare il metodo.

0

Anche se non è possibile creare un'istanza di una classe astratta, è possibile dichiarare concreti metodi/proprietà/variabili (in C#, per quanto ne so) che sarà disponibile per la classe derivata

class Program 
    { 
     static void Main(string[] args) 
     { 
      Dog a = new Dog(); 
      //concrete properties and methods in abstract base class 
      //are available to derived class 
      a.Name = "SuperDog"; 
      a.EatFood(); 
      //And now calling Dog's method 
      a.Speak();    
      Console.WriteLine(a.GetType()); 

     } 
    } 

    public abstract class Animal 
    { 
     public string Name { get; set; } 
     public void EatFood() 
     { 
      Console.WriteLine("Eating.."); 
     } 
    } 

    public class Dog :Animal 
    { 
     public void Speak() 
     { 
      Console.WriteLine("Bow .. Bow"); 
     } 
    } 
1

La definizione è menzionato in precedenza, ora io cercherò di darvi un esempio:

"abstract" garantisce di seguire una logica specifica, ad es. il materiale di un biglietto è SEMPRE "carta", o una carta di credito deve sempre avere un "codice". Questo è importante se lavori in una grande azienda che ha una rigorosa standardizzazione o se vuoi forzare i tuoi sviluppatori a seguire una struttura specifica, quindi il loro codice non finirà in un casino.

abstract class ticket{ 

    public function material() 
    { 
     return 'Paper'; 
    } 

} 

abstract class creditcard{ 

    public function material() 
    { 
     return 'Plastic'; 
    } 

    abstract function setCode(); // the ";" semicolon is important otherwise it will cause an error 

} 

class key extends ticket{ 

    public function getMaterial() 
    { 
     return parent::material(); 
    } 
} 

class anotherKey extends creditcard{ 

    public function setCode($code) 
    { 
     $this->code = $code; 
    } 
} 

Se noi non definiamo il metodo "setCode" il parser restituirà un errore su "new anotherKey"

1

Le classi astratte sono utilizzati per una relazione reale a-kind-of-modello. Ciò consente ad esempio un driver di database per mappare la gerarchia, in cui mira a fornire una classe base comune, le firme per i metodi delle classi di driver effettive. L'implementazione viene quindi eseguita in base alle firme predeterminate nelle classi di conducente effettive.

qui è esempio di codice

<?php 
abstract class AbstrakteKlasse { 
    public abstract function methode(); 
} 

class ImplementierendeKlasse extends AbstrakteKlasse { 
    public function methode() { 
    print "ImplementierendeKlasse::methode() aufgerufen.\n"; 
    } 
} 

$objekt = new ImplementierendeKlasse; 
$objekt->methode(); 
?> 
+0

.... Deutsch;) Sieht man hier selten –

+0

Ach so ;-) dispiace volontà non succederà la prossima volta ;-) – streetparade

+0

Nessun problema;) Vengo anche dalla Germania. Volevo solo menzionare che hai scritto tedesco nel tuo codice di esempio, il che potrebbe causare una sorta di confusione se un programmatore non tedesco cerca di capire l'effettiva denominazione delle tue classi. –

0

Abstract classes are classes that contain one or more abstract methods. An abstract method is a method that is declared, but contains no implementation. Abstract classes may not be instantiated, and require subclasses to provide implementations for the abstract methods.

1. Non può un'istanza di classe astratta: classi definite come astratta non può essere istanziato, e ogni classe che contiene almeno un metodo astratto deve anche essere astratto.

Esempio sotto:

abstract class AbstractClass 
{ 

    abstract protected function getValue(); 
    abstract protected function prefixValue($prefix); 


    public function printOut() { 
     echo "Hello how are you?"; 
    } 
} 

$obj=new AbstractClass(); 
$obj->printOut(); 
//Fatal error: Cannot instantiate abstract class AbstractClass 

2.Qualsiasi classe che contenga almeno un metodo astratto deve anche essere astratta: la classe astratta può avere metodi astratti e non astratti, ma deve contenere almeno un metodo astratto. Se una classe ha almeno un metodo astratto, la classe deve essere dichiarata astratta.

Note: Traits support the use of abstract methods in order to impose requirements upon the exhibiting class.

Esempio di seguito:

class Non_Abstract_Class 
{ 
    abstract protected function getValue(); 

    public function printOut() { 
     echo "Hello how are you?"; 
    } 
} 

$obj=new Non_Abstract_Class(); 
$obj->printOut(); 
//Fatal error: Class Non_Abstract_Class contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Non_Abstract_Class::getValue) 

3. Un metodo astratto non può contenere il corpo: Metodi definiti come astratto dichiarano semplicemente la firma del metodo - che non possono definire l'attuazione. Ma un metodo non astratto può definire l'implementazione.

abstract class AbstractClass 
{ 
    abstract protected function getValue(){ 
    return "Hello how are you?"; 
    } 

    public function printOut() { 
     echo $this->getValue() . "\n"; 
    } 
} 

class ConcreteClass1 extends AbstractClass 
{ 
    protected function getValue() { 
     return "ConcreteClass1"; 
    } 

    public function prefixValue($prefix) { 
     return "{$prefix}ConcreteClass1"; 
    } 
} 

$class1 = new ConcreteClass1; 
$class1->printOut(); 
echo $class1->prefixValue('FOO_') ."\n"; 
//Fatal error: Abstract function AbstractClass::getValue() cannot contain body 

4. Quando si eredita da una classe astratta, tutti i metodi contrassegnati astratto nella dichiarazione di classe dei genitori deve essere definito dal bambino: Se si eredita una classe astratta è necessario fornire implementazioni a tutti i metodi astratti dentro.

abstract class AbstractClass 
{ 
    // Force Extending class to define this method 
    abstract protected function getValue(); 

    // Common method 
    public function printOut() { 
     print $this->getValue() . "<br/>"; 
    } 
} 

class ConcreteClass1 extends AbstractClass 
{ 
    public function printOut() { 
     echo "swat"; 
    } 

} 
$class1 = new ConcreteClass1; 
$class1->printOut(); 
//Fatal error: Class ConcreteClass1 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (AbstractClass::getValue) 

5. Stesso (o meno limitata) visibilità: Quando si eredita da una classe astratta, tutti i metodi contrassegnati astratto nella dichiarazione di classe dei genitori deve essere definito dal bambino; inoltre, questi metodi devono essere definiti con la stessa (o meno limitata) visibilità. Ad esempio, se il metodo astratto è definito come protetto, l'implementazione della funzione deve essere definita come protetta o pubblica, ma non privata.

Note that abstract method should not be private.

abstract class AbstractClass 
{ 

    abstract public function getValue(); 
    abstract protected function prefixValue($prefix); 

     public function printOut() { 
     print $this->getValue(); 
    } 
} 

class ConcreteClass1 extends AbstractClass 
{ 
    protected function getValue() { 
     return "ConcreteClass1"; 
    } 

    public function prefixValue($prefix) { 
     return "{$prefix}ConcreteClass1"; 
    } 
} 
$class1 = new ConcreteClass1; 
$class1->printOut(); 
echo $class1->prefixValue('FOO_') ."<br/>"; 
//Fatal error: Access level to ConcreteClass1::getValue() must be public (as in class AbstractClass) 

6. Firma dei metodi astratti devono corrispondere: Quando si eredita da una classe astratta, tutti i metodi contrassegnati astratto nella dichiarazione di classe dei genitori deve essere definito dal bambino; ​​le firme dei metodi deve coincidere, cioè i tipi hint e il numero di argomenti richiesti devono essere gli stessi. Ad esempio, se la classe figlio definisce un argomento facoltativo, in cui la firma del metodo astratto non lo fa, non c'è conflitto nella firma.

abstract class AbstractClass 
{ 

    abstract protected function prefixName($name); 

} 

class ConcreteClass extends AbstractClass 
{ 


    public function prefixName($name, $separator = ".") { 
     if ($name == "Pacman") { 
      $prefix = "Mr"; 
     } elseif ($name == "Pacwoman") { 
      $prefix = "Mrs"; 
     } else { 
      $prefix = ""; 
     } 
     return "{$prefix}{$separator} {$name}"; 
    } 
} 

$class = new ConcreteClass; 
echo $class->prefixName("Pacman"), "<br/>"; 
echo $class->prefixName("Pacwoman"), "<br/>"; 
//output: Mr. Pacman 
//  Mrs. Pacwoman 

7. astratta classe non supporta l'ereditarietà multipla: Estratto classe può estende un'altra classe astratta, astratto di classe in grado di fornire l'implementazione di interface.But non supporta l'ereditarietà multipla.

interface MyInterface{ 
    public function foo(); 
    public function bar(); 
} 

abstract class MyAbstract1{ 
    abstract public function baz(); 
} 


abstract class MyAbstract2 extends MyAbstract1 implements MyInterface{ 
    public function foo(){ echo "foo"; } 
    public function bar(){ echo "bar"; } 
    public function baz(){ echo "baz"; } 
} 

class MyClass extends MyAbstract2{ 
} 

$obj=new MyClass; 
$obj->foo(); 
$obj->bar(); 
$obj->baz(); 
//output: foobarbaz 

Note: Please note order or positioning of the classes in your code can affect the interpreter and can cause a Fatal error. So, when using multiple levels of abstraction, be careful of the positioning of the classes within the source code.

sotto esempio causerà Fatal error: 'cavallo' di classe non trovata

class cart extends horse { 
    public function get_breed() { return "Wood"; } 
} 

abstract class horse extends animal { 
    public function get_breed() { return "Jersey"; } 
} 

abstract class animal { 
    public abstract function get_breed(); 
} 

$cart = new cart(); 
print($cart->get_breed());