2011-06-16 7 views
25

thể trùng lặp:
interface vs abstract classLợi thế nếu tôi sử dụng lớp trừu tượng trong php là gì?

lợi thế là gì nếu tôi sử dụng lớp trừu tượng trong php?

Mục đích của tôi là gì nếu tôi sử dụng lớp học hoặc giao diện trừu tượng ?

Cả hai chỉ đơn giản là tạo defenition tên với cơ thể ra

+1

nhiều hơn: http://stackoverflow.com/search?q=abstract+class+interface+php – Gordon

+0

Ya tôi hiểu .. muốn đóng câu hỏi – Sreeraj

+4

Bah, sau khi tôi dành mười phút để viết câu trả lời? :( –

Trả lời

63

Lợi thế nếu tôi sử dụng lớp trừu tượng trong php là gì? tôi không thể tìm thấy bất cứ điều gì tốt về điều đó. Tôi nghĩ rằng tôi có thể dễ dàng làm tất cả các công việc với ra bằng cách sử dụng lớp trừu tượng?

Bạn có thể, một cách tự nhiên. Tuy nhiên, nếu có nhiều đối tượng có cùng loại khá nhiều, nó có thể giúp trích xuất các chức năng chung thành một lớp "cơ sở", có nghĩa là bạn không phải sao chép logic đó.

Thực tế, có hai lý do. Lý do đầu tiên, đối với tôi, sẽ là tất cả các hậu duệ của lớp trừu tượng của bạn có cùng một loại và cả hai đều tuân thủ cùng một giao diện chính xác. Điều đó có nghĩa là một tài liệu PDF ví dụ sẽ có giao diện giống như một tài liệu docx, và mã máy khách không phải quan tâm đối tượng đó đang xử lý. Ví dụ ngắn (bằng PHP).

<?php 
abstract class Document { 
    protected $author; 

    public function __construct($author) { 
     $this->author = $author; 
    } 

    abstract public function render(); 

    public function author() { 
     return $this->author; 
    } 
} 

class PdfDocument extends Document { 
    public function render() { 
     // do something PDF specific here. 
    } 
} 

class DocxDocument extends Document { 
    public function render() { 
     // do something DOCX specific here. 
    } 
} 


class DocumentHandler { 
    public function handle(Document $document) { 
     $this->log('Author has been read ' . $document->author()); 
     return $document->render(); 
    } 
} 

Trước hết; hãy nhớ rằng lớp DocumentHandler không có kiến ​​thức về loại tài liệu mà nó thực sự xử lý. Nó thậm chí không quan tâm. Nó dốt nát. Tuy nhiên, nó không biết phương thức nào có thể được gọi, bởi vì giao diện giữa hai loại tài liệu giống nhau. Điều này được gọi là đa hình và có thể dễ dàng đạt được với việc triển khai giao diện Tài liệu.

Phần thứ hai là; nếu mỗi và mọi tài liệu đều có tác giả và tác giả đó luôn được yêu cầu, bạn có thể sao chép phương thức sang PdfDocument cũng như DocxDocument, nhưng bạn sẽ tự sao chép chính mình. Ví dụ, nếu bạn quyết định rằng bạn muốn tác giả viết bằng vốn, và bạn thay đổi trả $ this-> author thành ucwords ($ this-> author), bạn phải thực hiện nó nhiều lần như bạn ' đã sao chép phương thức đó. Sử dụng một lớp trừu tượng, bạn có thể xác định hành vi, trong khi đánh dấu chính lớp đó là không đầy đủ. Điều này đến rất tiện dụng.

Hy vọng điều đó sẽ hữu ích.

+0

Cảm ơn Berry. – Sreeraj

+1

Giải thích tuyệt vời, cảm ơn! –

+1

Lời giải thích tuyệt vời – Mirko

2

Không phải tất cả các lớp trừu tượng phương pháp phải trống, có thể có một số phương pháp cơ bản (và tài sản) để làm việc với. Ví dụ - bạn có và e-shop và bạn phát triển một lớp trừu tượng để nhập sản phẩm. Lớp này có một metod để lưu sản phẩm vào db, để tạo ra url của sản phẩm và một phương thức trừu tượng để lấy sản phẩm từ đâu đó (do đó phải được triển khai trong lớp mở rộng). Giao diện chỉ có các phương thức trống và không có thuộc tính (có thể có hằng số), vì vậy có thể không có logic thực tế, chỉ các hằng số phương thức, tên phương thức và công cụ sửa đổi truy cập của chúng.

10

Lớp trừu tượng giúp bạn khi bạn có nhiều lớp học có cùng phương pháp.

Ví dụ:

abstract class Foo { 
    public function foo1() { 
    //Do something 
    } 

    public abstract class foo2(); 
} 

class Bar extends Foo { 
    public class foo2() { 
    //Do something 
    } 
} 

class Baz extends Foo { 
} 

Điều gì sẽ xảy ra:

  • Bạn không thể sử dụng new Foo();, Foo là trừu tượng.
  • Bạn sẽ có thể sử dụng Bar.foo1()Baz.foo1(), họ sẽ thực hiện tương tự.
  • Bạn sẽ gặp lỗi vì Baz không triển khai phương pháp abstact foo2.

Ví dụ, nơi nó rất hữu ích:

abstract class Shape { 
    public function display() { /* ... */ } 
    //... 
} 

class Circle extends Shape { 
    //... 
} 

class Rectangle extends Shape { 
    //... 
} 

//... 

Bạn muốn mỗi lớp để có thể display(), nhưng không có những điều như "Shape" của chính nó.

1

Như tên cho thấy, mục đích của giao diện là khai báo rõ ràng giao diện cho dữ liệu và các phương thức do lớp và trường hợp cung cấp, mà không cần phải mã hóa các phương thức đó ngay lập tức. Ví dụ cổ điển là hình dạng hình học. Như một giao diện có thể định nghĩa một phương pháp mà tạo ra diện tích của một hình dạng như:

interface Shape { 
    public function getArea(); 
} 

Có thể có một số lớp khác nhau thực hiện giao diện này như CircleSquare rằng sẽ cung cấp triển khai khác nhau cho phương pháp getArea(). Sau đó bạn có thể thực hiện một chức năng hiển thị thông tin trên bất kỳ hình dạng hình học:

function displayInformation(Shape $shape) { 
    echo "The area of this shape is: " . $shape->getArea(); 
} 

Bạn có thể vượt qua bất kỳ đối tượng thực hiện các giao diện Shape để chức năng này, và đảm bảo giao diện mà các phương pháp getArea() có mặt.

Tất nhiên, các khái niệm này có thể hữu ích hơn trong các ngôn ngữ lập trình được đánh máy mạnh hơn PHP.