2009-12-05 51 views
6

嗨,我對PHP非常有經驗,但我不知道關鍵字抽象在面向對象編程時做了什麼。任何人都可以用簡單的英文解釋它可以用於什麼?在PHP中抽象關鍵字

我會在什麼情況下使用抽象關鍵字?它如何改變類/接口?

回答

15

(希望這是很簡單 - 我不認爲我可以做的更好^^)

abstract類不能被實例化:您只能創建另一個類從abstract類繼承,並instanciate那個孩子班。

而且如果你聲明一些方法爲abstract,那些必須在子類中定義,因爲那個方法是可實現的。

7

聲明一個類抽象意味着它必須被子類化才能被使用。抽象類不能被實例化。人們可以將它看作是一個擴展的接口,可能包含實現代碼(而不是接口)。

通過聲明方法摘要,可以強制子類實現該方法。

0

雖然無法實例化一個抽象類,可以聲明混凝土方法/屬性/變量(在C#,AFAIK),其將提供給

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

的定義上面提到的派生類,現在我將嘗試給你一個例子:

「抽象」確保你遵循特定的邏輯,例如一張票的材料總是「紙」,或一張信用卡必須始終有一個「代碼」。 如果你在一個嚴格標準化的大公司工作,或者如果你想'迫使'你的開發者遵循一個特定的結構,這是非常重要的,所以他們的代碼不會一團糟。

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; 
    } 
} 

如果我們沒有定義「setCode」方法解析器將在「new anotherKey

1

抽象類主要用於一類 - 的模型有實際聯繫的返回一個錯誤。這允許例如數據庫驅動程序來映射層次結構,其目的在於提供公共基類和實際驅動程序類的方法的簽名。然後根據實際駕駛員等級中的預定簽名執行該實施。

這裏是代碼示例

<?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

....德語)Sieht人票數澤爾滕 – 2009-12-05 14:04:00

+0

ACH所以;-)抱歉意願不會再發生下一次;-) – streetparade 2009-12-05 14:12:40

+0

沒問題;)我也來自德國。我只想提到你在你的示例代碼中編寫了德語,如果非德語程序員試圖理解你的類的實際命名,這可能會引起某種混淆。 – 2009-12-05 14:14:42

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.無法實例抽象類:定義爲抽象類可以不被實例化,並含有至少一個抽象方法的任何類也必須是抽象。下面

實施例:

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。任何包含至少一個抽象方法的類也必須是抽象的:抽象類可以具有抽象和非抽象方法,但它必須至少包含一個抽象方法。如果一個類至少有一個抽象方法,那麼該類必須聲明爲抽象的。下面

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

實施例:

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.一種抽象方法不能包含體:定義爲抽象方法簡單地聲明方法的簽名 - 它們不能定義實施。但是一個非抽象的方法可以定義實現。

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.當從一個抽象類繼承,所有的方法標誌着父類聲明抽象須由孩子定義:如果你繼承一個抽象類,你必須提供實現所有的抽象方法在裏面。

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.相同(或較少限制的)的可見性:當從一個抽象類繼承,所有的方法標示在父類聲明抽象必須由兒童來限定;另外,這些方法必須用相同(或更少限制)的可見性來定義。例如,如果抽象方法被定義爲受保護的,則必須將函數實現定義爲protected或public,但不是私有的。

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的抽象方法的簽名必須匹配:當從一個抽象類繼承,所有的方法標誌着父類聲明抽象必須由孩子來定義;的方法的簽名必須匹配,即類型提示和所需參數的數量必須相同。例如,如果子類定義了可選參數(抽象方法的簽名不存在),則簽名中不會有衝突。

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.抽象類不支持多重繼承:抽象類可以擴展另一個抽象類,抽象類可以提供interface.But執行它不支持多重繼承。

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.

示例將導致下面致命錯誤:類 '馬' 未找到

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());