Lập trình hướng đối tượng cho người mới bắt đầu. Nguyên lý lập trình hướng đối tượng OOP OOP

Có lẽ một nửa số vị trí tuyển dụng (nếu không muốn nói là nhiều hơn) yêu cầu kiến ​​thức và hiểu biết về OOP. Vâng, phương pháp này chắc chắn đã thu hút nhiều lập trình viên! Thông thường, việc hiểu OOP đi kèm với kinh nghiệm, vì thực tế không có tài liệu nào phù hợp và dễ tiếp cận về chủ đề này. Và ngay cả nếu có thì cũng không chắc độc giả sẽ bắt gặp được chúng. Tôi hy vọng tôi có thể giải thích các nguyên tắc của phương pháp tuyệt vời này, như người ta nói, trên ngón tay của tôi.

Vì vậy, ở đầu bài viết tôi đã đề cập đến thuật ngữ “phương pháp luận”. Khi áp dụng vào lập trình, thuật ngữ này ngụ ý sự hiện diện của bất kỳ tập hợp cách nào để tổ chức mã, phương pháp viết mã, tuân theo đó, lập trình viên sẽ có thể viết các chương trình hoàn toàn có thể sử dụng được.

OOP (hoặc lập trình hướng đối tượng) là một cách tổ chức mã chương trình trong đó các khối xây dựng chính của chương trình là các đối tượng và lớp và logic của chương trình được xây dựng dựa trên sự tương tác giữa chúng.


Về đối tượng và lớp

Lớp học- đây là cấu trúc dữ liệu có thể do chính lập trình viên tạo ra. Theo thuật ngữ OOP, một lớp bao gồm lĩnh vực(nói một cách đơn giản - các biến) và phương pháp(nói một cách đơn giản - chức năng). Và hóa ra, sự kết hợp giữa dữ liệu và các chức năng để làm việc trên nó trong một cấu trúc mang lại sức mạnh không thể tưởng tượng được. Một đối tượng là một thể hiện cụ thể của một lớp. Tương tự như một lớp có cấu trúc dữ liệu, một đối tượng là một cấu trúc dữ liệu cụ thể có một số giá trị được gán cho các trường của nó. Hãy để tôi giải thích bằng một ví dụ:

Giả sử chúng ta cần viết một chương trình tính chu vi và diện tích của một hình tam giác, tính theo hai cạnh và góc giữa chúng. Để viết một chương trình như vậy bằng OOP, chúng ta sẽ cần tạo một lớp (tức là một cấu trúc) Tam giác. Lớp Triangle sẽ lưu trữ ba trường (ba biến): cạnh A, cạnh B, góc giữa chúng; và hai phương thức (hai hàm): tính chu vi, tính diện tích. Với lớp này, chúng ta có thể mô tả bất kỳ hình tam giác nào và tính chu vi và diện tích. Vì vậy, một tam giác cụ thể với các cạnh cụ thể và một góc giữa chúng sẽ được gọi là một thể hiện của lớp Tam giác. Do đó, một lớp là một mẫu và một thể hiện là một triển khai cụ thể của mẫu đó. Nhưng các thể hiện là các đối tượng, tức là các phần tử cụ thể lưu trữ các giá trị cụ thể.

Một trong những ngôn ngữ lập trình hướng đối tượng phổ biến nhất là java. Ở đó bạn đơn giản là không thể làm gì nếu không sử dụng đồ vật. Đây là mã của một lớp mô tả một hình tam giác trong ngôn ngữ này sẽ trông như thế nào:

/** * Lớp tam giác. */ class Triangle ( /** * Phương thức đặc biệt được gọi là hàm tạo lớp. * Lấy ba tham số làm đầu vào: * chiều dài cạnh A, chiều dài cạnh B, * góc giữa các cạnh này (tính bằng độ) */ Triangle(double sideA, double sideB , double angleAB) ( this.sideA = sideA; this.sideB = sideB; this.angleAB = gócAB; ) double sideA; //Trường lớp, lưu trữ giá trị của cạnh A trong tam giác được mô tả double sideB; //Trường lớp , lưu trữ giá trị của cạnh B trong tam giác đôi gócAB được mô tả; //Trường lớp lưu trữ góc (tính bằng độ) giữa hai cạnh trong tam giác được mô tả /** * Phương thức lớp tính diện tích của tam giác */ double getSquare() ( double Square = this.sideA * this .sideB * Math.sin(this.angleAB * Math.PI / 180); trả về bình phương; ) /** * Phương thức lớp tính chu vi của một hình tam giác */ double getPerimeter() ( double sideC = Math.sqrt(Math.pow (this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math.cos(this. gócAB * Math.PI/180)); chu vi gấp đôi = this.sideA + this.sideB + sideC; chu vi trở lại; ) )

Nếu chúng ta thêm đoạn mã sau vào trong lớp:

/** * Đây là nơi chương trình chạy */ public static void main(String args) ( //Các giá trị 5, 17, 35 đi vào hàm tạo của lớp Triangle Triangle Triangle1 = new Triangle(5, 17, 35 ); System.out .println("Diện tích tam giác1: "+tam giác1.getSquare()); System.out.println("Chu vi tam giác1: "+tam giác1.getPerimeter()); // Giá trị ​6 , 8, 60 đi tới hàm tạo của lớp Triangle Triangle Triangle2 = new Triangle(6, 8, 60); System.out.println("Diện tích tam giác1: "+triangle2.getSquare()); System.out.println ("Chu vi của tam giác1: "+triangle2.getPerimeter()); )

thì chương trình đã có thể được khởi chạy để thực thi. Đây là một tính năng của ngôn ngữ java. Nếu lớp có một phương thức như vậy

Khoảng trống tĩnh công khai chính(String args)

sau đó lớp này có thể được thực thi. Chúng ta hãy xem xét mã chi tiết hơn. Hãy bắt đầu với dòng

Tam giác tam giác1 = Tam giác mới(5, 17, 35);

Ở đây chúng ta tạo một thể hiện của Triangle1 của lớp Triangle và ngay lập tức cung cấp cho nó các tham số của các cạnh và góc giữa chúng. Đồng thời, một phương thức đặc biệt gọi là hàm tạo được gọi và điền vào các trường của đối tượng các giá trị được truyền cho hàm tạo. Vâng, còn các dòng thì sao?

System.out.println("Diện tích tam giác1: "+tam giác1.getSquare()); System.out.println("Chu vi của tam giác1: "+triangle1.getPerimeter());

xuất diện tích tính toán của hình tam giác và chu vi của nó ra bảng điều khiển.

Điều tương tự cũng xảy ra với phiên bản thứ hai của lớp Triangle.

Hiểu bản chất của các lớp và cách xây dựng các đối tượng cụ thể là bước đầu tiên tự tin để hiểu phương pháp OOP.

Một lần nữa, điều quan trọng nhất:

OOP- đây là cách tổ chức mã chương trình;

Lớp học- đây là cấu trúc dữ liệu tùy chỉnh tập hợp dữ liệu và hàm để làm việc với chúng (trường lớp và phương thức lớp);

Một đối tượng là một thể hiện cụ thể của một lớp có các trường được cung cấp các giá trị cụ thể.


Ba từ kỳ diệu

OOP bao gồm ba cách tiếp cận chính: kế thừa, đóng gói và đa hình. Để bắt đầu, tôi sẽ đưa ra định nghĩa từ wikipedia:

Đóng gói là một thuộc tính hệ thống cho phép bạn kết hợp dữ liệu và các phương thức hoạt động với chúng trong một lớp. Một số ngôn ngữ (ví dụ C++) đánh đồng việc đóng gói với việc ẩn, nhưng hầu hết (Smalltalk, Eiffel, OCaml) đều phân biệt giữa các khái niệm này.

Kế thừa là một thuộc tính hệ thống cho phép bạn mô tả một lớp mới dựa trên lớp hiện có với chức năng mượn một phần hoặc toàn bộ. Lớp mà sự kế thừa được bắt nguồn từ đó được gọi là lớp cơ sở, lớp cha hoặc lớp cha. Một lớp mới là lớp con cháu, lớp thừa kế, lớp con hoặc lớp dẫn xuất.

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

Việc hiểu ý nghĩa thật sự của tất cả những định nghĩa này là khá khó khăn. Trong những cuốn sách chuyên ngành đề cập đến chủ đề này, mỗi định nghĩa thường dành cả một chương nhưng ít nhất là một đoạn văn. Mặc dù vậy, bản chất những gì một lập trình viên cần hiểu và in sâu mãi trong đầu là rất ít.
Và để làm ví dụ cho việc phân tích, chúng ta sẽ sử dụng các số liệu trên mặt phẳng. Từ hình học phổ thông, chúng ta biết rằng đối với tất cả các hình vẽ trên mặt phẳng, đều có thể tính được chu vi và diện tích. Ví dụ: đối với một điểm cả hai tham số đều bằng 0. Đối với một đoạn, chúng ta chỉ có thể tính chu vi. Và đối với hình vuông, hình chữ nhật hoặc hình tam giác - cả hai. Bây giờ chúng tôi sẽ mô tả nhiệm vụ này theo thuật ngữ OOP. Bạn cũng nên nắm bắt chuỗi lý luận dẫn đến hệ thống phân cấp lớp, từ đó, được thể hiện trong mã làm việc. Đi:


Vì vậy, điểm là hình hình học nhỏ nhất, là cơ sở của tất cả các công trình (hình) khác. Vì vậy, điểm được chọn làm lớp cha cơ sở. Hãy viết một lớp điểm trong Java:

/** * Lớp điểm. Lớp cơ sở */ lớp Điểm ( /** * Hàm tạo trống */ Point() () /** * Phương thức lớp tính diện tích hình */ double getSquare() ( return 0; ) /** * Phương thức lớp tính chu vi của hình */ double getPerimeter() ( return 0; ) /** * Phương thức lớp trả về mô tả của hình */ String getDescription() ( return "Point"; ) )

Lớp Point kết quả có một hàm tạo trống, vì trong ví dụ này chúng ta đang làm việc mà không có tọa độ cụ thể và chỉ hoạt động với các tham số và giá trị bên. Vì điểm không có cạnh nên không cần truyền bất kỳ tham số nào cho nó. Cũng lưu ý rằng lớp này có các phương thức Point::getSquare() và Point::getPerimeter() để tính diện tích và chu vi, cả hai đều trả về 0. Đối với một điểm, điều đó là hợp lý.


Vì điểm của chúng ta là cơ sở của tất cả các hình khác nên chúng ta kế thừa các lớp của các hình này từ lớp Point. Chúng ta hãy mô tả lớp của một đoạn được kế thừa từ lớp của một điểm:

/** * Phân đoạn dòng lớp */ lớp LineSegment mở rộng Điểm ( LineSegment(double SegLength) ( this.segmentLength = SegLength; ) double SegmentLength; // Độ dài của dòng /** * Phương thức lớp được ghi đè tính diện tích của ​dòng */ double getSquare( ) ( return 0; ) /** * Phương thức lớp được ghi đè tính toán chu vi của một đoạn */ double getPerimeter() ( return this.segmentLength; ) Chuỗi getDescription() ( return "Độ dài đoạn: " + this.segmentLength; ) )

Phân đoạn dòng lớp mở rộng điểm

có nghĩa là lớp LineSegment kế thừa từ lớp Point. Các phương thức LineSegment::getSquare() và LineSegment::getPerimeter() ghi đè các phương thức lớp cơ sở tương ứng. Diện tích của một đoạn luôn bằng 0 và diện tích chu vi bằng chiều dài của đoạn này.

Bây giờ, giống như lớp phân đoạn, chúng ta mô tả lớp tam giác (cũng kế thừa từ lớp điểm):

/** * Lớp tam giác. */ lớp Tam giác mở rộng Điểm ( /** * Hàm tạo lớp. Lấy ba tham số làm đầu vào: * độ dài cạnh A, độ dài cạnh B, * góc giữa các cạnh này (tính bằng độ) */ Tam giác(hai cạnhA, hai cạnhB, double angleAB ) ( this.sideA = sideA; this.sideB = sideB; this.angleAB = gócAB; ) double sideA; //Trường lớp, lưu trữ giá trị của cạnh A trong tam giác được mô tả double sideB; //Trường lớp, lưu trữ giá trị của cạnh B trong tam giác được mô tả tam giác góc đôiAB; //Trường lớp lưu trữ góc (tính bằng độ) giữa hai cạnh trong tam giác được mô tả /** * Phương thức lớp tính diện tích của một tam giác */ double getSquare() ( double Square = (this.sideA * this.sideB * Math.sin(this.angleAB * Math.PI / 180))/2; return Square; ) /** * Phương thức lớp tính chu vi của một tam giác */ double getPerimeter() ( double sideC = Math.sqrt(Math. pow(this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math.cos (this.angleAB * Math.PI/180)); chu vi gấp đôi = this.sideA + this.sideB + sideC; chu vi trở lại; ) Chuỗi getDescription() ( return "Tam giác có các cạnh: " + this.sideA + ", " + this.sideB + " và góc giữa chúng: " + this.angleAB; ) )

Không có gì mới ở đây cả. Ngoài ra, các phương thức Triangle::getSquare() và Triangle::getPerimeter() ghi đè các phương thức tương ứng của lớp cơ sở.
Chà, trên thực tế, chính đoạn mã này thể hiện sự kỳ diệu của tính đa hình và bộc lộ sức mạnh của OOP:

Class Main ( /** * Đây là nơi chương trình chạy */ public static void main(String args) ( //ArrayList - Đây là cấu trúc dữ liệu đặc biệt trong java // cho phép bạn lưu trữ các đối tượng thuộc một loại nhất định trong một array.ArrayList figure = new ArrayList (); //thêm ba đối tượng khác nhau vào các hình mảng figure.add(new Point());figures.add(new LineSegment(133));figures.add(new Triangle(10, 17, 55)); cho ( int i = 0;i

Chúng ta đã tạo một mảng các đối tượng của lớp Point, và vì các lớp LineSegment và Triangle kế thừa từ lớp Point nên chúng ta có thể đặt chúng trong mảng này. Hóa ra là chúng ta có thể coi mỗi hình trong mảng figure là một đối tượng của lớp Point. Tính đa hình là như thế này: không biết các đối tượng trong mảng hình thuộc về lớp nào, nhưng vì tất cả các đối tượng bên trong mảng này thuộc về cùng một lớp cơ sở Point, nên tất cả các phương thức áp dụng cho lớp Point cũng có thể áp dụng được đến các lớp con cháu của nó.


Bây giờ về đóng gói. Việc chúng ta đặt các tham số của một hình và các phương thức tính diện tích, chu vi trong một lớp là sự đóng gói; chúng ta đã gói gọn các hình đó thành các lớp riêng biệt. Việc chúng ta sử dụng một phương thức đặc biệt trong lớp để tính chu vi là tính đóng gói; chúng ta đã gói gọn việc tính chu vi trong phương thức getPerimiter(). Nói cách khác, đóng gói đang che giấu việc triển khai (có lẽ là định nghĩa ngắn nhất, đồng thời, đầy đủ về khả năng đóng gói).


Mã ví dụ đầy đủ:

Nhập java.util.ArrayList; class Main ( /** * Đây là nơi chương trình chạy */ public static void main(String args) ( //ArrayList là một cấu trúc dữ liệu đặc biệt trong java // cho phép bạn lưu trữ các đối tượng thuộc một loại nhất định trong một mảng. ArrayList figure = new ArrayList (); //thêm ba đối tượng khác nhau vào mảng hình figure.add(new Point()); figure.add(new LineSegment(133)); figure.add(new Triangle(10, 17, 55)); cho ( int i = 0;i

Nó dựa trên việc biểu diễn một chương trình dưới dạng một tập hợp các đối tượng. Mỗi đối tượng thuộc về một lớp, lớp này sẽ chiếm vị trí của nó trong hệ thống phân cấp được kế thừa. Sử dụng OOP giảm thiểu dữ liệu dư thừa, giúp cải thiện khả năng kiểm soát và hiểu biết về chương trình.

OOP là gì

Nó phát sinh như là kết quả của sự phát triển của lập trình thủ tục. Cơ sở của ngôn ngữ hướng đối tượng là các nguyên tắc sau:

  • đóng gói;
  • di sản;
  • tính đa hình.

Một số nguyên tắc ban đầu được đặt ra trong OYA đầu tiên đã trải qua những thay đổi đáng kể.

Ví dụ về ngôn ngữ hướng đối tượng:

  1. Pascal. Với việc phát hành Delphi 7, nó chính thức được gọi là Delphi. Lĩnh vực sử dụng chính của Object Pascal là viết phần mềm ứng dụng.
  2. C++ được sử dụng rộng rãi để phát triển phần mềm và là một trong những ngôn ngữ phổ biến nhất. Được sử dụng để tạo hệ điều hành, chương trình ứng dụng, trình điều khiển thiết bị, ứng dụng, máy chủ, trò chơi.
  3. Java - được dịch sang mã byte, được xử lý bởi máy ảo Java. Ưu điểm của phương pháp thực thi này là tính độc lập của nó với hệ điều hành và phần cứng. Các dòng hiện có: Phiên bản tiêu chuẩn, Phiên bản doanh nghiệp, Phiên bản vi mô, Thẻ.
  4. JavaScript được sử dụng làm ngôn ngữ kịch bản cho các trang web. Cú pháp rất giống với C và Java. Là một triển khai của Ecmascript. Bản thân Ecmascript được dùng làm cơ sở để xây dựng các phần mềm khác như JScript, ActionScript.
  5. Objective-C được xây dựng trên ngôn ngữ C và bản thân mã C có thể hiểu được bởi trình biên dịch Objective-C.
  6. Perl là một ngôn ngữ cấp cao, được diễn giải, năng động, có mục đích chung. Nó có nhiều khả năng làm việc với văn bản và ban đầu được thiết kế đặc biệt để thao tác văn bản. Hiện được sử dụng trong quản trị hệ thống, phát triển, lập trình mạng, tin sinh học, v.v.
  7. PHP. Chữ viết tắt được dịch là bộ tiền xử lý siêu văn bản. Được sử dụng để phát triển các ứng dụng web, đặc biệt là phần máy chủ. Với sự trợ giúp của nó, bạn có thể tạo các ứng dụng gui bằng gói WinBinder.
  8. Python là ngôn ngữ có mục đích chung tập trung vào việc cải thiện năng suất của nhà phát triển và khả năng đọc mã. Dự án Cython đã được phát triển, với sự trợ giúp của các chương trình viết bằng Python được dịch sang mã bằng ngôn ngữ C.

Trừu tượng

Bất kỳ cuốn sách nào như “Lập trình hướng đối tượng cho người mới bắt đầu” đều nêu bật một trong những nguyên tắc chính - tính trừu tượng. Ý tưởng là tách các chi tiết hoặc đặc điểm của việc thực hiện chương trình thành những phần quan trọng và những phần không quan trọng. Cần thiết cho các dự án lớn, nó cho phép bạn làm việc ở các cấp độ biểu diễn hệ thống khác nhau mà không cần chỉ định chi tiết.

Một kiểu dữ liệu trừu tượng được biểu diễn dưới dạng giao diện hoặc cấu trúc. Cho phép bạn không phải suy nghĩ về mức độ chi tiết thực hiện. ADT độc lập với các phần mã khác.

Câu cách ngôn nổi tiếng của David Wheeler khẳng định: Mọi vấn đề trong khoa học máy tính đều có thể được giải quyết ở một mức độ trừu tượng khác.

Di sản

Ngôn ngữ hướng đối tượng có tính kế thừa - đây là một trong những nguyên tắc quan trọng nhất.

Chỉ ra rằng một số loại chức năng có thể được sử dụng lại. Một lớp kế thừa các thuộc tính của một lớp khác được gọi là lớp dẫn xuất, lớp con hoặc lớp con. Lớp mà sự kế thừa xảy ra được gọi là tổ tiên, lớp cơ sở hoặc lớp cha. Mối quan hệ con cháu-người thừa kế làm phát sinh một hệ thống phân cấp đặc biệt.

Có một số loại thừa kế:

  • đơn giản;
  • số nhiều.

Với đa thừa kế, có thể có nhiều con từ một tổ tiên, trong khi với thừa kế đơn giản thì chỉ có thể có một. Đây là sự khác biệt chính giữa các loại.

Kế thừa trông như thế này:

hàm vẽ() (

trả về "chỉ là động vật";

hàm ăn() (

đáp lại “con vật đang ăn”;

lớp Bò mở rộng Động vật (

hàm vẽ() (

Trả về "thứ gì đó trông giống con bò";

Ta thấy lớp Cow kế thừa tất cả các phương thức từ lớp Animal. Bây giờ, nếu chúng ta thực thi Cow.eat(), chúng ta nhận được "con vật đang ăn", do đó phương thức draw() được thay đổi. Cow.draw() sẽ trả về “thứ gì đó trông giống con bò” và Animal.draw() sẽ trả về “chỉ là động vật”.

đóng gói

Việc đóng gói giới hạn quyền truy cập của các thành phần này vào các thành phần khác, liên kết dữ liệu với các phương thức xử lý. Trình xác định quyền truy cập riêng được sử dụng để đóng gói.

Thông thường các khái niệm về đóng gói và ẩn giống hệt nhau, nhưng một số ngôn ngữ phân biệt các khái niệm này. Nói cách khác, các thuộc tính quan trọng về hiệu suất được bảo vệ và không thể thay đổi.

hàm __construct($name) (

$this->name = $name;

hàm getName() (

trả lại $this->name;

Tên được chấp nhận làm đối số của hàm tạo. Khi hàm tạo được sử dụng trong các phần khác của mã, sẽ không có gì có thể thay đổi thành phần tên. Như bạn có thể thấy, nó được chỉ định nội bộ; nó không có sẵn cho các phần khác của mã.

Đa hình

Tính đa hình cho phép bạn sử dụng cùng một tên để giải quyết các vấn đề tương tự nhưng khác nhau về mặt kỹ thuật.

Ví dụ trên có chứa một bảng. Chúng ta thấy lớp CardDesk và lớp GraphicalObject. Cả hai đều có chức năng gọi là draw(). Nó thực hiện các hành động khác nhau mặc dù có cùng tên.

Đa hình ad hoc hoặc sử dụng đa hình đặc biệt:

  • nạp chồng các hàm và phương thức;
  • dàn diễn viên.

Quá tải liên quan đến việc sử dụng một số hàm có cùng tên khi việc lựa chọn các hàm phù hợp xảy ra ở giai đoạn biên dịch.

Truyền kiểu có nghĩa là chuyển đổi giá trị của một loại thành giá trị của loại khác. Có một chuyển đổi rõ ràng - một hàm được áp dụng lấy một kiểu và trả về một kiểu khác, ẩn - được thực hiện bởi trình biên dịch hoặc trình thông dịch.

“Một giao diện, nhiều cách triển khai” Bjarne Stroustrup.

Lớp học

Lớp là một kiểu dữ liệu bao gồm một tập hợp các trường và phương thức.

Có giao diện bên trong và bên ngoài để quản lý nội dung. Khi sao chép qua phép gán, giao diện được sao chép chứ không phải dữ liệu. Các loài khác nhau tương tác với nhau thông qua:

  • di sản;
  • hiệp hội;
  • tổng hợp.

Khi kế thừa, lớp con kế thừa tất cả các thuộc tính của lớp cha; sự liên kết ngụ ý sự tương tác của các đối tượng. Khi một đối tượng của một lớp được đưa vào một lớp khác, nó được gọi là tập hợp. Nhưng khi chúng vẫn phụ thuộc vào nhau trong suốt cuộc đời thì đây là sự sáng tác.

Một trong những đặc điểm chính là phạm vi. Khái niệm này được định nghĩa khác nhau bởi các ngôn ngữ khác nhau.

Trong Object Pascal nó được mô tả như sau:

Tên lớp = lớp (SuperClass)

(việc sử dụng các phần tử chỉ bị giới hạn trong mô-đun)

(các trường được chỉ định ở đây)

(công cụ xác định truy cập đã có sẵn với Delphi 2007, có nghĩa giống như riêng tư)

(các phần tử có thể được sử dụng bên trong ClassName hoặc khi kế thừa)

(các phần tử có sẵn cho mọi người, chúng được hiển thị trong Trình kiểm tra đối tượng)

Ở đây SuperClass là tổ tiên mà từ đó sự kế thừa xảy ra.

Đối với C++ việc tạo trông như thế này:

lớp MyClass: cha mẹ công khai

Lớp học của tôi(); // người xây dựng

~Lớp của tôi(); // hàm hủy

Trong ví dụ này, Parent là tổ tiên, nếu có. Các chỉ định riêng tư, công khai, được bảo vệ có ý nghĩa tương tự như trong ví dụ trước trong Pascal. Chúng ta cũng thấy hàm tạo và hàm hủy có sẵn cho bất kỳ phần nào của chương trình. Trong C++, tất cả các phần tử đều ở chế độ riêng tư theo mặc định, vì vậy điều này có thể được bỏ qua.

Tính năng triển khai

Trung tâm của các ngôn ngữ hướng đối tượng là đối tượng, nó là một phần của lớp. Nó bao gồm:

  • lĩnh vực;
  • phương pháp.

Trường dữ liệu mô tả các tham số của đối tượng. Chúng đại diện cho một giá trị nhất định thuộc về một lớp và mô tả trạng thái cũng như thuộc tính của nó. Chúng được đóng theo mặc định và thay đổi dữ liệu xảy ra thông qua việc sử dụng các phương pháp khác nhau.

Phương thức là một tập hợp các hàm xác định tất cả các hành động có thể được thực hiện trên một đối tượng. Tất cả các đối tượng tương tác bằng cách gọi các phương thức của nhau. Chúng có thể ở bên ngoài hoặc bên trong, được chỉ định bởi các công cụ sửa đổi truy cập.

Phương pháp OOP

Có các phương pháp sau:

  • Lập trình hướng thành phần;
  • Lập trình nguyên mẫu;
  • Lập trình theo định hướng lớp học.

Lập trình hướng thành phần dựa trên khái niệm về một thành phần - một thành phần của chương trình được dự định sẽ được sử dụng lại. Nó được triển khai như một tập hợp các cấu trúc có tính năng, quy tắc và hạn chế chung. Cách tiếp cận này được sử dụng trong ngôn ngữ Java hướng đối tượng, trong đó định hướng thành phần được triển khai thông qua “JavaBeans” được viết theo cùng các quy tắc.

Trong lập trình nguyên mẫu không có khái niệm về lớp - sự kế thừa đạt được bằng cách sao chép một nguyên mẫu hiện có. Nó là nền tảng của các ngôn ngữ hướng đối tượng javascript và các phương ngữ ecmascript khác, cũng như lua hoặc lo. Những đặc điểm chính:

  • con cháu không nên giữ lại sự tương đồng về cấu trúc với nguyên mẫu (trong mối quan hệ giữa lớp-thể hiện, đây chính xác là điều sẽ xảy ra);
  • khi sao chép một nguyên mẫu, tất cả các phương thức đều được kế thừa từng cái một.

Lập trình hướng lớp tập trung vào và ví dụ. Một lớp xác định một cấu trúc, hành vi chung cho các cá thể áp dụng nó.

Ngôn ngữ hướng đối tượng

Tất cả các OOP đều tuân thủ đầy đủ các nguyên tắc OOP - các phần tử là các đối tượng có các thuộc tính. Trong trường hợp này, có thể có thêm tiền.

OOYA nhất thiết phải chứa một tập hợp các phần tử sau:

  • khai báo lớp với các trường, phương thức;
  • mở rộng thông qua kế thừa các chức năng;
  • hành vi đa hình.

Ngoài danh sách trên, có thể bổ sung thêm các công cụ:

  • hàm tạo, hàm hủy, hàm hoàn thiện;
  • của cải;
  • người lập chỉ mục;
  • truy cập sửa đổi.

Một số OYA đáp ứng tất cả các yếu tố cơ bản, số khác đáp ứng một phần. Một số khác nữa là lai, nghĩa là chúng được kết hợp với các hệ thống con của các mô hình khác. Nói chung, các nguyên tắc OOP cũng có thể được áp dụng cho ngôn ngữ không hướng đối tượng. Tuy nhiên, việc sử dụng OTL vẫn chưa làm cho mã trở nên hướng đối tượng.

Ngôn ngữ ngôn ngữ hỗ trợ nhiều hơn một mô hình. Ví dụ: PHP hoặc JavaScript hỗ trợ lập trình hướng đối tượng, chức năng, thủ tục. Java hoạt động với năm mô hình: hướng đối tượng, chung, thủ tục, hướng khía cạnh, đồng thời. C# được coi là một trong những ví dụ thành công nhất của chủ nghĩa đa mô hình. Nó hỗ trợ các cách tiếp cận tương tự như Java, với việc bổ sung mô hình phản ánh được thêm vào danh sách. Một ngôn ngữ như Oz được thiết kế để tập hợp tất cả các khái niệm truyền thống gắn liền với các mô hình phần mềm khác nhau.

Đối với nhiều lập trình viên PHP, lập trình hướng đối tượng là một khái niệm đáng sợ, đầy cú pháp phức tạp và những trở ngại khác để thành thạo. Trong bài viết này khái niệm lập trình hướng đối tượng(OOP) được thể hiện dưới dạng kiểu mã hóa cho phép bạn nhóm các hoạt động liên quan thành các lớp để tạo mã nhỏ gọn và hiệu quả hơn.

lập trình hướng đối tượng là gì

Lập trình hướng đối tượng là một kiểu mã hóa cho phép nhà phát triển nhóm các nhiệm vụ tương tự thành các lớp học. Do đó, mã tuân thủ nguyên tắc DRY (không lặp lại chính mình) và trở nên dễ bảo trì.

Một trong những ưu điểm của lập trình DRY là nếu một số thông tin yêu cầu bạn thay đổi chương trình thì bạn cần phải chỉ thay đổi mã ở một nơi để cập nhật thuật toán. Một trong những cơn ác mộng tồi tệ nhất của nhà phát triển là duy trì mã khai báo dữ liệu lặp đi lặp lại, khiến mọi thay đổi đối với chương trình trở thành một trò chơi trốn tìm bất tận trong khi săn lùng các dữ liệu và phần thuật toán trùng lặp.

OOP khiến nhiều nhà phát triển sợ hãi vì nó giới thiệu cú pháp mới và thoạt nhìn có vẻ phức tạp hơn mã hóa thủ tục đơn giản. Tuy nhiên, khi xem xét kỹ hơn, OOP thực sự là một cách tiếp cận lập trình rất rõ ràng và cực kỳ đơn giản.

Đối tượng và lớp là gì

Trước khi đi sâu vào các định nghĩa rõ ràng về OOP, cần có hiểu biết cơ bản về sự khác biệt giữa các lớp họccác đối tượng. Phần này của bài viết sẽ giúp bạn có ý tưởng về các lớp, khả năng khác nhau của chúng và một số ứng dụng.

Sự khác biệt giữa các lớp và đối tượng là gì

Các nhà phát triển bắt đầu nói về các lớp và đối tượng, bắt đầu thay thế các khái niệm. Thật không may, điều này xảy ra rất thường xuyên.

Ví dụ, một lớp là Dự án nhà. Anh ta xác định trên giấy ngôi nhà sẽ trông như thế nào, mô tả rõ ràng tất cả các mối quan hệ giữa các bộ phận khác nhau của nó, ngay cả khi ngôi nhà không tồn tại trên thực tế.

Và đối tượng là ngôi nhà thực sự, được xây dựng theo dự án. Dữ liệu được lưu trữ trong một đồ vật cũng giống như gỗ, dây điện và bê tông tạo nên một ngôi nhà: nếu không lắp ráp theo thiết kế thì nó sẽ chỉ là một đống vật liệu. Tuy nhiên, khi kết hợp với nhau, chúng tạo nên một ngôi nhà tuyệt vời và thoải mái.

Các lớp tạo thành một cấu trúc dữ liệu và hành động và sử dụng thông tin này để xây dựng các đối tượng. Nhiều đối tượng có thể được xây dựng từ một lớp cùng một lúc, mỗi đối tượng sẽ độc lập với các đối tượng khác. Tiếp tục tương tự với việc xây dựng, toàn bộ khu phố có thể được xây dựng theo một thiết kế: 150 ngôi nhà khác nhau trông giống nhau, nhưng mỗi ngôi nhà lại chứa những gia đình khác nhau và cách trang trí nội thất của các tòa nhà cũng khác nhau.

Cấu trúc lớp học

Cú pháp tạo một lớp rất đơn giản: để khai báo một lớp, sử dụng từ khóa class, theo sau là tên lớp và một cặp dấu ngoặc nhọn (()):

Sau khi tạo một lớp, một đối tượng mới có thể được khởi tạo và lưu trữ trong một biến bằng từ khóa mới:

$obj = MyClass mới;

Để xem nội dung của một đối tượng, hãy sử dụng var_dump() :

Var_dump($obj);

Bạn có thể kiểm tra toàn bộ quá trình bằng cách sao chép tất cả mã vào tệp test.php:

Tải trang vào trình duyệt của bạn và dòng sau sẽ xuất hiện trên màn hình:

Đối tượng(MyClass)#1 (0) ( )

Bạn vừa tạo tập lệnh OOP đầu tiên của mình.

Xác định thuộc tính lớp

Các thuộc tính hoặc biến lớp được sử dụng để thêm dữ liệu vào một lớp. Thuộc tính hoạt động giống như các biến thông thường, nhưng chúng được liên kết với một đối tượng và chỉ có thể được truy cập bằng cách sử dụng đối tượng đó.

Để thêm thuộc tính vào lớp MyClass, hãy sử dụng mã này trong tập lệnh của bạn:

Từ khóa công khai xác định khả năng hiển thị của một thuộc tính mà chúng tôi sẽ đề cập ở phần sau của chương này. Thuộc tính sau đó được đặt tên bằng cú pháp biến thông thường và được gán một giá trị (mặc dù thuộc tính lớp không cần phải được khởi tạo).

Echo $obj->prop1;

Vì có thể có nhiều triển khai của một lớp mà không có tham chiếu đến một đối tượng cụ thể nên không thể đọc được thuộc tính này vì tập lệnh không thể xác định đối tượng nào sẽ đọc từ đó. Mũi tên (->) là cấu trúc OOP được sử dụng để truy cập các thuộc tính và phương thức của một đối tượng nhất định.

Sửa đổi tập lệnh trong test.php để đọc giá trị của thuộc tính thay vì hiển thị thông tin về toàn bộ lớp:

chống đỡ1; // Hiển thị thuộc tính?>

Làm mới trang trong trình duyệt của bạn để xem kết quả của tập lệnh:

Thuộc tính lớp

Xác định phương thức lớp

Phương pháp là một hàm lớp. Một hành động riêng lẻ mà một đối tượng có thể thực hiện được định nghĩa trong một lớp dưới dạng một phương thức.

Ví dụ: hãy tạo các phương thức đặt và đọc giá trị của thuộc tính $prop1:

prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "
"; ) ) $obj = MyClass mới; echo $obj->prop1; ?>

Ghi chú- OOP cho phép một đối tượng tham chiếu đến chính nó bằng cách sử dụng $this . Khi làm việc bên trong một phương thức, việc sử dụng $this cho phép bạn sử dụng tên của đối tượng bên ngoài lớp.

Để sử dụng một phương thức, hãy gọi nó giống như một hàm thông thường, nhưng trước tiên hãy chỉ định đối tượng mà nó thuộc về. Chúng tôi đọc thuộc tính từ MyClass , thay đổi giá trị, đọc lại:

prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "
"; ) ) $obj = new MyClass; echo $obj->getProperty(); // lấy giá trị thuộc tính $obj->setProperty("Thuộc tính mới."); // Đặt giá trị mới echo $obj->getProperty () ; // Đọc lại giá trị để xem thay đổi?>

Chúng tôi làm mới trang trong trình duyệt và thấy như sau:

Thuộc tính lớp Thuộc tính mới

Lợi ích của OOP phát huy tác dụng khi sử dụng nhiều đối tượng cùng một lớp.

prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "
"; ) ) // Tạo hai đối tượng $obj = new MyClass; $obj2 = new MyClass; // Lấy các giá trị ​​của $prop1 từ cả hai đối tượng echo $obj->getProperty(); echo $obj2->getProperty( ); // Đặt giá trị thuộc tính mới cho cả hai đối tượng $obj->setProperty("Giá trị thuộc tính mới"); $obj2->setProperty("Thuộc tính thuộc về đối tượng thứ hai"); // In các giá trị $prop1 ​​cho cả hai echo $obj->getProperty() ; echo $obj2->getProperty(); ?>

Khi bạn tải trang vào trình duyệt, bạn sẽ thấy như sau:

Thuộc tính lớp Thuộc tính lớp Giá trị thuộc tính mới Thuộc tính thuộc về đối tượng thứ hai

Ghi chú, OOP lưu trữ các đối tượng dưới dạng các thực thể khác nhau, giúp dễ dàng tách mã thành nhiều phần nhỏ và có liên kết với nhau.

Các phương thức kỳ diệu trong OOP

Để làm cho việc sử dụng các đối tượng dễ dàng hơn, PHP có một số những phương pháp thần kỳ.Đây là những phương thức đặc biệt được gọi khi một số hành động nhất định được thực hiện trên một đối tượng. Bằng cách này, nhà phát triển có thể hoàn thành một số nhiệm vụ phổ biến một cách tương đối dễ dàng.

Sử dụng hàm tạo và hàm hủy

Khi một đối tượng được tạo ra, thường cần phải thiết lập một số thuộc tính nhất định ngay lập tức. Để thực hiện các tác vụ như vậy, PHP có một phương thức kỳ diệu __construct() được gọi tự động khi một đối tượng mới được tạo.

Để minh họa khái niệm này, hãy thêm một hàm tạo vào lớp MyClass. Nó sẽ in một thông báo khi một đối tượng lớp mới được tạo:

"; ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "
"; ) ) // Tạo một đối tượng mới $obj = new MyClass; // Lấy giá trị của thuộc tính $prop1 echo $obj->
"; ?>

Ghi chú— hằng số __CLASS__ trả về tên của lớp mà nó được gọi; đây là một trong những hằng số kỳ diệu của PHP.

Một đối tượng của lớp "MyClass" đã được tạo! Thuộc tính lớp cuối của tệp.

Để gọi một hàm trong quá trình xóa một đối tượng, hãy sử dụng phương thức ma thuật __struct(). Đây là một phương pháp rất hữu ích để xóa đúng các thuộc tính của lớp (ví dụ: để đóng kết nối cơ sở dữ liệu đúng cách).

Chúng tôi sẽ hiển thị một thông báo khi một đối tượng lớp bị xóa bằng phương thức ma thuật:
__struct() trong MyClass:

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "
"; ) ) // Tạo một đối tượng mới $obj = new MyClass; // Lấy giá trị của thuộc tính $prop1 echo $obj->getProperty(); // Hiển thị thông báo về việc đến cuối file echo "End của tập tin.
"; ?>

Chúng ta làm mới trang trên trình duyệt và nhận được kết quả:

Một đối tượng của lớp "MyClass" đã được tạo! Thuộc tính lớp cuối của tệp. Đối tượng lớp "MyClass" đã bị xóa.

Khi đến cuối tệp, PHP sẽ tự động giải phóng tất cả tài nguyên.

Để gọi một hàm hủy và xóa một đối tượng một cách rõ ràng, bạn có thể sử dụng hàm unset():


"; ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "
"; ) ) // Tạo một đối tượng mới $obj = new MyClass; // Lấy giá trị của thuộc tính $prop1 echo $obj->getProperty(); // Xóa đối tượng unset($obj); // Hiển thị a thông báo về việc đến cuối tập tin echo "Cuối tập tin.
"; ?>

Bây giờ kết quả của đoạn mã sẽ như thế này sau khi tải vào trình duyệt:

Một đối tượng của lớp "MyClass" đã được tạo! Thuộc tính lớp Đối tượng lớp "MyClass" đã bị xóa. Phần cuối của tập tin.

Chuyển đổi thành chuỗi

Để tránh lỗi nếu tập lệnh cố xuất MyClass dưới dạng chuỗi, một phương thức ma thuật khác, __toString(), được sử dụng.

Không sử dụng __toString() cố gắng xuất một đối tượng dưới dạng chuỗi sẽ dẫn đến lỗi nghiêm trọng. Hãy thử sử dụng hàm echo để xuất một đối tượng mà không sử dụng phương thức ma thuật:

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty() ( return $this->prop1 . "

"; ?>

Kết quả sẽ như thế này:

Một đối tượng của lớp "MyClass" đã được tạo! Lỗi nghiêm trọng có thể bắt được: Không thể chuyển đổi đối tượng của lớp MyClass thành chuỗi trong /Applications/XAMPP/xamppfiles/htdocs/testing/test.php trên dòng 40

Để tránh lỗi, hãy sử dụng phương thức __toString():

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty( ) ( trả về $this->prop1 . "
"; ) ) // Tạo một đối tượng mới $obj = new MyClass; // Xuất đối tượng dưới dạng một chuỗi echo $obj; // Xóa đối tượng unset($obj); // Xuất ra thông báo về việc kết thúc chuỗi file echo "Kết thúc tập tin.
"; ?>

Trong trường hợp này, việc cố gắng chuyển đổi một đối tượng thành một chuỗi sẽ dẫn đến lệnh gọi phương thức getProperty(). Tải script vào trình duyệt và xem kết quả:

Một đối tượng của lớp "MyClass" đã được tạo! Chúng tôi sử dụng phương thức toString: Thuộc tính lớp Đối tượng lớp "MyClass" đã bị xóa. Phần cuối của tập tin.

Sử dụng kế thừa lớp

Các lớp có thể kế thừa các phương thức và thuộc tính từ các lớp khác bằng cách sử dụng từ khóa mở rộng. Ví dụ: hãy tạo một lớp thứ hai mở rộng MyClass và thêm một phương thức:

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty( ) ( trả về $this->prop1 . "
"; ) ) lớp MyOtherClass mở rộng MyClass ( public function newMethod() ( echo "Từ phương thức lớp mới " . __CLASS__ .".
"; ) ) // Tạo một đối tượng mới $newobj = new MyOtherClass; // Sử dụng phương thức mới echo $newobj->newMethod(); // Sử dụng phương thức từ lớp cha echo $newobj->getProperty(); ? >

Sau khi tải script vào trình duyệt, chúng ta nhận được kết quả:

Một đối tượng của lớp "MyClass" đã được tạo! Từ phương thức lớp mới "MyOtherClass". Thuộc tính lớp Đối tượng lớp "MyClass" đã bị xóa.

Quá tải các thuộc tính và phương thức được kế thừa

Để thay đổi hành vi của các thuộc tính hoặc phương thức hiện có trong một lớp mới, bạn chỉ cần nạp chồng chúng bằng cách khai báo lại chúng trong lớp mới:

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty( ) ( trả về $this->prop1 . "
"; ) ) lớp MyOtherClass mở rộng MyClass ( hàm công khai __construct() ( echo "Hàm tạo mới trong lớp " . __CLASS__ .".

"; ) ) // Tạo một đối tượng mới $newobj = new MyOtherClass; // Xuất đối tượng dưới dạng một chuỗi echo $newobj->newMethod(); // Sử dụng phương thức từ lớp cha echo $newobj->getProperty() ; ?>

Những thay đổi sẽ tạo ra kết quả sau khi chạy mã:

Hàm tạo mới trong lớp "MyOtherClass". Từ phương thức lớp mới "MyOtherClass". Thuộc tính lớp Đối tượng lớp "MyClass" đã bị xóa.

Bảo toàn chức năng ban đầu khi nạp chồng phương thức

Để thêm chức năng mới vào phương thức kế thừa trong khi vẫn duy trì chức năng của phương thức ban đầu, hãy sử dụng từ khóa parent với toán tử phân giải khả năng hiển thị ( :: ) :

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm công khai getProperty( ) ( trả về $this->prop1 . "
"; ) ) class MyOtherClass mở rộng MyClass ( public function __construct() ( parent::__construct(); // Gọi hàm tạo của lớp cha echo "Hàm tạo mới trong lớp " . __CLASS__ .".
"; ) hàm công khai newMethod() ( echo "Từ một phương thức mới của lớp " . __CLASS__ . ".
"; ) ) // Tạo một đối tượng mới $newobj = new MyOtherClass; // Xuất đối tượng dưới dạng một chuỗi echo $newobj->newMethod(); // Sử dụng phương thức từ lớp cha echo $newobj->getProperty() ; ?>

Đoạn mã trên, khi được thực thi, sẽ hiển thị các thông báo từ cả hàm tạo của lớp mới và lớp cha:

Một đối tượng của lớp "MyClass" đã được tạo! Hàm tạo mới trong lớp "MyOtherClass". Từ phương thức lớp mới "MyOtherClass". Thuộc tính lớp Đối tượng lớp "MyClass" đã bị xóa.

Xác định phạm vi của các thuộc tính và phương thức

Để kiểm soát bổ sung đối tượng, phương thức và thuộc tính, một phạm vi được đặt. Điều này kiểm soát cách thức và từ nơi các thuộc tính và phương thức có thể được truy cập. Có ba từ khóa để thiết lập phạm vi: public , protected và private . Ngoài việc thiết lập phạm vi, các phương thức và thuộc tính có thể được khai báo tĩnh, cho phép truy cập chúng mà không cần triển khai lớp.

Ghi chú- Phạm vi là một thuộc tính mới được giới thiệu trong PHP 5. Để biết khả năng tương thích OOP với PHP 4, hãy xem hướng dẫn sử dụng PHP.

Thuộc tính và phương thức công khai (Chung)

Tất cả các thuộc tính và phương thức bạn đã sử dụng trước đó trong bài viết này đều được công khai. Điều này có nghĩa là chúng có thể được truy cập ở bất cứ đâu, cả trong và ngoài lớp.

Các phương thức và thuộc tính được bảo vệ

Khi một thuộc tính hoặc phương thức được khai báo bằng chỉ thị được bảo vệ, nó chỉ có thể được truy cập trong chính lớp đó hoặc trong các lớp dẫn xuất(các lớp mở rộng một lớp cơ sở chứa một phương thức có lệnh được bảo vệ).

Hãy khai báo phương thức getProperty() là được bảo vệ trong MyClass và thử truy cập nó bên ngoài lớp:

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm được bảo vệ getProperty( ) ( trả về $this->prop1 . "

"; ) hàm công khai newMethod() ( echo "Từ một phương thức mới của lớp " . __CLASS__ . ".
"; ) ) // Tạo một đối tượng mới $newobj = new MyOtherClass; // Thử gọi phương thức được bảo vệ echo $newobj->getProperty(); ?>

Khi bạn cố gắng thực thi tập lệnh, lỗi sau sẽ được tạo ra:

Một đối tượng của lớp "MyClass" đã được tạo! Hàm tạo mới trong lớp "MyOtherClass". Lỗi nghiêm trọng: Gọi đến phương thức được bảo vệ MyClass::getProperty() từ ngữ cảnh "" trong /Applications/XAMPP/xamppfiles/htdocs/testing/test.php trên dòng 55

Bây giờ, hãy tạo một phương thức mới trong MyOtherClass để gọi phương thức getProperty():

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm được bảo vệ getProperty( ) ( trả về $this->prop1 . "
"; ) ) lớp MyOtherClass mở rộng MyClass ( hàm công khai __construct() ( parent::__construct(); echo "Hàm tạo mới trong lớp " . __CLASS__ .".
"; ) hàm công khai newMethod() ( echo "Từ một phương thức mới của lớp " . __CLASS__ . ".
"; ) public function callProtected() ( return $this->getProperty(); ) ) // Tạo một đối tượng mới $newobj = new MyOtherClass; // Gọi một phương thức được bảo vệ từ một phương thức public echo $newobj->callProtected() ; ?>

Khi chạy script sẽ có kết quả như sau:

Một đối tượng của lớp "MyClass" đã được tạo! Hàm tạo mới trong lớp "MyOtherClass". Thuộc tính lớp Đối tượng lớp "MyClass" đã bị xóa.

Phương thức và thuộc tính riêng tư

Các thuộc tính và phương thức được khai báo là riêng tư có thể truy cập được chỉ trong lớp mà chúng được định nghĩa. Nó có nghĩa là ngay cả khi lớp mới được dẫn xuất từ ​​một lớp xác định các thuộc tính và phương thức riêng tư, chúng sẽ không có sẵn trong lớp dẫn xuất.

Để minh họa, hãy khai báo phương thức getProperty() như riêng tư V. Lớp học của tôi, và hãy thử gọi phương thức callProtected() từ
Lớp khác của tôi :

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm riêng getProperty( ) ( trả về $this->prop1 . "
"; ) ) lớp MyOtherClass mở rộng MyClass ( hàm công khai __construct() ( parent::__construct(); echo "Hàm tạo mới trong lớp " . __CLASS__ .".
"; ) hàm công khai newMethod() ( echo "Từ một phương thức mới của lớp " . __CLASS__ . ".
"; ) public function callProtected() ( return $this->getProperty(); ) ) // Tạo một đối tượng mới $newobj = new MyOtherClass; // Sử dụng phương thức từ lớp cha echo $newobj->callProtected(); ?>

Chúng tôi lưu tập lệnh, làm mới trang trong trình duyệt và nhận được thông tin sau:

Một đối tượng của lớp "MyClass" đã được tạo! Hàm tạo mới trong lớp "MyOtherClass". Lỗi nghiêm trọng: Gọi đến phương thức riêng MyClass::getProperty() từ ngữ cảnh "MyOtherClass" trong /Applications/XAMPP/xamppfiles/htdocs/testing/test.php trên dòng 49

Các phương thức và thuộc tính tĩnh (tĩnh)

Các phương thức và thuộc tính được khai báo bằng lệnh tĩnh có thể được truy cập mà không cần khởi tạo lớp. Bạn chỉ cần sử dụng tên của lớp, toán tử cấp phép hiển thị và tên của thuộc tính hoặc phương thức.

Một trong những ưu điểm chính của thuộc tính tĩnh là chúng giữ lại các giá trị của mình trong toàn bộ tập lệnh.

Để chứng minh, hãy thêm thuộc tính tĩnh $count và phương thức tĩnh plusOne() vào lớp Lớp học của tôi. Sau đó, chúng ta sẽ thiết lập vòng lặp do...while để in ra giá trị tăng dần của $count cho đến khi nó lớn hơn 10:

"; ) hàm công khai __struct() ( echo "Class object "", __CLASS__, "" đã bị xóa.
"; ) hàm công khai __toString() ( echo "Sử dụng phương thức toString: "; return $this->getProperty(); ) hàm công khai setProperty($newval) ( $this->prop1 = $newval; ) hàm riêng getProperty( ) ( trả về $this->prop1 . "
"; ) hàm tĩnh công khai plusOne() ( return "count = " . ++self::$count . ".
"; ) ) lớp MyOtherClass mở rộng MyClass ( hàm công khai __construct() ( parent::__construct(); echo "Hàm tạo mới trong lớp " . __CLASS__ .".
"; ) hàm công khai newMethod() ( echo "Từ một phương thức mới của lớp " . __CLASS__ . ".
"; ) hàm công khai callProtected() ( return $this->getProperty(); ) ) do ( // Gọi plusOne mà không khởi tạo lớp MyClass echo MyClass::plusOne(); ) while (MyClass::$count< 10); ?>

Ghi chú- Để truy cập các thuộc tính tĩnh, phải có ký hiệu đô la ($) đứng sau toán tử cấp phép hiển thị.

Chạy script trên trình duyệt sẽ cho kết quả như sau:

Đếm = 1. Đếm = 2. Đếm = 3. Đếm = 4. Đếm = 5. Đếm = 6. Đếm = 7. Đếm = 8. Đếm = 9. Đếm = 10.

Lập trình hướng đối tượng (OOP) hiện là công nghệ lập trình phổ biến nhất. Lập trình hướng đối tượng là sự phát triển của công nghệ lập trình có cấu trúc nhưng có những nét đặc trưng riêng.

Các hệ thống lập trình trực quan hướng đối tượng phổ biến nhất là Microsoft Visual Basic và Borland Delphi.

Về cốt lõi, lập trình hướng đối tượng là tạo ra các ứng dụng từ các đối tượng, giống như những ngôi nhà được xây dựng từ các khối và các bộ phận khác nhau. Một số đối tượng phải được tạo hoàn toàn theo cách riêng của bạn, trong khi những đối tượng khác có thể được mượn làm sẵn từ nhiều thư viện khác nhau.

Một vị trí quan trọng trong công nghệ lập trình hướng đối tượng bị chiếm giữ bởi sự kiện. Sự kiện có thể là click chuột vào một đối tượng, nhấn một phím nhất định, mở tài liệu, v.v. Để phản ứng với các sự kiện, một thủ tục nhất định được gọi, có thể thay đổi các thuộc tính của đối tượng, gọi các phương thức của nó, v.v.

Các hệ thống lập trình hướng đối tượng thường sử dụng giao diện đồ họa để trực quan hóa quá trình lập trình. Có thể tạo các đối tượng, thiết lập các thuộc tính và hành vi của chúng bằng cách sử dụng chuột.

Một mặt, một đối tượng có một số thuộc tính nhất định đặc trưng cho trạng thái của nó tại một thời điểm nhất định và mặt khác, các hoạt động có thể dẫn đến thay đổi các thuộc tính.

Đơn vị cơ bản trong lập trình hướng đối tượng là một đối tượng đóng gói cả dữ liệu mô tả nó (thuộc tính) và phương tiện để xử lý dữ liệu này (phương thức).

Đóng gói là sự kết hợp các thuộc tính của một đối tượng và các hoạt động (phương thức) có thể có trên nó.

Một nguyên tắc cơ bản khác của OOP là khả năng tạo ra một lớp đối tượng mới với sự kế thừa các thuộc tính và phương thức của một số lớp đã tồn tại.

Kế thừa là khả năng lấy được lớp này từ lớp khác trong khi vẫn bảo toàn tất cả các thuộc tính và phương thức của lớp tổ tiên (lớp tiền thân, đôi khi được gọi là lớp cha) và thêm, nếu cần, các thuộc tính và phương thức mới.

Một tập hợp các lớp có quan hệ kế thừa được gọi là hệ thống phân cấp. Kế thừa nhằm mục đích phản ánh một thuộc tính của thế giới thực như hệ thống phân cấp.

Một nguyên tắc khác của OOP là nguyên tắc đa hình.

Đa hình là hiện tượng một hàm (phương thức) có cùng tên tương ứng với mã chương trình (mã đa hình) khác nhau tùy thuộc vào đối tượng lớp nào được sử dụng khi gọi phương thức này.

Tính đa hình được đảm bảo bằng cách thay đổi cách triển khai phương thức của lớp tổ tiên trong lớp con cháu với việc bắt buộc phải bảo toàn chữ ký phương thức. Điều này đảm bảo rằng giao diện của lớp tổ tiên không thay đổi và cho phép bạn liên kết tên phương thức trong mã với các lớp khác nhau - từ đối tượng của lớp mà cuộc gọi được thực hiện, từ lớp đó, phương thức có tên đã cho sẽ được lấy. Cơ chế này được gọi là liên kết động (hoặc muộn) - trái ngược với liên kết tĩnh (sớm), được thực hiện tại thời điểm biên dịch

Cách tiếp cận hướng đối tượng cho phép bạn kết hợp mô hình tĩnh mô tả các thuộc tính của đối tượng và mô hình động mô tả các thay đổi của chúng.

Với cách tiếp cận này, chỉ có thể truy cập để thay đổi các thuộc tính của một đối tượng thông qua các phương thức thuộc về đối tượng đó. Các phương thức “bao quanh” thuộc tính của một đối tượng; các thuộc tính được cho là được "đóng gói" trong một đối tượng.

Do đó, trong lập trình hướng đối tượng, vị trí trung tâm được chiếm giữ bởi các đối tượng kết hợp thành một tổng thể (đóng gói) các thuộc tính của đối tượng và các hoạt động (phương thức) có thể có trên đó.

Các đối tượng đóng gói cùng một danh sách các thuộc tính và hoạt động được kết hợp thành các lớp học. Mỗi đối tượng riêng lẻ đều một thể hiện của lớp. Các thể hiện của một lớp có thể có các giá trị thuộc tính khác nhau.

Ví dụ: hệ thống tệp của máy tính có thể chứa hàng trăm hoặc hàng nghìn tệp. Tất cả các tệp đều có cùng một bộ thuộc tính (tên, vị trí trong hệ thống tệp, v.v.) và các thao tác (đổi tên, di chuyển hoặc sao chép, v.v.) và tạo thành một lớp đối tượng Các tập tin.

Mỗi tệp riêng lẻ là một phiên bản của lớp này và có các giá trị thuộc tính cụ thể (tên, vị trí, v.v.).

Một tình huống thường xảy ra khi các thao tác giống nhau có thể được thực hiện trên các đối tượng thuộc các lớp khác nhau. Hầu hết các lớp đối tượng trong môi trường Windows (thư mục, tài liệu, ký hiệu, v.v.) cũng được đặc trưng bởi một tập hợp các thao tác giống nhau (đổi tên, di chuyển, sao chép, xóa, v.v.). Tính đồng nhất này rất thân thiện với người dùng.

Tuy nhiên, rõ ràng là cơ chế thực hiện các hoạt động này ở các lớp khác nhau là không giống nhau. Ví dụ: để sao chép một thư mục, bạn cần thực hiện một chuỗi hành động để thay đổi hệ thống tệp và để sao chép ký hiệu, thực hiện các thay đổi đối với tài liệu. Các thao tác này sẽ được thực hiện bởi nhiều chương trình khác nhau có sẵn tương ứng trong hệ điều hành Windows và trong trình soạn thảo văn bản Word.

Bằng cách này nó được thực hiện đa hình, những thứ kia. khả năng thực hiện các thao tác tương tự trên các đối tượng thuộc các lớp khác nhau, trong khi vẫn duy trì các phương thức riêng lẻ để triển khai chúng cho từng lớp.

Các đối tượng có cùng tập thuộc tính và phương thức lớp đối tượng. Vì vậy, trong ứng dụng Word có một lớp đối tượng tài liệu(Tài liệu), có các thuộc tính sau: Tên(Tên), vị trísự(FileNaine), v.v. Các đối tượng của lớp này cũng có một tập hợp các phương thức nhất định, ví dụ: mở một tài liệucảnh sát(Mở) in ấn tài liệu(In ra), sự bảo tồntài liệu(Lưu), v.v.

Các đối tượng trong ứng dụng tạo thành một số loại phân cấp. Ở đầu hệ thống phân cấp đối tượng là ứng dụng(Ứng dụng). Do đó, hệ thống phân cấp đối tượng ứng dụng Word bao gồm các đối tượng sau: ứng dụng(Ứng dụng), tài liệu(Các tài liệu), mảnh tài liệu(Tuyển chọn), biểu tượng(Nhân vật), v.v.

Hệ thống phân cấp đối tượng ứng dụng Excel bao gồm các đối tượng sau: ứng dụng(Ứng dụng), sách(Sách bài tập), tờ giấy(Bảng tính) phạm vi tế bào(Phạm vi), tế bàoka(Di động), v.v.

Một tham chiếu đầy đủ đến một đối tượng bao gồm một loạt tên của các đối tượng được lồng tuần tự vào nhau. Dấu phân cách cho tên đối tượng trong chuỗi này là dấu chấm; chuỗi bắt đầu bằng đối tượng Ứng dụng cấp cao nhất và kết thúc bằng tên của đối tượng mà chúng ta quan tâm. Ví dụ: liên kết đến tài liệu Пpo6a.doc trong Word sẽ có dạng như sau:

Ứng dụng. Các tài liệu("Ppo6a.doc")

Để một đối tượng thực hiện bất kỳ thao tác nào, một phương thức phải được chỉ định. Nhiều phương thức có các đối số cho phép bạn chỉ định các tham số cho các hành động sẽ được thực hiện. Để gán các giá trị cụ thể cho các đối số, dấu hai chấm và dấu bằng được sử dụng và các đối số được phân tách bằng dấu phẩy.

Trong Visual Basic, các đối tượng được đặc trưng không chỉ bởi các thuộc tính và phương thức mà còn bởi sự kiện. Một sự kiện là một hành động được một đối tượng thừa nhận. Một sự kiện có thể do người dùng tạo ra (ví dụ: nhấn nút chuột hoặc phím trên bàn phím) hoặc là kết quả hoạt động của các đối tượng ứng dụng khác.

Đối với mỗi sự kiện, bạn có thể lập trình phản hồi, tức là phản ứng của đối tượng đối với sự kiện đã xảy ra. Chương trình này được gọi là thủ tục sự kiện. Tên của một thủ tục sự kiện thường bao gồm tên của đối tượng và tên của sự kiện. Ví dụ: đối với một đối tượng nút có tên Yêu cầu1 và sự kiện Nhấp chuột("nhấp chuột" xảy ra khi chúng ta di chuyển con trỏ chuột qua hình ảnh nút và nhấn nút chuột trái) thủ tục sự kiện sẽ nhận được tên Yêu cầu1_ Nhấp chuột.

Một số đối tượng có thể tham gia vào một thủ tục sự kiện. Ví dụ, trong thủ tục nêu trên Yêu cầu1_ Nhấp chuộtđội có thể có mặt

Chữ1. Chữ= “Xin chào!”,

là kết quả của việc thực thi which trong đối tượng “trường văn bản” có tên Chữ1 Một dòng có chữ “Xin chào!” sẽ xuất hiện.

Lập trình trực quan, các phương pháp được môi trường phát triển Visual Basic sử dụng, cho phép bạn tạo giao diện đồ họa cho các ứng dụng đã phát triển dựa trên việc sử dụng các phần tử điều khiển, bao gồm nút(Nút lệnh), hộp kiểm(Hộp kiểm) , Trường văn bản(Hộp văn bản) hộp tổ hợp(ListBox) và những thứ khác. Những đối tượng này, thuộc tính và phương thức của chúng sẽ được thảo luận trong phần tiếp theo. Hiện tại, hãy lưu ý rằng các phần tử điều khiển thường được sử dụng nhiều nhất để nhận dữ liệu từ người dùng và hiển thị kết quả của ứng dụng. Như vậy, các điều khiển là cơ sở để xây dựng giao diện người dùng của ứng dụng.

Các đối tượng chính được sử dụng trong lập trình trực quan là các hình thức(Hình thức). Biểu mẫu là một cửa sổ nơi đặt các phần tử điều khiển. Một biểu mẫu cũng là một đối tượng được đặc trưng bởi một tập hợp các thuộc tính và phương thức. Giống như bất kỳ đối tượng nào khác, bạn có thể viết một thủ tục sự kiện cho một biểu mẫu, chẳng hạn Hình thức_ Trọng tải, được khởi chạy khi sự kiện Tải xảy ra và do đó các hướng dẫn cần thiết cho hoạt động của ứng dụng đã khởi chạy sẽ được thực thi.

Khái niệm lập trình hướng đối tượng (OOP) đã xuất hiện hơn bốn mươi năm trước, như một sự phát triển của các ý tưởng về lập trình thủ tục. Hệ tư tưởng của lập trình thủ tục không có gì đặc biệt: tất cả các chương trình được biểu diễn bằng một tập hợp các thủ tục và hàm, trong khi bản thân các thủ tục và hàm là các chuỗi câu lệnh, thực thi mà máy tính sẽ sửa đổi giá trị của các biến trong bộ nhớ. Chương trình chính trong lập trình thủ tục cũng là một thủ tục (hàm), phần thân của nó có thể chứa các lệnh gọi đến các thủ tục và hàm khác - chương trình con. Bản chất của lập trình thủ tục rất đơn giản: dữ liệu riêng biệt, hành vi riêng biệt. Tôi đã cố gắng thu thập những gì một ngôn ngữ lập trình thủ tục bao gồm (nó bao gồm những cấu trúc gì) trong một phần riêng biệt. Việc chia mã thành các chương trình con, trước hết, cho phép bạn làm nổi bật các đoạn mã có thể sử dụng lại và thứ hai, làm cho mã chương trình có cấu trúc.

Hệ tư tưởng của lập trình hướng đối tượng, đúng như tên gọi, được xây dựng xung quanh khái niệm đối tượng. Một đối tượng kết hợp cả dữ liệu và hành vi. Đối tượng là bất kỳ thực thể nào mà chương trình xử lý, cụ thể là: các đối tượng miền được chương trình mô hình hóa; tài nguyên hệ điều hành; giao thức mạng và nhiều hơn nữa. Về bản chất, một đối tượng là cùng một cấu trúc (kiểu tổng hợp) nhưng được bổ sung các thủ tục và hàm quản lý các thành phần của cấu trúc này. Ví dụ: để làm việc với một tệp bằng ngôn ngữ lập trình thủ tục, một biến sẽ được tạo riêng để lưu tên tệp và riêng để lưu bộ mô tả của nó (một mã định danh tài nguyên duy nhất trong hệ điều hành), cũng như một số quy trình cho thao tác với file: mở file, đọc dữ liệu từ file và đóng file. Tất cả các quy trình này, ngoài các tham số và biến thông thường để lưu trữ kết quả, sẽ được yêu cầu chấp nhận cùng một bộ mô tả để hiểu chúng ta đang nói về tệp nào. Trong ngôn ngữ hướng đối tượng, với cùng mục đích, một đối tượng tệp sẽ được mô tả, đối tượng này cũng sẽ lưu trữ tên và mã điều khiển bên trong chính nó và cung cấp cho người dùng các thủ tục để mở, đọc và đóng chính nó (tệp được liên kết với một địa chỉ cụ thể). sự vật). Sự khác biệt là ở chỗ phần điều khiển sẽ bị ẩn khỏi phần còn lại của chương trình, được tạo trong mã thủ tục mở tệp và chỉ được sử dụng ngầm bởi chính đối tượng đó. Do đó, người dùng đối tượng (mã chương trình của chương trình bên ngoài đối tượng) sẽ không cần chuyển phần điều khiển mỗi lần trong các tham số thủ tục. Một đối tượng là một tập hợp dữ liệu và các phương thức để làm việc với dữ liệu này, một số trong đó có thể bị ẩn khỏi thế giới xung quanh nó, bao gồm cả các chi tiết triển khai. Thuật ngữ lập trình hướng đối tượng sẽ được thảo luận chi tiết hơn dưới đây.

Trong ngôn ngữ lập trình hướng đối tượng, hầu hết mọi thứ đều là đối tượng, ngoại trừ toán tử: kiểu cơ bản là đối tượng, mô tả lỗi là đối tượng và cuối cùng, chương trình chính cũng là đối tượng. Vẫn còn phải hiểu đối tượng là gì theo quan điểm của chính chương trình, nó được tạo và sử dụng như thế nào. Khái niệm cơ bản thứ hai của OOP là lớp. Lớp là một kiểu dữ liệu mới so với lập trình thủ tục, các thể hiện của nó được gọi là đối tượng. Một lớp, như đã đề cập, tương tự như kiểu hoặc cấu trúc dữ liệu tổng hợp, nhưng được bổ sung các thủ tục và hàm (phương thức) để làm việc với dữ liệu của nó. Bây giờ là lúc mô tả các thuật ngữ cơ bản của lập trình hướng đối tượng.

Thuật ngữ lập trình hướng đối tượng

Trước khi chuyển sang mô tả những lợi ích mà OOP mang lại cho các nhà phát triển phần mềm trong quá trình thiết kế, mã hóa và thử nghiệm sản phẩm phần mềm, cần phải làm quen với các thuật ngữ được sử dụng phổ biến nhất trong lĩnh vực này.

  • Lớp học– kiểu dữ liệu mô tả cấu trúc và hành vi của các đối tượng.
  • Một đối tượng– một thể hiện của một lớp
  • Cánh đồng– phần tử dữ liệu lớp: một biến thuộc kiểu, cấu trúc cơ bản hoặc lớp khác là một phần của lớp.
  • Trạng thái đối tượng– một tập hợp các giá trị trường đối tượng hiện tại.
  • Phương pháp– một thủ tục hoặc hàm thực thi trong ngữ cảnh của đối tượng mà nó được gọi. Các phương thức có thể thay đổi trạng thái của đối tượng hiện tại hoặc trạng thái của các đối tượng được truyền cho chúng dưới dạng tham số.
  • Tài sản– một loại phương thức đặc biệt được thiết kế để sửa đổi các trường riêng lẻ của một đối tượng. Tên của thuộc tính thường giống với tên của các trường tương ứng. Nhìn bên ngoài, làm việc với các thuộc tính trông giống hệt như làm việc với các trường của cấu trúc hoặc lớp, nhưng trên thực tế, trước khi trả về hoặc gán giá trị mới cho một trường, mã chương trình có thể được thực thi để thực hiện nhiều loại kiểm tra khác nhau, ví dụ: kiểm tra liệu giá trị mới có hợp lệ hay không.
  • Thành viên lớp– các trường, phương thức và thuộc tính của lớp.
  • Công cụ sửa đổi quyền truy cập– một đặc điểm bổ sung của các thành viên lớp xác định xem chúng có thể truy cập được từ một chương trình bên ngoài hay chúng chỉ được sử dụng trong ranh giới của lớp và ẩn với thế giới bên ngoài. Bộ sửa đổi quyền truy cập tách tất cả các thành viên của một lớp thành các chi tiết triển khai và giao diện công khai hoặc một phần công khai.
  • Người xây dựng– một phương thức đặc biệt được thực thi ngay sau khi tạo một thể hiện của một lớp. Hàm tạo khởi tạo các trường của đối tượng - đưa đối tượng về trạng thái ban đầu. Các nhà xây dựng có thể có hoặc không có tham số. Hàm tạo không có tham số được gọi là hàm tạo mặc định, chỉ có thể có một hàm tạo. Tên của phương thức khởi tạo thường trùng với tên của chính lớp đó.
  • Hàm hủy diệt– một phương thức đặc biệt được gọi bởi môi trường thực thi chương trình tại thời điểm một đối tượng bị xóa khỏi RAM. Hàm hủy được sử dụng trong trường hợp lớp bao gồm các tài nguyên yêu cầu giải phóng rõ ràng (tệp, kết nối cơ sở dữ liệu, kết nối mạng, v.v.)
  • Giao diện– một tập hợp các phương thức và thuộc tính của một đối tượng được cung cấp công khai và được thiết kế để giải quyết một số vấn đề nhất định, ví dụ: giao diện để tạo biểu diễn đồ họa của đối tượng trên màn hình hoặc giao diện để lưu trạng thái của đối tượng trong một tập tin hoặc cơ sở dữ liệu.
  • Thành viên tĩnh– bất kỳ phần tử nào của lớp có thể được sử dụng mà không cần tạo đối tượng tương ứng. Ví dụ: nếu một phương thức lớp không sử dụng một trường duy nhất mà chỉ hoạt động với các tham số được truyền cho nó, thì không có gì ngăn cản việc sử dụng nó trong ngữ cảnh của toàn bộ lớp mà không tạo ra các phiên bản riêng biệt của nó. Các hằng số trong ngữ cảnh của một lớp thường luôn là thành viên tĩnh của lớp.

Lợi ích của lập trình hướng đối tượng

Bây giờ hãy nói về các thuộc tính mà một chương trình có được khi sử dụng cách tiếp cận hướng đối tượng để thiết kế và mã hóa nó. Đối với tôi, có vẻ như hầu hết các thuộc tính này đều là ưu điểm của OOP, nhưng cũng có những ý kiến ​​​​khác về vấn đề này...

  • đóng gói biểu thị việc ẩn các chi tiết triển khai của một lớp bằng cách thưởng cho từng thành viên bằng các công cụ sửa đổi quyền truy cập thích hợp. Do đó, tất cả chức năng của một đối tượng nhằm tương tác với các đối tượng chương trình khác được nhóm thành một giao diện mở và các chi tiết được ẩn cẩn thận bên trong, giúp lưu mã logic nghiệp vụ chính của hệ thống thông tin khỏi những thứ không cần thiết. Việc đóng gói cải thiện độ tin cậy của mã của bạn vì nó đảm bảo rằng một số dữ liệu nhất định không thể bị thay đổi bên ngoài lớp chứa.
  • Di sản. Nền tảng của OOP. Trong lập trình hướng đối tượng, có thể kế thừa cấu trúc và hành vi của một lớp từ một lớp khác. Lớp mà chúng kế thừa được gọi là lớp cơ sở hoặc lớp cha, và lớp thu được do sự kế thừa được gọi là lớp dẫn xuất hoặc đơn giản là lớp con. Bất kỳ lớp nào cũng có thể đóng vai trò vừa là siêu lớp vừa là lớp con. Các mối quan hệ kế thừa lớp tạo thành một hệ thống phân cấp lớp. Đa kế thừa là định nghĩa của một lớp được kế thừa từ nhiều siêu lớp cùng một lúc. Không phải tất cả các ngôn ngữ lập trình hướng đối tượng đều hỗ trợ đa kế thừa. Kế thừa là một cách hiệu quả để tách biệt các đoạn mã có thể tái sử dụng, nhưng nó cũng có những nhược điểm, sẽ được thảo luận sau.
  • Trừu tượng. Khả năng kết hợp các lớp thành các nhóm riêng biệt, làm nổi bật các đặc điểm chung có ý nghĩa quan trọng đối với tất cả chúng (các lĩnh vực chung và hành vi chung). Trên thực tế, sự trừu tượng hóa là hệ quả của sự kế thừa: các lớp cơ sở không phải lúc nào cũng có phép chiếu riêng lên các đối tượng của thế giới thực mà được tạo ra chỉ nhằm mục đích làm nổi bật những đặc điểm chung của cả một nhóm đối tượng. Ví dụ, đồ nội thất là một khái niệm cơ bản cho bàn, ghế và ghế sofa, tất cả chúng đều thống nhất với nhau bởi thực tế là chúng là tài sản di chuyển, một phần nội thất của cơ sở và chúng có thể được làm cho gia đình hoặc văn phòng. , đồng thời đề cập đến “phổ thông” hoặc “cao cấp” ” cho hạng. Trong OOP có một khái niệm riêng cho việc này: lớp trừu tượng - một lớp có các đối tượng bị cấm tạo nhưng có thể được sử dụng làm lớp cơ sở. Tính kế thừa và tính trừu tượng giúp mô tả cấu trúc dữ liệu chương trình và mối quan hệ giữa chúng theo cách giống hệt như các đối tượng tương ứng trong mô hình miền đang được xem xét.

Một ví dụ về sơ đồ lớp được xây dựng bằng cách trừu tượng trong quá trình phân tích các loại phương tiện hiện có được thể hiện trong hình dưới đây. Ở các cấp cao hơn của hệ thống phân cấp kế thừa có các lớp trừu tượng hợp nhất các phương tiện theo những đặc điểm quan trọng nhất.

Sơ đồ lớp hoặc hệ thống phân cấp kế thừa "Phương tiện". Hình vuông màu trắng đại diện cho các lớp trừu tượng.

  • Đa hình. Một tài sản khác là hệ quả của thừa kế. Thực tế là các ngôn ngữ lập trình hướng đối tượng cho phép bạn làm việc với một tập hợp các đối tượng từ cùng một hệ thống phân cấp theo cách giống như thể chúng đều là các đối tượng của lớp cơ sở. Nếu quay lại ví dụ về đồ nội thất, chúng ta có thể giả định rằng trong bối cảnh tạo hệ thống thông tin cho một cửa hàng đồ nội thất, việc thêm một phương pháp “hiển thị đặc điểm” chung vào lớp cơ sở cho tất cả các loại đồ nội thất là hợp lý. Khi in ra đặc điểm của tất cả các loại hàng hóa, chương trình sẽ gọi phương thức này một cách bừa bãi cho tất cả các đối tượng và mỗi đối tượng cụ thể sẽ tự quyết định thông tin nào cần cung cấp cho mình. Cách thực hiện điều này: Đầu tiên, lớp cơ sở định nghĩa một phương thức chung cho tất cả các hành vi chung. Trong trường hợp ví dụ của chúng tôi, đây sẽ là phương pháp in các thông số chung cho tất cả các loại đồ nội thất. Thứ hai, trong mỗi lớp dẫn xuất, khi cần thiết, chúng xác định lại phương thức cơ sở (thêm một phương thức có cùng tên), trong đó chúng mở rộng hành vi cơ bản bằng hành vi của chính chúng, ví dụ, chúng hiển thị các đặc điểm chỉ đặc trưng của một loại cụ thể của sản phẩm nội thất. Một phương thức trong lớp cơ sở đôi khi không cần phải chứa bất kỳ mã nào mà chỉ cần xác định tên và một tập hợp các tham số - chữ ký của phương thức. Các phương thức như vậy được gọi là phương thức trừu tượng và các lớp chứa chúng sẽ tự động trở thành các lớp trừu tượng. Vì vậy, đa hình là khả năng giao tiếp thống nhất với các đối tượng thuộc các lớp khác nhau thông qua một giao diện cụ thể. Hệ tư tưởng đa hình cho rằng để giao tiếp với một đối tượng, bạn không cần phải biết loại của nó mà thay vào đó là giao diện mà nó hỗ trợ.
  • Giao diện. Trong một số ngôn ngữ lập trình (C#, Java), khái niệm giao diện được xác định rõ ràng - nó không chỉ là các phương thức và thuộc tính công khai của chính lớp đó. Các ngôn ngữ như vậy, theo quy tắc, không hỗ trợ đa kế thừa và bù đắp cho điều này bằng cách cho phép bất kỳ đối tượng nào có một đối tượng cơ sở và triển khai bất kỳ số lượng giao diện nào. Theo cách giải thích của họ, một giao diện giống như một lớp trừu tượng chỉ chứa mô tả (chữ ký) của các phương thức và thuộc tính công khai. Việc triển khai một giao diện thuộc về mỗi lớp có ý định hỗ trợ nó. Giao diện tương tự có thể được triển khai bởi các lớp có hệ thống phân cấp hoàn toàn khác nhau, điều này mở rộng khả năng đa hình. Ví dụ: giao diện “lưu/khôi phục thông tin trong cơ sở dữ liệu” có thể được triển khai bởi cả hai lớp của hệ thống phân cấp “nội thất” và các lớp liên quan đến việc đặt hàng sản xuất đồ nội thất và khi bạn nhấp vào nút “lưu”, chương trình sẽ đi qua tất cả các đối tượng, yêu cầu chúng cung cấp giao diện này và gọi phương thức tương ứng.

Lập trình hướng đối tượng không ngừng phát triển, tạo ra các mô hình mới như lập trình hướng khía cạnh, hướng chủ thể và thậm chí hướng tác nhân. Cần lưu ý rằng vinh quang của OOP đã ám ảnh các nhà lý thuyết khác và họ vội vàng đưa ra các lựa chọn của riêng mình để cải thiện và mở rộng nó. Lập trình nguyên mẫu loại bỏ khái niệm về một lớp, thay thế nó bằng một nguyên mẫu - một ví dụ về một đối tượng. Do đó, trong ngôn ngữ hướng nguyên mẫu không có khái niệm về loại đối tượng mà có khái niệm về mẫu hoặc nguyên mẫu. Nguyên mẫu là một thể hiện của một đối tượng mà từ đó các thể hiện khác được tạo ra bằng cách sao chép (nhân bản) các thành viên của nó. Trong JavaScript, bạn không mô tả các trường và phương thức của một lớp mà trước tiên hãy tạo một đối tượng trống, sau đó thêm các trường và phương thức cần thiết vào đó (trong JavaScript, một phương thức có thể được xác định và thêm vào một đối tượng một cách linh hoạt). Theo cách tương tự, các nguyên mẫu được tạo ra, sau đó được các đối tượng khác gọi là nguyên mẫu của chúng. Nếu một đối tượng không có phương thức hoặc trường nào đó được chỉ định trong vị trí cuộc gọi thì nó sẽ được tìm kiếm trong số các thành viên nguyên mẫu của nó.

Một số thành phần của lập trình hướng đối tượng hiện đại

Thời gian không đứng yên và đã khá nhiều thời gian trôi qua kể từ khi OOP ra đời, vì vậy không có gì đáng ngạc nhiên khi ngày nay vốn từ vựng về lập trình hướng đối tượng đã phát triển đáng kể. Vì vậy, đây là một số thuật ngữ và khái niệm mới liên quan đến OOP.

  • Sự kiện. Một loại đối tượng đặc biệt được tạo ra để thông báo cho một số đối tượng về các sự kiện xảy ra với các đối tượng khác. Trong các ngôn ngữ lập trình khác nhau, cơ chế sự kiện được triển khai theo nhiều cách khác nhau: đôi khi sử dụng các cấu trúc cú pháp đặc biệt và đôi khi sử dụng các công cụ OOP cơ bản.
  • Loại phổ quát. Khái niệm generic type không liên quan trực tiếp đến khái niệm OOP nhưng nó là nguyên nhân xuất hiện các phần tử như generic class, generic phương thức, generic sự kiện, v.v. Loại chung là loại được tham số hóa bởi loại khác (tập hợp các loại). Loại tham số này là gì trong bối cảnh thiết kế kiểu chung vẫn chưa được xác định, mặc dù có thể hạn chế giá trị của các loại tham số bằng cách buộc chúng xuất phát từ một lớp cụ thể hoặc triển khai các giao diện nhất định. Một ví dụ là một lớp phổ quát để sắp xếp một chuỗi các phần tử, trong đó loại phần tử trong chuỗi không được biết trước. Khi thiết kế một lớp như vậy, điều quan trọng là phải xác định rằng loại tham số phải hỗ trợ thao tác so sánh. Khi tạo các đối tượng thuộc loại chung, bạn chỉ định rõ ràng một tham số, chẳng hạn như số nguyên hoặc loại chuỗi và bản thân đối tượng bắt đầu hoạt động như thể nó là một thể hiện của một lớp được tạo riêng để sắp xếp số nguyên hoặc chuỗi.
  • Ngoại lệ. Một loại đối tượng đặc biệt khác được hỗ trợ bởi cơ chế xử lý lỗi và ngoại lệ được tích hợp trong một ngôn ngữ lập trình cụ thể. Các ngoại lệ, ngoài mã lỗi, còn chứa mô tả của nó, các nguyên nhân có thể xảy ra và một loạt lệnh gọi phương thức xảy ra trước khi ngoại lệ xảy ra trong chương trình.

Nhược điểm của lập trình hướng đối tượng

Tôi đã nói rằng mức độ phổ biến của cách tiếp cận hướng đối tượng để tạo ra các sản phẩm phần mềm là rất lớn. Tôi cũng đã lưu ý rằng có khá nhiều người tìm cách mở rộng mô hình này. Nhưng có một cách khác để nổi bật giữa cộng đồng khổng lồ các chuyên gia về công nghệ thông tin - đó là tuyên bố rằng OOP đã không tự biện minh rằng nó không phải là thuốc chữa bách bệnh mà là giả dược. Trong số những người này có những chuyên gia thực sự rất cao cấp, chẳng hạn như Christopher Date, Alexander Stepanov, Edsger Dijkstra và những người khác, và ý kiến ​​của họ đáng được quan tâm, nhưng cũng có những người mà họ nói rằng “có điều gì đó luôn cản trở một vũ công tồi.” Đây là những nhược điểm rõ ràng nhất của OOP, được các chuyên gia chỉ ra:

1. OOP tạo ra hệ thống phân cấp lớp khổng lồ, dẫn đến thực tế là chức năng bị dàn trải hoặc, như người ta nói, bị mờ giữa các thành viên cơ sở và dẫn xuất của lớp, và việc theo dõi logic hoạt động của một lớp cụ thể trở nên khó khăn phương pháp.

2. Trong một số ngôn ngữ, tất cả dữ liệu đều là đối tượng, bao gồm cả các loại cơ bản và điều này không thể không dẫn đến việc tiêu tốn thêm bộ nhớ và thời gian CPU.

3. Ngoài ra, tốc độ thực hiện chương trình có thể bị ảnh hưởng bất lợi bởi việc triển khai tính đa hình, dựa trên các cơ chế ràng buộc muộn của lệnh gọi phương thức với việc triển khai cụ thể của nó trong một trong các lớp dẫn xuất.

4. Khía cạnh tâm lý. Nhiều người nghĩ rằng OOP rất tuyệt và bắt đầu sử dụng các cách tiếp cận của nó mọi lúc, mọi nơi và một cách bừa bãi. Tất cả điều này dẫn đến việc giảm hiệu suất chương trình nói riêng và làm mất uy tín của OOP nói chung.