2009-10-17 39 views
38

Tôi đã tự hỏi nếu nó được phép tạo một thể hiện của một lớp bên trong một lớp khác.Tôi có thể khởi tạo một lớp PHP bên trong một lớp khác không?

Hoặc, tôi có phải tạo ra nó bên ngoài và sau đó chuyển nó qua thông qua các nhà xây dựng? Nhưng sau đó tôi đã tạo ra nó mà không biết tôi có cần nó hay không.

Ví dụ (một lớp cơ sở dữ liệu):

class some{ 

if(.....){ 
include SITE_ROOT . 'applicatie/' . 'db.class.php'; 
$db=new db 

Trả lời

29

Bạn không thể định nghĩa một lớp trong lớp khác. Bạn nên bao gồm các tệp với các lớp khác bên ngoài lớp học. Trong trường hợp của bạn, điều đó sẽ cung cấp cho bạn hai lớp học cấp cao nhất dbsome. Bây giờ trong hàm tạo của some, bạn có thể quyết định tạo một thể hiện của db. Ví dụ:

include SITE_ROOT . 'applicatie/' . 'db.class.php'; 

class some { 

    public function __construct() { 
     if (...) { 
      $this->db = new db; 
     } 
    } 

} 
+10

Tôi khuyên bạn nên sử dụng 'require' thay vì' include'. –

+2

Điều này cũng giống như một tình huống tốt cho việc sử dụng mẫu thiết kế tiêm phụ thuộc. – Ejaz

+6

@ rink.attendant.6 'require_once' thậm chí còn tốt hơn: D –

2

Không thể tạo lớp học trong lớp khác bằng PHP. Tạo một đối tượng (một thể hiện của một lớp) trong một đối tượng khác là một thứ khác.

+0

Bạn sẽ làm gì tương tự như thế này? –

13

Tôi chỉ muốn chỉ ra rằng có thể tải định nghĩa lớp động bên trong định nghĩa lớp khác. Lukas đúng là chúng ta không thể định nghĩa một lớp bên trong lớp khác, nhưng chúng ta có thể bao gồm() hoặc yêu cầu() động, vì mọi hàm và lớp được định nghĩa trong tệp được bao gồm sẽ có phạm vi toàn cục. Nếu bạn cần tải một lớp hoặc một hàm động, chỉ cần gộp các tệp vào một trong các hàm của lớp. Bạn có thể làm điều này:

function some() 
{ 
    require('db.php'); 
    $db = new Db(); 
    ... 
} 

http://php.net/manual/en/function.include.php

+1

Để tải lớp động, tôi khuyên bạn nên sử dụng 'require_once' hoặc' include_once' - theo cách đó bạn sẽ đảm bảo bạn không bao gồm/yêu cầu nhiều lần :) –

+2

trong trường hợp này, bạn nên sử dụng "include_once" gây ra "require" gọi khi tệp đó (nơi hàm được xác định) được đưa vào hệ thống. nhưng bạn có thể sử dụng include hoặc include_once trong sub-routine. nó sẽ thực thi khi nó trỏ vào tiểu trình con đó –

2

Không, nó không phải là có thể. Các lớp lồng ghép và các đối tượng tổng hợp là các cơ chế khác nhau. Các lớp lồng nhau có nghĩa là các tên lớp lồng nhau, trên thực tế. Lớp A lồng trong lớp B sẽ được đặt tên là "B \ A" (?). Từ v5.3 bạn có thể lồng các tên lớp (và một số tên khác) vào các không gian tên.

16

Mọi người nói rằng có thể 'tạo lớp trong lớp' có vẻ như có thể tạo đối tượng/thể hiện trong một lớp. Tôi chưa thấy một ví dụ về một định nghĩa lớp thực tế trong một định nghĩa lớp, trong đó sẽ trông giống như:

class myClass{ 

    class myNestedClass{ 

    } 

} 

/* THIS IS NOT ALLOWED AND SO IT WON'T WORK */ 

Kể từ khi câu hỏi là 'là nó có thể tạo một lớp bên lớp khác', tôi bây giờ có thể chỉ giả định rằng nó là KHÔNG thể.

+0

Có các ví dụ trong các ngôn ngữ lập trình khác, và các lớp lồng nhau có ích: http://docs.oracle.com/javase/tutorial/java/javaOO/nested. html –

1

Điều này có thể trong PHP 7 với Anonymous classes.

Xem ví dụ từ the docs:

class Outer 
{ 
    private $prop = 1; 
    protected $prop2 = 2; 

    protected function func1() 
    { 
     return 3; 
    } 

    public function func2() 
    { 
     return new class($this->prop) extends Outer { 
      private $prop3; 

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

      public function func3() 
      { 
       return $this->prop2 + $this->prop3 + $this->func1(); 
      } 
     }; 
    } 
} 

echo (new Outer)->func2()->func3(); 
// Output: 6 

Đây là một ví dụ đơn giản cho thấy việc sử dụng của các tầng lớp vô danh, nhưng không phải từ bên trong một lớp:

// Pre PHP 7 code 
class Logger 
{ 
    public function log($msg) 
    { 
     echo $msg; 
    } 
} 

$util->setLogger(new Logger()); 

// PHP 7+ code 
$util->setLogger(new class { 
    public function log($msg) 
    { 
     echo $msg; 
    } 
}); 
+0

Func3 không có sẵn trên toàn cầu trong cá thể lớp 'bên ngoài'? –

+1

@ChrisO Nope. 'print_r (get_class_methods ('Outer'));' in 'Array ([0] => func2)' –

+0

Đó là quá xấu, nhưng, đó là một cái gì đó anyway. Chỉ cần một chút cú pháp, cảm ơn. :) –

0

(Chỉnh sửa) Ok các câu hỏi và ví dụ về những gì bạn đang cố gắng đạt được là khó hiểu. Có vẻ như từ ví dụ của bạn, bạn đang cố gắng DEFINE một lớp bên trong một lớp khác.

Tên chính xác cho điều này là NESTED CLASS và không thể thực hiện trong PHP. Vì vậy, ví dụ của bạn câu trả lời là "KHÔNG". Không phải trong PHP anyway. Các ngôn ngữ khác sẽ cho phép "các lớp lồng nhau". Java là một ví dụ.

Ví dụ này sẽ KHÔNG làm việc trong PHP

class outer_class{ 
    class inner_class{ 
     ... 
    } 
    ... 
} 

Bây giờ câu hỏi hỏi là tạo ra một thể hiện của một lớp trong lớp khác.

Để câu trả lời này là "CÓ", bạn có thể CÀI ĐẶT một "đối tượng" bên trong "lớp". Chúng tôi làm cả ngày.

class simple_class{ 

    protected $instanceOfOtherClass; 

    public function instanciateObject_KeepingAReferenceToIt(){ 
     // create an instance of OtherClass and associate it to $this->instanceOfOtherClass 
     $this->instanceOfOtherClass = new OtherClass(); 
    } 

    public function instanciateObject_Without_KeepingAReferenceToIt(){ 
     // create an instance of OtherClass and return it 
     return new OtherClass(); 
    } 
} 

Một lớp thậm chí có thể tự khởi tạo. Đó là những gì các singleton nổi tiếng và nhiều người khác Creational patterns. Đáng buồn là một số người tin rằng biết về dependency injection có nghĩa là họ sẽ không bao giờ gọi NEW trong một phương thức nữa. SAI RỒI.

Nó giúp hiểu sự khác biệt giữa một lớp và một đối tượng. A class là mẫu mã chương trình có thể mở rộng để tạo đối tượng. An object đề cập đến một trường hợp cụ thể của một lớp học.

Các vấn đề liên quan