Đóng gói với ví dụ đơn giản trong php là gì? Đây là chức năng cha mẹ

Theo ý muốn của số phận, tôi phải đọc một khóa học đặc biệt về mẫu thiết kế tại một trường đại học. Khóa học đặc biệt là bắt buộc nên học viên đến với tôi rất khác nhau. Tất nhiên, trong số đó cũng có những lập trình viên đang hành nghề. Nhưng thật không may, hầu hết mọi người đều gặp khó khăn trong việc hiểu các thuật ngữ cơ bản của OOP.

Để làm điều này, tôi đã cố gắng giải thích ít nhiều bằng các ví dụ trực tiếp các khái niệm cơ bản OOP (lớp, đối tượng, giao diện, trừu tượng hóa, đóng gói, kế thừa và đa hình).

Phần đầu tiên được dành cho các lớp, đối tượng và giao diện.
Phần thứ hai dưới đây minh họa tính đóng gói, tính đa hình và tính kế thừa

đóng gói

Hãy tưởng tượng một chút rằng chúng ta đang ở cuối thế kỷ trước, khi Henry Ford vẫn chưa phát minh ra dây chuyền lắp ráp, và những nỗ lực đầu tiên nhằm tạo ra một chiếc ô tô đã phải đối mặt với sự chỉ trích từ chính quyền vì thực tế là những con quái vật khói này gây ô nhiễm. không khí và khiến ngựa sợ hãi. Hãy tưởng tượng rằng để lái chiếc ô tô hơi nước đầu tiên, cần phải biết cách thức hoạt động của nồi hơi, liên tục thêm than, theo dõi nhiệt độ và mực nước. Trong trường hợp này, để quay các bánh xe, hãy sử dụng hai cần gạt, mỗi cần quay riêng một bánh xe. Tôi nghĩ chúng ta có thể đồng ý rằng việc lái ô tô vào thời điểm đó là một trải nghiệm rất bất tiện và khó khăn.

Bây giờ chúng ta hãy quay trở lại ngày hôm nay với những kỳ quan hiện đại của ngành công nghiệp ô tô với hộp số tự động. Trên thực tế, về cơ bản không có gì thay đổi. Bơm xăng vẫn cung cấp xăng cho động cơ, bộ vi sai đảm bảo cho các bánh xe quay theo các góc khác nhau, đồng thời trục khuỷu biến chuyển động tịnh tiến của piston thành chuyển động quay của các bánh xe. Tiến độ là khác nhau. Giờ đây, tất cả những hành động này đều bị ẩn khỏi người dùng và cho phép anh ta quay vô lăng và nhấn bàn đạp ga mà không cần suy nghĩ về điều gì đang xảy ra với kim phun, van tiết lưu và trục cam vào lúc này. Chính việc che giấu các quá trình bên trong xảy ra trong ô tô đã cho phép nó được sử dụng một cách hiệu quả ngay cả với những người không phải là thợ sửa ô tô chuyên nghiệp với hai mươi năm kinh nghiệm. Việc ẩn trong OOP này được gọi là đóng gói.

đóng gói là thuộc tính hệ thống cho phép bạn kết hợp dữ liệu và phương thức hoạt động với chúng trong một lớp và ẩn chi tiết
việc triển khai từ người dùng.

Đóng gói được liên kết chặt chẽ với khái niệm về giao diện lớp. Về cơ bản, mọi thứ không có trong giao diện đều được gói gọn trong lớp.

Trừu tượng

Hãy tưởng tượng rằng một người lái xe đang lái ô tô dọc theo một con đường đông đúc. Rõ ràng là lúc này anh ta sẽ không nghĩ đến thành phần hóa học của nước sơn ô tô, đặc thù về sự tương tác của các bánh răng trong hộp số, hay ảnh hưởng của hình dáng thân xe đến tốc độ (trừ khi xe bị kẹt xe). và người lái xe hoàn toàn không có việc gì phải làm). Tuy nhiên, anh ta sẽ sử dụng vô lăng, bàn đạp, đèn xi nhan (và có thể cả gạt tàn) thường xuyên.

Trừu tượng là một cách để làm nổi bật một bộ đặc điểm quan trọngđối tượng, loại trừ những đối tượng không đáng kể khỏi sự xem xét. Tương ứng, sự trừu tượng là tập hợp tất cả các đặc điểm như vậy.

Nếu phải tính đến thành phần hóa học của sơn thân xe và nhiệt dung riêng của bóng đèn gắn biển số xe để mô hình hóa hoạt động của chiếc ô tô, chúng ta sẽ không bao giờ biết NFS là gì.

Đa hình

Bất kỳ khóa đào tạo lái xe nào cũng sẽ vô nghĩa nếu một người đã học lái xe, chẳng hạn như VAZ 2106, sau đó không thể lái VAZ 2110 hoặc BMW X3. Mặt khác, thật khó để tưởng tượng một người bình thường có thể lái một chiếc ô tô mà bàn đạp ga ở bên trái bàn đạp phanh và thay vì vô lăng lại có cần điều khiển.

Có điều là các bộ phận điều khiển chính của xe đều có thiết kế và nguyên lý hoạt động giống nhau. Người lái xe biết chắc rằng muốn rẽ trái thì phải bẻ lái, bất kể có trợ lực lái hay không.
Nếu một người cần đi từ nơi làm về nhà, anh ta sẽ ngồi sau tay lái của một chiếc ô tô và thực hiện các hành động tương tự, bất kể anh ta sử dụng loại ô tô nào. Trên thực tế, chúng ta có thể nói rằng tất cả các ô tô đều có giao diện giống nhau và người lái xe, trừu tượng hóa bản chất của ô tô, làm việc với giao diện này. Nếu người lái xe phải lái dọc theo đường Autobahn của Đức, có lẽ anh ta sẽ chọn một chiếc xe nhanh với vị trí ngồi thấp, và nếu anh ta phải trở về từ một trại cá marlin xa xôi ở Dãy núi Altai sau cơn mưa, rất có thể anh ta sẽ chọn một chiếc UAZ với trục quân đội. Tuy nhiên, bất kể chuyển động và hoạt động bên trong của máy được thực hiện như thế nào thì giao diện vẫn sẽ được giữ nguyên.

Đa hình– đây là thuộc tính của hệ thống để sử dụng các đối tượng có cùng giao diện mà không có thông tin về loại và cấu trúc bên trong của đối tượng.

Ví dụ: nếu bạn đang đọc dữ liệu từ một tệp thì rõ ràng lớp thực hiện luồng tệp sẽ có một phương thức tương tự như sau: byte readBytes(int n);
Bây giờ giả sử bạn cần đọc cùng một dữ liệu từ ổ cắm. Lớp thực hiện socket cũng sẽ có một phương thức readByte. Chỉ cần thay thế đối tượng của một lớp này bằng đối tượng của lớp khác trong hệ thống của bạn là đủ và bạn sẽ đạt được kết quả.

Trong trường hợp này, logic hệ thống có thể được triển khai bất kể dữ liệu được đọc từ tệp hay nhận qua mạng. Do đó, chúng tôi loại bỏ chuyên môn cụ thể về thu thập dữ liệu và làm việc ở cấp độ giao diện. Yêu cầu duy nhất là mỗi đối tượng được sử dụng đều có một phương thức readByte.

Di sản

Hãy tưởng tượng chúng ta, trong giây lát, là kỹ sư tại một nhà máy ô tô. Nhiệm vụ của chúng tôi là phát triển một chiếc ô tô hiện đại. Chúng tôi đã có rồi mô hình trước đó, điều này đã được chứng minh qua nhiều năm sử dụng. Mọi thứ sẽ ổn, nhưng thời gian và công nghệ thay đổi, và nhà máy hiện đại của chúng tôi phải cố gắng cải thiện sự tiện lợi và thoải mái của sản phẩm cũng như đáp ứng các tiêu chuẩn hiện đại.

Chúng ta cần phát hành toàn bộ đội hình xe ô tô: sedan, station wagon và hatchback cỡ nhỏ. Rõ ràng, chúng tôi sẽ không thiết kế một chiếc ô tô mới từ đầu, nhưng lấy thế hệ trước làm cơ sở, chúng tôi sẽ thực hiện một số thay đổi về thiết kế. Ví dụ: chúng tôi sẽ bổ sung trợ lực lái, giảm khoảng cách giữa chắn bùn và mui xe, đồng thời lắp đặt đèn sương mù. Ngoài ra, mỗi người mẫu sẽ có một vóc dáng cơ thể khác nhau.

Rõ ràng, cả ba sửa đổi sẽ có hầu hết các đặc tính của mẫu xe trước đó (động cơ cũ tốt từ năm 1970, khung gầm không thể xuyên thủng đã chứng tỏ khả năng hoạt động xuất sắc trên đường nội địa, hộp số, v.v.). Hơn nữa, mỗi mô hình sẽ triển khai một số chức năng mới hoặc Tính năng thiết kế. TRONG trong trường hợp này, chúng ta đang giải quyết vấn đề thừa kế.
Di sản là một thuộc tính của hệ thống cho phép bạn mô tả lớp mới dựa trên cái hiện có với chức năng được mượn một phần hoặc toàn bộ. Lớp mà từ đó sự kế thừa được thực hiện được gọi là lớp cơ sở hoặc lớp cha. Một lớp mới là lớp con cháu, lớp thừa kế hoặc lớp dẫn xuất.

Cần lưu ý rằng lớp dẫn xuất đáp ứng đầy đủ đặc điểm kỹ thuật của lớp cha nhưng có thể có chức năng bổ sung. Về mặt giao diện, mỗi lớp dẫn xuất thực hiện đầy đủ giao diện của lớp cha. Điều ngược lại là không đúng sự thật.

Thật vậy, trong ví dụ của chúng tôi, chúng tôi có thể thực hiện tất cả các hành động tương tự với ô tô mới cũng như ô tô cũ: tăng hoặc giảm tốc độ, rẽ, bật đèn xi nhan. Tuy nhiên, ngoài ra, chúng tôi còn có cơ hội bật đèn sương mù chẳng hạn.

Thiếu khả năng tương thích ngược có nghĩa là chúng ta không nên mong đợi mẫu cũ phản ứng chính xác với các hành động như bật đèn sương mù (đơn giản là không có trong mẫu xe này).

Trong bài học này chúng ta sẽ tìm hiểu về trụ cột đầu tiên trong ba trụ cột của OOP - đóng gói. Đóng gói (tiếng Latin trong Capsules; từ “hộp” Capsules) - đặt trong một cái vỏ, cách ly, đóng một cái gì đó để loại trừ ảnh hưởng đến môi trường. Bạn sẽ học cách sử dụng tính năng này trong lập trình hướng đối tượng khi chúng ta xem qua bài học này.

Thuộc tính đối tượng

Hãy quay lại chủ đề trước của chúng ta. Những ai đã từng nhìn thấy hải cẩu đều biết rằng một số đặc điểm của hải cẩu là khác nhau: màu sắc, trọng lượng, số lượng tiếng kêu, v.v. Tất cả các đồ vật đều có dấu hiệu như vậy, kể cả của chúng ta. Và trong OOP chúng được gọi thuộc tính của đồ vật. Hãy đưa ra ví dụ về các đặc tính như vậy đối với mèo:

  • màu sắc;

Bây giờ chúng ta hãy tạo một lớp trông giống một con mèo thật hơn:

Khóa học OOP trong PHP.

Tất cả điều này: $name, $color, $weight - thuộc tính của các đối tượng trong tương lai của lớp này. Tên thuộc tính luôn được đặt trước bởi công cụ sửa đổi quyền truy cập. Trong trường hợp của chúng tôi nó là công khai. Từ này có nghĩa là thuộc tính này sẽ có sẵn cho tất cả những người làm việc với các đối tượng thuộc lớp này. Có các công cụ sửa đổi quyền truy cập khác nhưng sẽ có nhiều thông tin hơn về chúng bên dưới.

Một lần nữa, chỉ riêng mã này sẽ không xuất ra bất cứ thứ gì ngay bây giờ. Đây một lần nữa chỉ là một mẫu.

Vì vậy, chúng tôi đã tạo một số mẫu mô tả khá rõ ràng về những con mèo. Bây giờ chúng ta hãy tạo một đối tượng mới của lớp này.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Vì vậy, chúng tôi đã tạo một đối tượng có kiểu Cat và kết xuất nó bằng var_dump().

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Như bạn có thể thấy, biến chứa một đối tượng và nó có ba thuộc tính, tất cả đều có giá trị null. Hãy khắc phục điều này. Hãy đặt tên cho con mèo của chúng ta, vẽ nó và tô màu nó bằng thứ gì đó để nó nặng một thứ gì đó. Việc này được thực hiện như thế này:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Toán tử -> (một mũi tên gồm hai ký tự - "dấu gạch ngang" và "lớn hơn") được sử dụng để truy cập các thuộc tính của một đối tượng. Trong mã này, chúng tôi đã truy cập từng thuộc tính riêng biệt và gán giá trị cho chúng. Nếu bây giờ chúng ta kết xuất $cat1 bằng cách sử dụng var_dump() chúng ta sẽ nhận được những điều sau:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Như bạn có thể thấy, đây không còn là một thứ vô nghĩa nữa mà là một Quả cầu tuyết màu trắng nặng ba kg rưỡi.

Bây giờ chúng ta có thể truy cập vào thuộc tính của con mèo này và tìm ra tên của nó.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Và kết quả là “Quả cầu tuyết”.

Chúng ta có thể tạo ra nhiều con mèo và gán cho chúng những thuộc tính khác nhau:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Kết quả khá được mong đợi:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Hai đối tượng khác nhau có giá trị thuộc tính riêng.

Điều này khá giống với cách làm việc với mảng, như thể chúng ta đang viết một giá trị bằng khóa.

Việc có các thuộc tính bên trong các đối tượng đã là biểu hiện của sự đóng gói. Một đối tượng có các thuộc tính, nó chứa chúng bên trong chính nó - đó là “capsule”.

Phương thức đối tượng

Nhưng các đối tượng không chỉ giới hạn ở các thuộc tính. Chúng có thể có các phương thức - đây là các hàm thuộc về các đối tượng cụ thể. Chúng ta mô tả chúng bên trong lớp, sau đó các hàm này được liên kết với các đối tượng của lớp này.

Các phương thức được khai báo như sau:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

public là công cụ sửa đổi truy cập cho một phương thức, chỉ ra rằng tất cả những người sử dụng đối tượng đều có thể gọi nó, sayHello là tên của phương thức, theo sau là các đối số (trong trường hợp của chúng ta là không có đối số nào), và sau đó là phần thân của phương thức, trong đó chúng tôi chỉ in dòng "Meo meo!";

Như chúng ta có thể thấy, nhìn chung, các phương thức đối tượng không khác mấy so với các hàm thông thường. Khi mô tả chúng, chúng tôi chỉ thêm công cụ sửa đổi quyền truy cập.

Chúng ta có thể gọi phương thức từ soz của đối tượng này. Hãy tạo một con mèo mới và yêu cầu nó chào chúng ta. Để gọi phương thức của đối tượng, hãy sử dụng toán tử tương tự như để truy cập các thuộc tính của đối tượng ->

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Mã này sẽ xuất ra chuỗi "Meow!" Cứ như thế, một con mèo ảo đã chào đón chúng tôi!

biến $ này

Có, nhưng phương pháp không như vậy chức năng đơn giản. Bên trong các phương thức, một biến đặc biệt $this có sẵn và nó lưu trữ... đối tượng hiện được tạo của chúng ta. Ồ! Đầu óc tôi nổ tung :)

Trong thực tế, mọi thứ không quá phức tạp. Chúng ta có thể sử dụng biến này để truy cập các phương thức và thuộc tính khác của đối tượng này. Ví dụ, hãy dạy một con mèo nói xin chào như con người. Hãy để anh ấy nói tên của mình. Để làm điều này, chúng ta cần viết lại phương thức sayHello() như sau:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Và bây giờ, khi chúng ta tạo một đối tượng mèo mới và yêu cầu nó chào chúng ta, $this->name sẽ trả về giá trị thuộc tính name của đối tượng hiện tại.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Mã này sẽ xuất ra như sau:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Nó đơn giản mà. Tôi hy vọng cái này ví dụ rõ ràngđã giúp bạn hiểu rằng $this chỉ là đối tượng hiện tại và chỉ đối tượng được tạo mới có $this.

Cả hai phương thức và biến $this - cũng đóng gói! Nhưng đó không phải là tất cả:)

Công cụ sửa đổi quyền truy cập

Bây giờ tất cả các thuộc tính và phương thức của đối tượng đều được công khai - từ bất kỳ đâu trong mã mà đối tượng này có thể truy cập được, chúng ta có thể truy cập các thuộc tính và phương thức này. Để công khai một thuộc tính hoặc phương thức, hãy sử dụng từ khóa công cộng.

Tuy nhiên, còn có các công cụ sửa đổi truy cập khác và trong bài học này chúng ta sẽ nghiên cứu một công cụ sửa đổi khác - riêng tư. Nó cho phép bạn đặt các thuộc tính và phương thức của một đối tượng ở chế độ riêng tư, sau đó chúng sẽ chỉ có thể được truy cập trong đối tượng này.

Ví dụ: hãy thay đổi công cụ sửa đổi cho thuộc tính tên:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Bây giờ chúng ta hãy thử thay đổi thuộc tính này của một đối tượng:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Chúng tôi sẽ nhận được một lỗi:

Tuy nhiên, chúng ta có thể viết phương pháp công khai, điều này sẽ cho phép bạn đặt thuộc tính này bằng cách sử dụng nó. Hãy gọi nó là setName(). Nó sẽ lấy chuỗi được truyền cho nó và đặt giá trị này cho thuộc tính name.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Bây giờ hãy đặt tên cho con mèo bằng phương pháp này:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Bây giờ mọi thứ đã hoạt động thành công và con mèo thậm chí còn nói tên của mình bằng phương thức sayHello(). Tuy nhiên, nếu chúng ta cố gắng in tên anh ấy một cách đơn giản như thế này:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

thì chúng ta sẽ lại gặp lỗi truy cập.

Như bạn có thể nhận thấy, bằng cách sử dụng phương thức setName, chúng tôi cho phép bạn chỉ đặt một chuỗi cho thuộc tính name. Không phải số, cũng không phải mảng, hay bất cứ thứ gì khác, cụ thể là một chuỗi. Đây là một cách tiếp cận tốt - nó cho phép bạn sử dụng các loại xác thực khác nhau. Rốt cuộc, bên trong phương thức này, bạn có thể thực hiện một số kiểm tra trước khi đưa giá trị vào thuộc tính. Điều này cho phép bạn tránh các tình huống mà bạn có thể nhét bất kỳ điều vô nghĩa nào vào thuộc tính. Các phương thức như setName() đặt giá trị cho thuộc tính của đối tượng được gọi người định cư.

Để trực tiếp lấy giá trị thuộc tính riêng của một đối tượng, bạn có thể viết một phương thức công khai khác sẽ trả về giá trị của thuộc tính này. Hãy viết phương thức getName().

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Bây giờ chúng ta có thể đơn giản lấy tên của con mèo từ bên ngoài:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Những phương pháp như vậy lần lượt được gọi là getter.

Công cụ sửa đổi quyền truy cập là một biểu hiện khác của tính đóng gói.

Người xây dựng

Bây giờ chúng ta hãy bắt và phá vỡ một con mèo :)

Để làm điều này, chúng ta sẽ không đặt tên cho nó mà sẽ gọi phương thức getName().

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Chuyện gì sẽ xảy ra? Đúng vậy - một sai lầm!

Xét cho cùng, chúng ta đã mô tả rằng getName() phải luôn trả về một chuỗi. Và đối tượng của chúng tôi trả về null.

Có cách nào để đảm bảo rằng thuộc tính name sẽ luôn chứa một chuỗi không? Có thể. Có một hàm tạo cho việc này - đây là một phương thức được gọi khi một đối tượng của lớp này được tạo. Về nguyên tắc, đây là phương pháp giống như tất cả các phương pháp khác, nó có thể có các lý lẽ khác nhau. Nhưng nó nhất thiết phải được gọi tự động khi một đối tượng của lớp mà nó được mô tả được tạo ra.

Phương thức khởi tạo phải được đặt tên là __construct. Chính xác là như vậy và không còn cách nào khác.

Hãy tạo một hàm tạo cho con mèo của chúng ta sẽ có đối số $name bắt buộc thuộc loại chuỗi.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Thông thường, người ta khai báo một hàm tạo ở đầu một lớp, sau khi khai báo các thuộc tính, nhưng trước các phương thức khác.

Bây giờ, để tạo một con mèo có tên Snowball, chúng ta phải truyền một đối số khi tạo một đối tượng mới:

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Và đây là điều đã xảy ra: lập luận được chuyển tới dấu ngoặc tròn, được truyền vào phương thức __construct(). Ở đó giá trị này được đặt thành thuộc tính tên của đối tượng.

Nếu bây giờ chúng ta cố gắng tìm ra tên của con mèo này, chúng ta sẽ hiểu được.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Bây giờ, hãy thử tạo một con mèo không có tên theo cách cổ điển, không truyền đối số khi tạo một đối tượng.

Mã chỉ khả dụng sau khi mua khóa học OOP bằng PHP.

Chúng ta sẽ gặp lỗi.

Ở đây nói rằng hàm tạo mong đợi 1 đối số bắt buộc, nhưng chúng tôi đã không chuyển bất kỳ đối số nào.

Vì vậy, chúng ta có một lớp mèo mà đối tượng của chúng không thể được tạo nếu không có tên. Và đây chính xác là điều nên xảy ra trên thế giới - tất cả mèo đều phải có tên. Đồng ý rằng một thế giới như vậy sẽ tốt hơn nhiều so với thế giới chúng ta đang sống. Chà, trong lập trình, chúng ta có thể xây dựng thế giới mà chúng ta muốn. Và điều đó thật tuyệt :)

Tóm lại, chúng ta có thể nói rằng đóng gói là khả năng của các đối tượng chứa các thuộc tính và phương thức. Đây là cách chúng tôi làm cho chúng phụ thuộc lẫn nhau bên trong “con nhộng” này.

Đây là trụ cột đầu tiên của OOP - đóng gói. Hẹn gặp lại các bạn trong bài học tiếp theo, nhưng bây giờ chúng ta hãy làm bài tập về nhà.

Đóng gói chỉ đơn giản là gói một số dữ liệu vào một đối tượng. Thuật ngữ "đóng gói" thường được sử dụng thay thế cho "ẩn thông tin". Wikipedia có một bài viết hay.

_user == null) ( $this->_user = new User(); ) return $this->_user; ) ) lớp Người dùng ( private $_name; public function __construct() ( $this->_name = "Joseph Crawford Jr."; ) public function GetName() ( return $this->_name; ) ) $app = new App( ); echo $app->User()->GetName(); ?>

Đóng gói là một cơ chế liên kết mã và dữ liệu mà nó quản lý, đồng thời giữ cho mã và dữ liệu đó được an toàn trước sự can thiệp và lạm dụng từ bên ngoài. Việc gói dữ liệu và phương thức vào một đơn vị duy nhất (gọi là lớp) được gọi là đóng gói. Lợi ích của việc đóng gói là nó thực hiện nhiệm vụ nội bộ mà không khiến bạn phải lo lắng.

Đóng gói là cách lưu trữ một đối tượng hoặc dữ liệu dưới dạng thuộc tính bên trong một vật thể khác, vậy vật thể bên ngoài có toàn quyền kiểm soát về cách dữ liệu nội bộ hoặc các đối tượng có thể được truy cập.

Ví dụ

Lớp OuterClass ( riêng var $innerobject; hàm tăng() ( return $this->innerobject->increment(); ) )

Bạn có lớp bổ sung xung quanh một đối tượng được đóng gói, cho phép đối tượng bên ngoài kiểm soát quyền truy cập vào đối tượng bên trong. Điều này, kết hợp với việc đặt đối tượng/thuộc tính bên trong ở chế độ riêng tư, cho phép ẩn thông tin .

đóng gói: Đóng gói là khái niệm gói hoặc ràng buộc các phần tử và phương thức dữ liệu liên quan trong một mô-đun, được gọi là đóng gói.

Đây ví dụ đúngđóng gói

tên = $n; $này -> tuổi = $a; ) hàm công khai setAge($ag) ( $this -> ag = $ag; ) hàm công khai display() ( echo "welcome " . $this -> name . "
"; return $this -> age - $this -> ag; ) ) $person = người mới("Pankaj", 25); $person -> setAge(10); echo "Bạn là " . $person -> display (). "tuổi";

Mọi người dường như nhầm lẫn các chi tiết về định hướng đối tượng với sự đóng gói, đây là một khái niệm cũ hơn và rộng hơn nhiều. Cấu trúc dữ liệu được đóng gói

  • có thể được chuyển bằng một tham chiếu duy nhất, ví dụ: số tăng (myDate), thay vì số tăng (năm, tháng, ngày)
  • có một tập hợp các hoạt động có thể áp dụng được lưu trữ trong một mô-đun chương trình duy nhất (lớp, mô-đun, tệp, v.v.),
  • không cho phép khách hàng xem hoặc thao tác các thành phần phụ của nó NGOẠI TRỪ bằng cách gọi các hoạt động thích hợp

Bạn có thể thực hiện đóng gói bằng hầu hết mọi ngôn ngữ và bạn sẽ nhận được lợi ích to lớn về khả năng điều chế và bảo trì.

Đóng gói là một cơ chế bảo vệ cho lớp và cấu trúc dữ liệu của bạn. Nó làm cho cuộc sống của bạn dễ dàng hơn nhiều. Với Đóng gói, bạn có quyền kiểm soát quyền truy cập và thiết lập các tham số và phương thức của lớp. Bạn có quyền kiểm soát mức độ hiển thị đối với người ngoài và cách thiết lập các tham số cho đối tượng của bạn.

Truy cập và thiết lập các tham số lớp

(Cách tốt)

giới tính; ) hàm công khai setGender($gender) ( if ("nam" !== $gender và "female" !== $gender) ( ném new \Exception("Đặt nam hay nữ cho giới tính"); ) $this-> giới tính = $giới tính; ) )

Bây giờ bạn có thể tạo một đối tượng từ lớp Người dùng của mình và bạn có thể đặt các tùy chọn giới tính một cách an toàn. Nếu bạn đặt sai thứ gì đó cho lớp của mình thì nó sẽ loại bỏ và loại trừ. Bạn có thể nghĩ rằng điều này là không cần thiết, nhưng khi mã của bạn phát triển, bạn muốn thấy một thông báo ngoại lệ có ý nghĩa hơn là một vấn đề logic bất tiện trong một hệ thống không có ngoại lệ.

$user = Người dùng mới(); $user->setGender("nam"); // Một ngoại lệ sẽ xuất hiện và bạn không thể đặt "Y" thành giới tính người dùng $user->setGender("Y");

(Cách xấu)

Nếu bạn không thực hiện vai trò Đóng gói thì mã của bạn sẽ giống như thế này. Rất khó để duy trì. Lưu ý rằng chúng ta có thể đặt bất cứ thứ gì cho thuộc tính giới tính tùy chỉnh.

giới tính = "nam"; // Sẽ không có ngoại lệ nào xảy ra và bạn có thể đặt "Y" thành giới tính người dùng // cuối cùng bạn sẽ gặp phải một số vấn đề logic trong hệ thống của mình // rất khó phát hiện $user->gender = "Y";

Truy cập các phương thức lớp

(Cách tốt)

làm cái này(...); ... $this->doThat(...); ... $this->doThisExtra(...); ) hàm riêng doThis(...some Parameters...) ( ... ) hàm riêng doThat(...some Parameters...) ( ... ) hàm riêng doThisExtra(...some Parameters...) (...))

Tất cả chúng ta đều biết rằng chúng ta không nên tạo một hàm với 200 dòng mã, thay vào đó chúng ta nên chia nó thành một số hàm tùy chỉnh để chia nhỏ mã và cải thiện khả năng đọc của mã. Giờ đây với tính năng đóng gói, bạn có thể buộc các hàm này ở chế độ riêng tư, nghĩa là người khác không thể truy cập chúng và sau này khi bạn muốn thay đổi hàm, bạn sẽ rất vui khi thấy từ khóa riêng tư.

(Cách xấu)

Người dùng lớp ( public function doSomethingComplex() ( // làm mọi thứ ở đây ... ... ... ... ) )

Ngược lại với việc đóng gói sẽ giống như chuyển một biến cho từng phương thức (chẳng hạn như một trình xử lý tệp cho từng phương thức được liên kết với tệp) hoặc các biến toàn cục.

Đóng gói là quá trình loại bỏ dữ liệu của một đối tượng khỏi thế giới bên ngoài và hạn chế quyền truy cập vào nó đối với các thành viên của lớp.

đóng gói: – đóng gói dữ liệu trong một thiết bị. chúng tôi cũng có thể nói rằng chúng tôi đang che giấu thông tin về các chi tiết cần thiết. Ví dụ. Bạn có một chiếc điện thoại di động. Có một số loại giao diện giúp bạn tương tác với điện thoại di động và bạn có thể sử dụng các dịch vụ điện thoại di động. Nhưng thực sự làm việc trên điện thoại di động sẽ biến mất. bạn không biết nó hoạt động như thế nào trong nước.

Một hiệp hội các phần tử dữ liệu và phương thức cùng nhau thành một khối (tức là lớp) được gọi đóng gói . đóng gói giống như một viên nang. Điều này bao gồm các hoạt động liên quan và dữ liệu liên quan đến một đối tượng vào đối tượng đó. Đóng gói giống như chiếc túi của bạn, trong đó bạn có thể đựng bút, sách, v.v. Điều này có nghĩa là nó là thuộc tính của việc đóng gói các thành viên và chức năng.

0) $mark = 10; khác $mark = 0; ) ) ) ?>

Tôi cho thêm một cái nữa ví dụ đời thực (sử dụng hàng ngày), là một "hoạt động truyền hình". Nhiều người điều khiển truyền hình trong cuộc sống hàng ngày của họ.

Nó được đóng gói bằng nắp và chúng ta có thể vận hành điều khiển từ xa điều khiển từ xa và không cần phải mở TV và chuyển kênh. Mọi thứ ở đây đều được đóng ngoại trừ điều khiển từ xa để mọi người đều có thể truy cập mà không cần phải làm việc hay thay đổi mọi thứ trên TV.

Tôi chỉ thích đó là khả năng hiển thị các thuộc tính và phương thức của lớp bạn. Ví dụ – – công khai – riêng tư – được bảo vệ

Chúng ta hãy xem một ví dụ thực tế về đóng gói.

Class MyClass( Private $name; public function showName($newName)( $this->name = $newName; return $this->name; ) ) // khởi tạo đối tượng $obj = new MyClass(); echo $obj->showName("tisuchi");

Trong trường hợp này, đóng gói có nghĩa là chúng ta hạn chế một số thuộc tính. Ví dụ: thuộc tính tên, chúng ta không thể truy cập từ bên ngoài lớp. Mặt khác, chúng ta có thể truy cập một hàm công khai có tên showName() với một tham số riêng tư.

Đúng là những gì tôi muốn gói gọn,

khả năng hiển thị tài sản và phương pháp của bạn.

Mặc dù vậy, nếu bạn muốn hiểu về đóng gói, tôi liên kết đến hướng dẫn đặc biệt của tôi dựa trên đóng gói.

Hy vọng điều này làm cho khái niệm của bạn rõ ràng hơn. Chúc vui vẻ!

Về cơ bản, đây là cách chúng tôi xác định mức độ hiển thị của các thuộc tính và phương thức của mình. Khi tạo lớp, bạn nên tự hỏi những thuộc tính và phương thức nào có thể được truy cập bên ngoài lớp. Giả sử chúng ta có một thuộc tính foo. Nếu một lớp mở rộng lớp của bạn, nó có được phép thao tác và truy cập foo không? Điều gì sẽ xảy ra nếu ai đó tạo các phiên bản của lớp bạn? Có được phép thao tác và truy cập foo không?

Đóng gói là cách bạn muốn các đối tượng/phương thức hoặc thuộc tính/biến hiển thị trong ứng dụng của mình. Ví dụ, :

Lớp ecap ( public $name; private $id; protected $tax; )

Nếu bạn muốn truy cập các thuộc tính riêng tư hoặc được bảo vệ, bạn cần sử dụng các phương thức getter và setter trong lớp của mình, những phương thức này sẽ có thể truy cập được từ bên ngoài lớp của bạn. Điều này có nghĩa là bạn không thể truy cập các thuộc tính riêng tư hoặc được bảo vệ trực tiếp từ bên ngoài lớp học của mình, nhưng bạn có thể sử dụng chúng bằng bất kỳ phương thức nào. Chúng ta hãy xem-

trong lớp thêm phương thức sau:

Lớp ecap ( hàm công khai userId() ( return $this->id; ) )

và chúng ta có thể truy cập nó như:

$obj = ecap mới(); echo $obj->userId();

PHP, OOP, Đóng gói, Kế thừa, Đa hình

Trong bài học này tôi sẽ cho bạn biết về ba khái niệm chính của Lập trình hướng đối tượng: Đóng gói, Kế thừa, Đa hình; Và tôi sẽ dạy bạn cách sử dụng chúng trong quá trình phát triển.

đóng gói

Đóng gói - tài sản ngôn ngữ lập trình cho phép bạn kết hợp và bảo vệ dữ liệu và mã thành một đối tượng và ẩn thực hiệnđối tượng từ người dùng (lập trình viên). Đồng thời, người dùng cung cấp chỉ đặc điểm kỹ thuật ( giao diện) sự vật.

Nói cách khác, khi làm việc với một lớp được thiết kế tốt, chúng ta có thể thưởng thức chỉ bằng phương pháp của mình, mà không đi sâu vào về cách chúng được xây dựng và cách chúng hoạt động với các trường lớp. Đó là về về tình huống khi chúng ta làm việc với một lớp do các lập trình viên khác phát triển. Chúng tôi chỉ đơn giản là sử dụng chức năng đã được triển khai.

Hãy đưa ra một ví dụ khác. Các nguyên tắc đóng gói như che giấu việc triển khai nội bộ được nhúng trong bất kỳ Hàm PHP. Có thể bạn đã biết chức năng strpos()để làm việc với các chuỗi từ thư viện chuẩn PHP. Hàm này tìm kiếm một chuỗi ký tự nhất định trong một chuỗi và trả về vị trí của nó dưới dạng số. Nếu chúng ta nghĩ về việc triển khai hàm này, chúng ta có thể giả sử rằng chúng ta sẽ cần lặp qua từng ký tự từ đầu dòng để khớp với ký tự đầu tiên của chuỗi tìm kiếm và nếu vậy, hãy so sánh hai ký tự tiếp theo, v.v. Nhưng đối với chúng tôi, những lập trình viên không cần phải suy nghĩở trên và đi sâu vào sự phức tạp của việc thực hiện chức năng này. Chúng ta có đủ biết các thông số mà nó chấp nhận và định dạng giá trị trả về. Hàm strpos() gói gọn giải pháp cho vấn đề tìm chuỗi con, chỉ cung cấp cho chúng ta giao diện bên ngoài để sử dụng chuỗi đó.

Tương tự như vậy, các lớp được thiết kế tốt sẽ ẩn việc triển khai nội bộ của chúng bằng cách hiển thị giao diện cho người dùng bên ngoài dưới dạng một tập hợp các phương thức.

TRONG Ngôn ngữ PHP Khái niệm đóng gói được triển khai dưới dạng các công cụ sửa đổi quyền truy cập đặc biệt vào các trường và phương thức của các lớp. Chúng ta sẽ nói về điều này sau.

Di sản

Kế thừa là một cơ chế lập trình hướng đối tượng cho phép bạn mô tả một lớp mới dựa trên đã có sẵn(lớp cha), trong khi các thuộc tính và chức năng của lớp cha được lớp mới mượn.

Hãy lấy một ví dụ thực tế về thừa kế. Bạn có thể lấy một hình hình học làm lớp học. Đồng thời, chúng tôi không nêu rõ con số cụ thể là bao nhiêu. Có thể xác định được những tính chất nào của hình? Giả sử nó có màu sắc. Khi đó lớp mô tả hình phải có trường tương ứng kiểu chuỗi, trong đó chỉ định màu của hình dạng. Ngoài ra bất kỳ hình hình học có diện tích. Hãy để diện tích là tài sản thứ hai của lớp chúng tôi.

Bây giờ giả sử rằng chương trình của chúng ta cần làm việc với hình dạng hình học cụ thể: hình vuôngHình tam giác, bao gồm cả vị trí hình học của chúng trên mặt phẳng. Rõ ràng, việc mô tả hình tam giác và hình vuông bằng cách sử dụng lớp Nhân vật sẽ không đủ vì nó không lưu trữ thông tin vị trí hình học. Vì vậy, chúng tôi sẽ cần giới thiệu thêm hai lớp: Quảng trườngTam giác. Đồng thời, giả sử rằng trong chương trình của chúng ta, chúng ta cũng cần màu sắc và diện tích của các hình. Tình huống này chính xác đòi hỏi phải sử dụng tính kế thừa. Bởi vì bất kỳ hình vuông và hình tam giác nào trong chương trình rõ ràng là một hình, nghĩa là nó có màu sắc và diện tích. Đồng thời, mỗi hình yêu cầu dữ liệu bổ sung (ngoài màu sắc và diện tích) cho mô tả của nó, điều này được giải quyết bằng cách giới thiệu hai lớp bổ sung cho hình vuôngHình tam giác, được kế thừa từ lớp Nhân vật.

Điều này có nghĩa là trong các lớp Quảng trườngTam giác chúng ta sẽ không phải xác định lại các trường màu và vùng. Chỉ cần chỉ ra rằng các lớp được đề cập kế thừa từ lớp Hình là đủ.

Bây giờ chúng ta hãy xem một ví dụ khác, gần hơn với thực tế của các lập trình viên web. Ngày nay, nhiều blog khác nhau đã trở nên phổ biến rộng rãi trên Internet. Trên thực tế, blog chỉ là một tập hợp các bài viết. Và điều cốt lõi khi phát triển một blog chính là bài viết.

Bây giờ hãy tưởng tượng rằng trong blog tương lai của chúng ta, các bài viết có thể có Nhiều loại khác nhau. Đầu tiên, hãy tập trung vào hai loại: bài viết ghi chú thông thường và bài báo tin tức. Đối với một bài báo, ngày xuất bản của nó rất quan trọng vì nó mang một số tin tức cụ thể.

Để triển khai tình huống này trong PHP, chúng ta sẽ cần định nghĩa hai lớp: một lớp dành cho một bài viết ghi chú thông thường và một lớp dành cho một bài báo tin tức. Đồng thời, hãy để bài báo mở rộng khả năng của một bài báo thông thường, tức là. thừa hưởng từ cô ấy. Để kế thừa các lớp trong PHP, từ khóa được sử dụng mở rộng.

Lớp (... // nội dung lớp) lớp (... // nội dung lớp)

Đoạn mã sau định nghĩa một lớp Tin tứcBài viết với tư cách là người thừa kế Bài báo. Lớp học Bài báo lần lượt là cha mẹ của lớp Tin tứcBài viết. Điều này có nghĩa là các trường và phương thức của lớp Bài báo cũng sẽ có mặt trong lớp Tin tứcBài viết và không cần phải xác định lại chúng.

Bằng cách sử dụng tính kế thừa, bạn có thể xây dựng toàn bộ hệ thống phân cấp của các lớp, kế thừa lớp này từ lớp khác. Đồng thời, bất kỳ lớp nào cũng chỉ có thể có một lớp cha:


Đôi khi chúng ta có thể cần xác định lại một trong các phương thức của lớp cha. Hãy hiển thị lại việc thực hiện lớp Bài báo:

Class Article ( ... // các trường lớp // Hàm hiển thị bài viết hàm view() ( echo "

$this->tiêu đề

$this->nội dung

"; } }

Giả sử rằng đầu ra của một bài báo phải khác với cách trình bày của một bài báo thông thường và chúng ta cũng nên xuất ra thời gian xuất bản của tin tức. Cùng lúc đó ở lớp Bài báođã có một phương pháp xem(), chịu trách nhiệm về kết quả đầu ra của bài viết. Bạn có thể làm điều đó theo hai cách. Trong trường hợp đầu tiên, bạn có thể nghĩ đến phương pháp mới Trong lớp Tin tứcBài viết, ví dụ, với tên viewNews()đặc biệt để hiển thị tin tức. Tuy nhiên, sẽ đúng hơn khi sử dụng các phương thức tương tự để thực hiện các hành động tương tự trong các lớp kế thừa. Vì vậy sẽ tốt hơn nếu phương pháp hiển thị tin tức trong lớp Tin tứcBài viết sẽ được gọi giống như trong lớp cha - xem(). Để triển khai logic như vậy trong PHP, có thể ghi đè các phương thức cha, nghĩa là đặt trong các phương thức của lớp con có tên khớp với lớp cha mẹ. Việc triển khai các phương thức này trong lớp cha trong trường hợp này trở nên không liên quan đến lớp con. Hãy cho một ví dụ về một lớp Tin tứcBài viết với phương thức ghi đè xem():

Lớp NewsArticle mở rộng bài viết ( $datetime; // ngày xuất bản tin // Hàm hiển thị bài viết hàm view() ( echo "

$this->tiêu đề

". strftime("%d.%m.%y", $this->datetime) " Tin tức

$this->nội dung

"; } }

Đoạn mã sau sử dụng hàm strftime(), cho phép bạn hiển thị ngày ở dạng thuận tiện. Để hiểu rõ hơn về mã, vui lòng xem lại thông số kỹ thuật cho chức năng này trong tài liệu tham khảo. Đối với chúng tôi bây giờ điều quan trọng là bạn phải chú ý đến thực tế là lớp Tin tứcBài viết, giống Bài báo, định nghĩa phương thức xem(). Theo đó, tất cả các đối tượng của lớp này sẽ sử dụng phương thức xem() khai báo trong lớp Tin tứcBài viết, không có trong Bài báo.

Bạn có thể thắc mắc: tại sao việc ghi đè một số phương thức lại quan trọng thay vì giới thiệu các phương thức mới trong các lớp con? Hiểu điều này sẽ đi kèm với việc hiểu khái niệm quan trọng nhất tiếp theo về OOP.

Đa hình

Đa hình - khả năng thay thế lẫn nhau của các đối tượng với cùng một giao diện.

Ngôn ngữ lập trình hỗ trợ tính đa hình nếu các lớp có cùng đặc tả có thể có các cách triển khai khác nhau - ví dụ: việc triển khai một lớp có thể được thay đổi thông qua quá trình kế thừa. Đây chính xác là những gì chúng ta đã thấy trong ví dụ bài viết trước.

Hãy xem ví dụ sau đây, cho biết sự hiểu biết về bản chất của đa hình:

Lớp A ( function Test() ( echo "Đây là lớp A
"; ) function Call() ( $this->Test(); ) ) lớp B mở rộng A ( function Test() ( echo "Đây là lớp B
"; ) ) $a = new A(); $b = new B(); $a->Call(); // in: "Đây là lớp A" $b->Test(); // in: " Đây là lớp B" $b->

Hãy chú ý đến các bình luận ở ba dòng cuối cùng. Hãy tự mình thử giải thích kết quả này. Bạn nên tự mình thực hiện và thử nghiệm ví dụ này. Hãy dành thời gian để đảm bảo rằng bạn hoàn toàn hiểu rõ hoạt động của tập lệnh, bởi vì điều này một ví dụ nhỏ có một ý nghĩa sâu sắc đằng sau OOP. Bây giờ chúng ta hãy thử phân tích mã được đề xuất cùng nhau.

$a->Gọi(); // in: "Đây là lớp A"

Dòng này gọi phương thức Gọi() tại đối tượng lớp MỘT. Như được định nghĩa trong hàm Gọi() lớp học MỘT, phương thức này được gọi là Bài kiểm tra(). Thực hành phương pháp Bài kiểm tra() tại đối tượng lớp MỘT và dòng chữ “Đây là lớp A” hiển thị trên màn hình.

$b->Kiểm tra(); // in: "Đây là lớp B"

Dòng này gọi phương thức Bài kiểm tra() tại đối tượng lớp B. Phương pháp Bài kiểm tra() lớp học B hiển thị dòng chữ "Đây là lớp B".

$b->Gọi(); // in: "Đây là lớp B"

Cuối cùng, trong dòng cuối cùng lớp học được gọi là Gọi() tại đối tượng lớp TRONG. Nhưng trong việc thực hiện lớp B chúng ta sẽ không thấy một phương thức như vậy, điều đó có nghĩa là nó được kế thừa từ lớp MỘT, bởi vì lớp B là hậu duệ của lớp MỘT. Chúng ta thấy gì khi thực hiện phương pháp này? Gọi() lớp học MỘT? Đoạn mã sau:

$this->Test();

Phương pháp Gọi() gọi một phương thức Bài kiểm tra()đối tượng mà nó nằm trong đó. Điều này có nghĩa là phương pháp này sẽ hoạt động Bài kiểm tra()đối tượng lớp B. Điều này giải thích kết quả hiển thị trên màn hình.

Đây là tất cả những gì về nó nguyên tắc đa hình. Lớp học có thể có phương pháp tương tự, nhưng cách thực hiện của chúng là khác nhau. Khi phát triển mã tập lệnh, chúng ta chỉ có thể biết thông số kỹ thuật chung về các phương thức của chúng cho một nhóm lớp, nhưng không biết phiên bản nào của lớp nào sẽ được sử dụng tại một thời điểm cụ thể.

Các khái niệm về đóng gói, kế thừa và đa hình có thể được gọi là ba trụ cột của OOP. Hiểu và áp dụng thành thạo các nguyên tắc của các khái niệm này - công thức để thành công phát triển sử dụng OOP.