1. Tại sao cần OOP?
Giả sử rằng bạn muốn lắp ráp máy tính của riêng bạn, bạn đi đến một cửa hàng phần cứng và chọn lên một bo mạch chủ, bộ xử lý, một số RAM, ổ đĩa cứng, một vỏ bọc, một nguồn cung cấp năng lượng, và đặt chúng lại với nhau. Bạn bật điện, và các máy tính chạy. Bạn không cần phải lo lắng cho dù CPU là 1-core hoặc 6 lõi; bo mạch chủ là một 4-layer hay 6 lớp; các đĩa cứng có 4 tấm, 6 tấm, 3 inch hoặc 5 inch đường kính; RAM được thực hiện tại Nhật Bản hay Hàn Quốc, và như vậy. Bạn chỉ cần đặt hardwarecomponents với nhau và mong đợi máy để chạy. Tất nhiên, bạn phải chắc chắn rằng bạn có giao diện chính xác, ví dụ, bạn chọn một đĩa cứng IDE hơn là một đĩa cứng SCSI, nếu bo mạch chủ của bạn chỉ hỗ trợ IDE; bạn phải chọn RAMS với đánh giá tốc độ chính xác, và như vậy. Tuy nhiên, nó không phải là khó khăn để thiết lập một máy từ các thành phần phần cứng.
Tương tự như vậy, một chiếc xe được lắp ráp từ các bộ phận và linh kiện, chẳng hạn như khung xe, cửa ra vào, động cơ, bánh xe, phanh và truyền tải. Các thành phần có thể tái sử dụng, ví dụ, một bánh xe có thể được sử dụng trong rất nhiều xe ô tô (các thông số kỹ thuật tương tự).
Phần cứng, chẳng hạn như máy tính và xe hơi, được lắp ráp từ các bộ phận, đó là những thành phần tái sử dụng.
Làm thế nào về phần mềm? Bạn có thể “lắp ráp” một ứng dụng phần mềm bằng cách chọn một thói quen ở đây, một thói quen ở đó, và mong muốn các chương trình để chạy? Câu trả lời rõ ràng là không! Không giống như phần cứng, nó là rất khó khăn để “lắp ráp” một ứng dụng từ các thành phần phần mềm. Kể từ sự ra đời của máy tính 70 năm trước đây, chúng tôi đã viết tấn và tấn của các chương trình. Tuy nhiên, đối với mỗi ứng dụng mới, chúng ta phải tái phát minh ra bánh xe và ghi các chương trình từ đầu.
Tại sao lại phát minh ra bánh xe? Tại sao viết lại mã?
Lập trình hướng đối tượng trong java
Ngôn ngữ thủ tục hướng truyền thống
Ngôn ngữ lập trình thủ tục theo định hướng truyền thống (chẳng hạn như C, Fortran, Cobol và Pascal) bị một số nhược điểm đáng chú ý trong việc tạo ra các thành phần phần mềm tái sử dụng:
1. Các chương trình thủ tục định hướng được tạo thành từ các chức năng. Chức năng ít sử dụng lại. Nó là rất khó khăn để sao chép một chức năng từ một chương trình và dùng lại trong các chương trình khác vì các chức năng có thể tham khảo các biến toàn cầu và các chức năng khác. Nói cách khác, chức năng này không được đóng gói như một đơn vị tái sử dụng khép kín.
2. Các ngôn ngữ thủ tục không phù hợp của các cấp cao trừu tượng để giải quyết các vấn đề thực tế cuộc sống. Ví dụ, chương trình C sử dụng các cấu trúc như if-else, cho-loop, mảng, phương pháp, con trỏ, đó là mức độ thấp và khó khăn cho các vấn đề thực trừu tượng như một Relationship Management (CRM) hệ thống hoặc một trò chơi bóng đá máy tính khách hàng.
2. Các ngôn ngữ thủ tục không phù hợp của các cấp cao trừu tượng để giải quyết các vấn đề thực tế cuộc sống. Ví dụ, chương trình C sử dụng các cấu trúc như if-else, cho-loop, mảng, phương pháp, con trỏ, đó là mức độ thấp và khó khăn cho các vấn đề thực trừu tượng như một Relationship Management (CRM) hệ thống hoặc một trò chơi bóng đá máy tính khách hàng.
Nói tóm lại, các thủ tục, ngôn ngữ truyền thống tách các cấu trúc dữ liệu và thuật toán của các thực thể phần mềm.
Trong năm 1970, Bộ Quốc phòng Mỹ (DoD) đưa một lực lượng đặc nhiệm để điều tra tại sao ngân sách IT của nó luôn luôn đi ra ngoài tầm kiểm soát; nhưng không có nhiều người thực hiện. Các phát hiện này là:
1. 80% ngân sách đã đi đến phần mềm (với 20% còn lại đến phần cứng).
2. Hơn 80% ngân sách phần mềm đi để bảo trì (chỉ có 20% còn lại cho phát triển phần mềm mới).
3. Các thành phần phần cứng có thể được áp dụng cho các sản phẩm khác nhau, và tính toàn vẹn của họ thường không ảnh hưởng đến các sản phẩm khác. (Phần cứng có thể chia sẻ và sử dụng lại! Lỗi phần cứng đang bị cô lập!)
4. Thủ tục phần mềm thường không thể chia sẻ và không thể tái sử dụng. Lỗi phần mềm có thể ảnh hưởng đến các chương trình khác đang chạy trong máy tính.
2. Hơn 80% ngân sách phần mềm đi để bảo trì (chỉ có 20% còn lại cho phát triển phần mềm mới).
3. Các thành phần phần cứng có thể được áp dụng cho các sản phẩm khác nhau, và tính toàn vẹn của họ thường không ảnh hưởng đến các sản phẩm khác. (Phần cứng có thể chia sẻ và sử dụng lại! Lỗi phần cứng đang bị cô lập!)
4. Thủ tục phần mềm thường không thể chia sẻ và không thể tái sử dụng. Lỗi phần mềm có thể ảnh hưởng đến các chương trình khác đang chạy trong máy tính.
Các lực lượng đặc nhiệm đề xuất để làm cho phần mềm trở nên giống OBJECT phần cứng. Sau đó, Bộ Quốc phòng thay thế hơn 450 ngôn ngữ máy tính, sau đó được sử dụng để xây dựng các hệ thống DoD, với một ngôn ngữ hướng đối tượng được gọi là Ada.
Lập trình hướng đối tượng với java
Lập trình hướng đối tượng (OOP) Các ngôn ngữ được thiết kế để khắc phục những vấn đề này.
- Các đơn vị cơ bản của OOP là một lớp, và tóm cả các thuộc tính tĩnh và hoạt động năng động trong một “hộp”, và xác định các giao diện nào để sử dụng các hộp. Kể từ khi các lớp học đều được đóng gói, nó là dễ dàng hơn để sử dụng lại các lớp học. Nói cách khác, OOP kết hợp các cấu trúc dữ liệu và thuật toán của một phần mềm thực thể bên trong cùng một hộp.
- OOP ngôn ngữ cho phép mức độ trừu tượng cao hơn để giải quyết các vấn đề thực tế cuộc sống. Các ngôn ngữ thủ tục truyền thống (chẳng hạn như C và Pascal) buộc bạn phải suy nghĩ về cấu trúc của máy tính (ví dụ như bộ nhớ bit và byte, mảng, quyết định, vòng lặp) hơn là suy nghĩ về những vấn đề bạn đang cố gắng để giải quyết. Những ngôn ngữ OOP (như Java, C ++ và C #) cho bạn nghĩ rằng trong không gian vấn đề, và sử dụng các đối tượng phần mềm để đại diện và thực thể trừu tượng của không gian vấn đề để giải quyết vấn đề.
Như một ví dụ, giả sử bạn muốn viết một trò chơi bóng đá máy tính (mà tôi coi như một ứng dụng phức tạp). Nó là khá khó khăn để mô hình các trò chơi trong ngôn ngữ thủ tục theo định hướng. Nhưng sử dụng OOP ngôn ngữ, bạn có thể dễ dàng mô hình chương trình cho phù hợp với “những điều thực sự” xuất hiện trong trò chơi bóng đá.
- Player: thuộc tính bao gồm tên, số lượng, vị trí trong lĩnh vực, và vv; hoạt động bao gồm chạy, nhảy, đá-the-ball, và vv
- Ball:
- Reference:
- Field:
- Audience:
- Weather:
Quan trọng nhất, một số trong các lớp này (chẳng hạn như bóng và khán giả) có thể được tái sử dụng trong một ứng dụng khác, ví dụ như, trò chơi bóng rổ máy tính, với rất ít hoặc không sửa đổi.
Hiệu quả của OOP
Các ngôn ngữ thủ tục định hướng tập trung vào các thủ tục, với chức năng là đơn vị cơ bản. Bạn cần phải đầu tiên tìm ra tất cả các chức năng và sau đó suy nghĩ về làm thế nào để đại diện cho dữ liệu.
Các ngôn ngữ hướng đối tượng tập trung vào các thành phần mà người sử dụng nhận thấy, với các đối tượng là đơn vị cơ bản. Bạn tìm ra tất cả các đối tượng bằng cách đặt tất cả các dữ liệu và các hoạt động mô tả sự tương tác của người dùng với các dữ liệu.
Công nghệ hướng đối tượng có nhiều lợi ích:
- Dễ dàng trong thiết kế phần mềm như bạn có thể nghĩ rằng trong không gian vấn đề chứ không phải là bit của máy và byte. Bạn đang đối phó với những khái niệm cao cấp và trừu tượng. Dễ trong thiết kế dẫn đến phát triển phần mềm hiệu quả hơn.
- Ease in software maintenance: hướng đối tượng phần mềm là dễ hiểu, do đó dễ dàng hơn để kiểm tra, gỡ lỗi, và duy trì.
- Reusable software: bạn không cần phải tiếp tục tái phát minh ra bánh xe và viết lại các chức năng tương tự cho các tình huống khác nhau. Cách nhanh nhất và an toàn nhất của việc phát triển một ứng dụng mới là sử dụng lại mã số hiện có – mã số kiểm tra đầy đủ và đã được chứng minh.
2. OOP in Java
2.1 Class & Instances
Trong Java, một lớp là một định nghĩa của các đối tượng cùng loại. Nói cách khác, một lớp học là một kế hoạch chi tiết, mẫu, hoặc một nguyên mẫu mà xác định và mô tả các thuộc tính tĩnh và hành vi động chung cho tất cả các đối tượng cùng loại.
Một ví dụ là một hiện thực của một mặt hàng cụ thể của một lớp. Nói cách khác, một thể hiện là một instantiation của một lớp. Tất cả các trường hợp của một lớp học có tính chất tương tự, như được mô tả trong định nghĩa lớp. Ví dụ, bạn có thể định nghĩa một lớp được gọi là “sinh viên” và tạo ra ba trường hợp của lớp “Sinh viên” cho “Peter”, “Paul” và “Pauline”.
Thuật ngữ “đối tượng” thường đề cập đến trường hợp. Nhưng nó thường được sử dụng một cách lỏng lẻo, có thể tham khảo một lớp hoặc một ví dụ.
2.2 A Class is a 3-Compartment Box encapsulating Data and Operations
Một lớp có thể được hình dung như một hộp ba khoang, như minh họa:
- Name (or identity): xác định các lớp.
- Variables (or attribute, state, field):chứa các thuộc tính tĩnh của lớp.
- Methods (or behaviors, function, operation): chứa các hành vi năng động của lớp.
Nói cách khác, một lớp đóng gói các thuộc tính tĩnh (dữ liệu) và hành vi động (hoạt động hoạt động trên dữ liệu) trong một hộp.
Các con số sau đây cho thấy một vài ví dụ về các lớp học:
Hình dưới đây cho thấy hai trường hợp của học sinh lớp, được xác định là “paul” và “peter”.
Unified Modeling Language (UML) Class và Instance Diagrams: Các sơ đồ lớp trên được rút ra theo các ký hiệu UML. Một lớp được biểu diễn như một hộp 3 ngăn, có chứa tên, các biến và phương pháp tương ứng. Tên lớp được in đậm và tập trung. Một ví dụ (đối tượng) cũng được biểu diễn như một hộp 3 ngăn, với tên dụ thể hiện asinstanceName: className và gạch chân.
Tóm tắt
- Một lớp là một lập trình viên xác định, trừu tượng, khép kín, tái sử dụng thực thể phần mềm bắt chước một điều thực tế.
- Một lớp là một hộp 3 ngăn chứa tên, các biến và các phương pháp.
- Một lớp đóng gói các cấu trúc dữ liệu (trong các biến) và thuật toán (phương pháp). Các giá trị của các biến tạo thành trạng thái của nó. Các phương pháp cấu thành hành vi của mình.
- Một ví dụ là một instantiation (hoặc thực hiện) của một mặt hàng cụ thể của một lớp.
2.3 Class Definition
Trong Java, chúng ta sử dụng từ khoá class định nghĩa một lớp. Cho ví dụ:
public class Circle { // class name
double radius; // variables
String color;
double getRadius() {...} // methods
double getArea() {...}
}
public class SoccerPlayer { // class name
int number; // variables
String name;
int x, y;
void run() {...} // methods
void kickBall() {...}
}
Cú pháp để định nghĩa lớp trong Java là:
[AccessControlModifier] class ClassName {
// class body contains definition of variables and methods
...
}
Chúng tôi sẽ giải thích sự sửa đổi điều khiển truy cập, chẳng hạn như công cộng và tư nhân, sau đó.
Quy ước đặt tên lớp: Một tên lớp phải là một danh từ hoặc một cụm danh từ tạo thành một vài từ. Tất cả các từ được ban đầu có vốn (camel-case). Sử dụng một danh từ số ít cho tên lớp. Chọn một classname ý nghĩa và tự mô tả. Đối với ví dụ, SoccerPlayer, HttpProxyServer, FileInputStream, PrintStream và SocketFactory.
2.4 Creating Instances of a Class
Để tạo ra một thể hiện của một lớp, bạn phải:
Khai báo một định danh dụ (ví dụ tên) của một lớp học đặc biệt.
Xây dựng các ví dụ (ví dụ, phân bổ lưu trữ cho các ví dụ và khởi tạo instance) bằng cách sử dụng toán tử “mới”.
Đối với ví dụ, giả sử rằng chúng ta có một lớp được gọi là Circle, chúng ta có thể tạo ra các trường hợp của các mối như sau:
Xây dựng các ví dụ (ví dụ, phân bổ lưu trữ cho các ví dụ và khởi tạo instance) bằng cách sử dụng toán tử “mới”.
Đối với ví dụ, giả sử rằng chúng ta có một lớp được gọi là Circle, chúng ta có thể tạo ra các trường hợp của các mối như sau:
// Declare 3 instances of the class Circle, c1, c2, and c3
Circle c1, c2, c3;
// Allocate and construct the instances via new operator
c1 = new Circle();
c2 = new Circle(2.0);
c3 = new Circle(3.0, "red");
// You can declare and construct in the same statement
Circle c4 = new Circle();
2.5 Dot Operator
Các biến và phương pháp thuộc về một lớp học được chính thức gọi là biến thành viên và phương pháp thành viên. Để tham khảo một biến thành viên hay phương pháp, bạn phải:
đầu tiên xác định các trường hợp bạn quan tâm, và sau đó
Sử dụng dấu chấm (.) Để tham khảo các thành viên (biến hay phương thức).
Ví dụ, giả sử rằng chúng ta có một lớp được gọi là Circle, với hai biến (bán kính và màu sắc) và hai phương thức (getRadius () và getArea ()). Chúng tôi đã tạo ra ba trường hợp của lớp Circle, cụ thể là, c1, c2 và c3. Để gọi các phương pháp getArea (), bạn phải nhận diện đầu tiên thể hiện sự quan tâm, nói c2, sau đó sử dụng các dấu chấm, dưới hình thức của c2.getArea (), để gọi getArea () phương pháp dụ c2.
Sử dụng dấu chấm (.) Để tham khảo các thành viên (biến hay phương thức).
Ví dụ, giả sử rằng chúng ta có một lớp được gọi là Circle, với hai biến (bán kính và màu sắc) và hai phương thức (getRadius () và getArea ()). Chúng tôi đã tạo ra ba trường hợp của lớp Circle, cụ thể là, c1, c2 và c3. Để gọi các phương pháp getArea (), bạn phải nhận diện đầu tiên thể hiện sự quan tâm, nói c2, sau đó sử dụng các dấu chấm, dưới hình thức của c2.getArea (), để gọi getArea () phương pháp dụ c2.
Ví dụ,
// Declare and construct instances c1 and c2 of the class Circle
Circle c1 = new Circle ();
Circle c2 = new Circle ();
// Invoke member methods for the instance c1 via dot operator
System.out.println(c1.getArea());
System.out.println(c1.getRadius());
// Reference member variables for instance c2 via dot operator
c2.radius = 5.0;
c2.color = "blue";
Gọi getArea () mà không xác định các trường hợp là vô nghĩa, như bán kính là không rõ (có thể có nhiều trường hợp của Circle – từng duy trì bán kính của riêng mình).
Nói chung, giả sử có một lớp được gọi là Aclass với một biến thành viên được gọi là aVariable và một phương pháp gọi là thành viên aMethod (). Một ví dụ được gọi là anInstance được xây dựng cho Aclass. Bạn useanInstance.aVariable và anInstance.aMethod ().
2.6 Member Variables
Một biến thành viên có một cái tên (hoặc định danh) và một loại; và giữ một giá trị của loại hình cụ thể (như descried trong chương trước đó). Một biến thành viên cũng có thể là một thể hiện của một lớp nào đó (sẽ được thảo luận sau).
Quy ước đặt tên biến: Một tên biến phải là một danh từ hoặc một cụm danh từ tạo thành một vài từ. Từ đầu tiên là chữ thường và phần còn lại của từ này là ban đầu có vốn (camel-case), ví dụ như, fontSize, roomNumber, Xmax, ymin và xTopLeft. Hãy lưu ý rằng tên biến bắt đầu bằng một chữ thường, trong khi tên lớp học bắt đầu với một chữ hoa.
Cú pháp chính thức để định nghĩa biến trong Java là:
[AccessControlModifier] type variableName [= initialValue];
[AccessControlModifier] type variableName-1 [= initialValue-1] [, type variableName-2 [= initialValue-2]] ... ;
For example,
private double radius;
public int length = 1, width = 1;
2.7 Member Methods
Một phương pháp (như mô tả trong các chương trước):
nhận được các thông số từ người gọi,
thực hiện các hoạt động được xác định trong cơ thể phương pháp, và
trả lại một phần của kết quả (hoặc void) để người gọi.
Cú pháp để khai báo phương thức trong Java là như sau:
thực hiện các hoạt động được xác định trong cơ thể phương pháp, và
trả lại một phần của kết quả (hoặc void) để người gọi.
Cú pháp để khai báo phương thức trong Java là như sau:
[AccessControlModifier] returnType methodName ([argumentList]) {
// method body or implementation
......
}
Cho ví dụ:
public double getArea() {
return radius*radius*Math.PI;
}
Quy ước đặt tên phương pháp: Một phương pháp hiệu sẽ là một động từ, hoặc một cụm động từ gồm nhiều từ. Từ đầu tiên là chữ thường và phần còn lại của từ này là ban đầu có vốn (camel-case). Ví dụ, getRadius (), getParameterValues ().
Hãy lưu ý rằng tên biến là một danh từ (biểu thị một thuộc tính tĩnh), trong khi tên phương pháp là một động từ (thể hiện một hành động). Họ có quy ước đặt tên. Tuy nhiên, bạn có thể dễ dàng phân biệt chúng với các ngữ cảnh. Phương pháp lấy đối số trong ngoặc đơn (có thể không tranh cãi với dấu ngoặc rỗng), nhưng các biến không. Trong văn bản này, các phương pháp được biểu thị bằng một cặp dấu ngoặc đơn, ví dụ như, println (), getArea () cho rõ ràng.
2.8 Đưa chúng với nhau: Một OOP Ví dụ
Một lớp được gọi là Circle là để được định nghĩa như được minh họa trong sơ đồ lớp. Nó bao gồm hai yếu tố: bán kính (kiểu double) và màu sắc (kiểu String); và ba phương pháp: getRadius (), getColor (), và getArea ().
Ba trường hợp của Circles gọi là c1, c2, c3 và sau đó sẽ được xây dựng với các thành viên dữ liệu của mình, như thể hiện trong sơ đồ ví dụ.
Các mã nguồn cho Circle.java là như sau:
Circle.java
1 | // Define the Circle class |
Compile “
Circle.java
” into “Circle.class
“.Chú ý rằng lớp mối không có một phương pháp chính (). Do đó, nó là không một chương trình độc lập và bạn không thể chạy các lớp mối của chính nó. Lớp Circle có nghĩa là một khối xây dựng và sử dụng trong các chương trình khác.
TestCircle.java
Bây giờ chúng ta sẽ viết một lớp được gọi TestCircle, trong đó sử dụng các lớp Circle. Lớp TestCircle có một phương thức main () và có thể được thực hiện.
1 | // Test driver program for the Circle class |
Compile
TestCircle.java
into TestCircle.class
.Run the
TestCircle
and study the output:Radius is 2.0 Color is blue Area is 12.566370614359172
Radius is 2.0 Color is red Area is 12.566370614359172
Radius is 1.0 Color is red Area is 3.141592653589793
2.9 Constructors
Một constructor là một phương pháp đặc biệt có tên cùng một phương pháp như tên lớp. Trong lớp các mối ở trên, chúng ta định nghĩa ba phiên bản quá tải của nhà xây dựng “Circle (….)”. Một nhà xây dựng được sử dụng toconstruct và khởi tạo tất cả các biến thành viên. Để tạo ra một thể hiện mới của một lớp, bạn cần phải sử dụng một nhà điều hành “mới” đặc biệt tiếp theo là một cuộc gọi đến một trong những nhà xây dựng. Ví dụ,
Circle c1 = new Circle();
Circle c2 = new Circle(2.0);
Circle c3 = new Circle(3.0, "red");
Một nhà xây dựng là khác nhau từ một phương pháp thông thường ở các khía cạnh sau:
Tên của phương thức khởi tạo là giống như tên lớp, và theo quy ước className, bắt đầu bằng một chữ hoa.
Constructor không có kiểu trả về (hoặc ngầm trả về void). Do đó, không có tuyên bố trả lại được phép vào bên trong cơ thể của constructor.
Constructor chỉ có thể hiện thông qua các nhà điều hành “mới”. Nó chỉ có thể được sử dụng một lần để khởi tạo các ví dụ xây dựng. Bạn không thể gọi các constructor sau đó.
Các nhà xây dựng không được thừa kế (sẽ được giải thích sau).
Một constructor không có tham số được gọi là constructor mặc định, khởi tạo các biến thành viên với giá trị mặc định của chúng. Ví dụ, các Circle () trong ví dụ trên.
Constructor không có kiểu trả về (hoặc ngầm trả về void). Do đó, không có tuyên bố trả lại được phép vào bên trong cơ thể của constructor.
Constructor chỉ có thể hiện thông qua các nhà điều hành “mới”. Nó chỉ có thể được sử dụng một lần để khởi tạo các ví dụ xây dựng. Bạn không thể gọi các constructor sau đó.
Các nhà xây dựng không được thừa kế (sẽ được giải thích sau).
Một constructor không có tham số được gọi là constructor mặc định, khởi tạo các biến thành viên với giá trị mặc định của chúng. Ví dụ, các Circle () trong ví dụ trên.
2.10 Method Overloading
Phương pháp quá tải có nghĩa là tên cùng một phương pháp có thể có hiện thực khác nhau (các phiên bản). Tuy nhiên, việc triển khai khác nhau phải được phân biệt bởi danh sách đối số của họ (hoặc số lượng các đối số, hoặc các loại của các đối số, hoặc đặt hàng của họ).
Ví dụ: Các phương pháp bình quân () có 3 phiên bản, với danh sách đối số khác nhau. Người gọi có thể gọi các phiên bản được lựa chọn bằng cách cung cấp các luận cứ hợp.
1 | // Example to illustrate Method Overloading |
Overloading Circle Class’ Constructor
The above
Circle
class has three versions of constructors differentiated by their parameter list, as followed:Circle()
Circle(double r)
Circle(double r, String c)
Tùy thuộc vào các danh sách đối số thực tế sử dụng khi gọi phương pháp này, các nhà xây dựng phù hợp sẽ được gọi. Nếu danh sách đối số của bạn không phù hợp với bất kỳ một trong những phương pháp, bạn sẽ nhận được một lỗi biên dịch.
2.11 public vs. private – Access Control Modifiers
Một trình sửa đổi điều khiển truy cập có thể được sử dụng để kiểm soát tầm nhìn của một lớp, hoặc một biến thành viên hoặc một phương thức thành viên trong một lớp. Chúng tôi bắt đầu với hai bổ khiển truy cập sau đây:
công cộng: Lớp / biến / phương pháp tiếp cận được và có sẵn cho tất cả các đối tượng khác trong hệ thống.
tin: Các lớp học / biến / phương pháp tiếp cận và sẵn chỉ trong lớp học này.
Ví dụ, trong định nghĩa các mối trên, các thành viên bán kính biến được khai báo là private. Kết quả là, bán kính là ở bên trong lớp Circle, nhưng không bên trong lớp TestCircle. Nói cách khác, bạn không thể sử dụng “c1.radius” để chỉ bán kính c1 trong TestCircle. Hãy thử chèn các tuyên bố “System.out.println (c1.radius);” trong TestCircle và quan sát các thông báo lỗi. Hãy thử changingradius cho công chúng, và chạy lại các tuyên bố.
tin: Các lớp học / biến / phương pháp tiếp cận và sẵn chỉ trong lớp học này.
Ví dụ, trong định nghĩa các mối trên, các thành viên bán kính biến được khai báo là private. Kết quả là, bán kính là ở bên trong lớp Circle, nhưng không bên trong lớp TestCircle. Nói cách khác, bạn không thể sử dụng “c1.radius” để chỉ bán kính c1 trong TestCircle. Hãy thử chèn các tuyên bố “System.out.println (c1.radius);” trong TestCircle và quan sát các thông báo lỗi. Hãy thử changingradius cho công chúng, và chạy lại các tuyên bố.
Mặt khác, các phương pháp getRadius () được khai báo nào trong lớp Circle. Do đó, nó có thể được áp dụng trong lớp TestCircle.
UML Notation: Trong UML ký hiệu, thành viên công cộng được thể hiện bằng một “+”, trong khi các thành viên riêng với một “-” trong sơ đồ lớp.
More bổ kiểm soát truy cập sẽ được thảo luận sau.
2.12 Ẩn thông tin và Encapsulation
Một lớp học gói gọn tên, thuộc tính tĩnh và hành vi động thành một “hộp 3 ngăn”. Khi một lớp được định nghĩa, bạn có thể đóng dấu lên các “hộp” và đặt “hộp” trên xiên cho người khác sử dụng và tái sử dụng. Bất cứ ai cũng có thể nhận các “hộp” và sử dụng nó trong ứng dụng của họ. Điều này không thể được thực hiện trong các ngôn ngữ thủ tục định hướng truyền thống như C, như các thuộc tính tĩnh (hoặc các biến) nằm rải rác trên toàn bộ chương trình và các tập tin tiêu đề. Bạn không thể “cắt” ra một phần của chương trình C, cắm vào một chương trình khác, và mong muốn các chương trình để chạy mà không cần thay đổi sâu rộng.
Biến thành viên của một lớp học thường được giấu kín từ bên ngoài (ví dụ, các lớp khác), với sửa đổi điều khiển truy cập tin. Truy cập vào các biến thành viên được cung cấp thông qua các phương pháp giám định viên công cộng, ví dụ như, getRadius () và getColor ().
Điều này theo nguyên tắc ẩn thông tin. Đó là, đối tượng giao tiếp với nhau bằng cách sử dụng giao diện cũng được xác định (phương pháp công cộng). Đối tượng không được phép để biết chi tiết thực hiện của người khác. Các chi tiết thực hiện được ẩn hoặc đóng gói trong lớp. Ẩn thông tin tạo điều kiện tái sử dụng của lớp.
Rule of Thumb: Không thực hiện bất kỳ công biến, trừ khi bạn có một lý do chính đáng.
2.13 Getters and Setters
Để cho phép các lớp khác để đọc các giá trị của một biến tư nhân nói xxx, bạn phải cung cấp một phương thức get (hoặc getter hoặc phương pháp accessor) gọi getXxx (). Một phương pháp get không cần phải tiếp xúc với các dữ liệu ở dạng thô. Nó có thể xử lý dữ liệu và hạn chế về dữ liệu người khác sẽ thấy. có được phương pháp này không thể sửa đổi các biến.
Để cho phép các lớp khác để sửa đổi các giá trị của một biến tư nhân nói xxx, bạn phải cung cấp một phương thức thiết lập (hoặc setter hoặc phương pháp mutator) gọi setXxx (). Một phương thức thiết lập có thể cung cấp dữ liệu xác nhận (chẳng hạn như phạm vi kiểm tra), và chuyển đổi dữ liệu thô thành các đại diện nội.
Ví dụ, trong lớp các mối của chúng tôi, các biến và bán kính màu được khai báo là private. Đó là để nói, họ chỉ có sẵn trong lớp Circle và không thể nhìn thấy trong bất kỳ lớp khác – lớp includingTestCircle. Bạn không thể truy cập các biến radius và màu sắc riêng từ lớp TestCircle trực tiếp – thông qua nói c1.radius hoặc c1.color. Lớp mối cung cấp hai phương pháp accessor công cộng, cụ thể là, getRadius () và getColor (). Những phương pháp này được tuyên bố công khai. Lớp TestCircle có thể gọi các phương pháp accessor công cộng để lấy bán kính và màu sắc của một đối tượng Circle, qua nói c1.getRadius () và c1.getColor ().
Không có cách nào bạn có thể thay đổi bán kính hoặc màu sắc của một đối tượng Circle, sau khi nó được xây dựng trong lớp TestCircle. Bạn không thể phát hành báo cáo như c1.radius = 5.0 để thay đổi bán kính của dụ c1, như bán kính được khai báo là tin trong lớp Circle và không nhìn thấy được đến các lớp học khác bao gồm TestCircle.
Nếu các nhà thiết kế của lớp mối cho phép thay đổi bán kính và màu sắc sau khi một đối tượng Circle xây dựng, ông có để cung cấp các phương pháp thích hợp tập (hoặc máy tạo hoặc các phương pháp mutator), ví dụ:
// Setter for color
public void setColor(String c) {
color = c;
}
// Setter for radius
public void setRadius(double r) {
radius = r;
}
Với việc thực hiện đúng các ẩn thông tin, các nhà thiết kế của một lớp có toàn quyền kiểm soát những gì người dùng của lớp có thể và không thể làm được.
2.14 Từ khóa”this“
Bạn có thể sử dụng từ khoá “này” để chỉ trường hợp này bên trong một định nghĩa lớp.
Một trong những cách sử dụng chính của từ khóa này là để giải quyết sự mơ hồ.
public class Circle {
double radius; // Member variable called "radius"
public Circle(double radius) { // Method's argument also called "radius"
this.radius = radius;
// "this.radius" refers to this instance's member variable
// "radius" resolved to the method's argument.
}
...
}
Trong các mã trên, có hai định danh được gọi là bán kính – một biến thành viên của lớp học và lý luận của phương pháp. Điều này gây ra xung đột đặt tên. Để tránh sự trùng tên, bạn có thể tên của phương pháp luận r thay vì bán kính. Tuy nhiên, bán kính là khoảng hơn và có ý nghĩa trong bối cảnh này. Java cung cấp một từ khóa gọi này để giải quyết cuộc xung đột đặt tên này. “this.radius” đề cập đến các biến thành viên; trong khi “radius” giải quyết cho lập luận của phương pháp.
Sử dụng các từ khóa “này”, các phương pháp xây dựng, phương thức getter và setter cho một biến tư nhân gọi là xxx của loại T như sau:
public class Aaa {
// A private variable named xxx of type T
private T xxx;
// Constructor
public Aaa(T xxx) {
this.xxx = xxx;
}
// A getter for variable xxx of type T receives no argument and return a value of type T
public T getXxx() {
return xxx;
}
// A setter for variable xxx of type T receives a parameter of type T and return void
public void setXxx(T xxx) {
this.xxx = xxx;
}
}
Đối với một biến boolean xxx, các getter được đặt tên isXxx (), thay vì getXxx (), như sau:
// Private boolean variable
private boolean xxx;
// Getter
public boolean isXxx() {
return xxx;
}
// Setter
public void setXxx(boolean xxx) {
this.xxx = xxx;
}
Ghi chú:
this.varName đề cập đến varname của trường hợp này; this.methodName (…) gọi methodName (…) trong trường hợp này.
Trong một nhà xây dựng, chúng ta có thể sử dụng này (…) để gọi một constructor của lớp này.
Bên trong một phương pháp, chúng ta có thể sử dụng câu lệnh “quay trở lại này” để trở về trường hợp này để người gọi.
Trong một nhà xây dựng, chúng ta có thể sử dụng này (…) để gọi một constructor của lớp này.
Bên trong một phương pháp, chúng ta có thể sử dụng câu lệnh “quay trở lại này” để trở về trường hợp này để người gọi.
2.15 Method toString()
Mỗi lớp Java được thiết kế tốt nên có một phương pháp nào được gọi là toString () trả về một chuỗi mô tả của đối tượng. Bạn có thể gọi toString () phương pháp một cách rõ ràng bởi callinganInstanceName.toString () hoặc ngầm qua println () hoặc String hành nối ‘+’. Chạy println (anInstance) với một đối tượng sẽ gọi toString () phương pháp mà dụ ngầm.
Ví dụ, nếu toString () sau đây là phương pháp được đưa vào lớp mối của chúng tôi:
// Return a short String description of this instance
public String toString() {
return "Circle with radius = " + radius + " and color of " + color;
}
Trong lớp TestCircle của bạn, bạn có thể có được một mô tả văn bản ngắn của một đối tượng bằng các mối:
Circle c1 = new Circle();
System.out.println(c1.toString()); // explicitly calling toString()
System.out.println(c1); // implicit call to c1.toString()
System.out.println("c1 is: " + c1); // '+' invokes c1.toString() to get a String before concatenation
The signature of
toString()
is:public String toString() { ...... }
2.16 Constants (final)
Hằng số là các biến được định nghĩa với các thức sửa đổi. Một biến cuối cùng chỉ có thể được chỉ định một lần và giá trị của nó có thể không được sửa đổi lần giao. Ví dụ,
public final double X_REFERENCE = 1.234;
private final int MAX_ID = 9999;
MAX_ID = 10000; // error: cannot assign a value to final variable MAX_ID
// You need to initialize a final member variable during declaration
private final int SIZE; // error: variable SIZE might not have been initialized
Quy ước đặt tên biến: Một tên hằng là một danh từ, hoặc một cụm danh từ tạo thành một vài từ. Tất cả các từ được viết hoa phân cách bằng dấu gạch dưới “_”, cho ví dụ, X_REFERENCE, MAX_INTEGER và MIN_VALUE.
Nâng cao:
- A
final
primitive variable cannot be re-assigned a new value. - A
final
instance cannot be re-assigned a new address. - A
final
class cannot be sub-classed (or extended). - A
final
method cannot be overridden.
2.17 Putting Them Together in the Revised Circle Class
Circle.java
1 | // The Circle class definition |
TRY
Write a test driver to test ALL the public methods in the
Circle
class.3. More Examples on Classes
3.1 Example: The Account Class
A class called
Account
, which models a bank account, is designed as shown in the class diagram. It contains:- Two private variables:
accountNumber
(int
) andbalance
(double
), which maintains the current account balance. - Public methods
credit()
anddebit()
, which adds or subtracts the given amount from the balance, respectively. Thedebit()
method shall print “amount withdrawn exceeds the current balance!” ifamount
is more thanbalance
. - A
toString()
, which returns “A/C no: xxx Balance=xxx” (e.g., A/C no: 991234 Balance=$88.88), withbalance
rounded to two decimal places.
Account.java
1 | /* The Account class Definition */ |
TestAccount.java
1 | public class TestAccount { |
3.2 Example: The Ball class
A
Ball
class models a moving ball, designed as shown in the class diagram, contains the following members:- Two
private
variablesx
,y
, which maintain the position of the ball. - Constructors, public getters and setters for the private variables.
- A method
setXY()
, which sets the position of the ball andsetXYSpeed()
to set the speed of the ball. - A method
move()
, which increasesx
andy
by the givenxDisp
andyDisp
, respectively. - A
toString()
, which returns “Ball @ (x,y)
“.
Ball.java
1 | // Define the class Ball |
3.3 The Author and Book Classes
Let’s start with the Author class
A class called
Author
is defined as shown in the class diagram. It contains:- Three
private
member variables:name
(String
),email
(String
), andgender
(char
of either'm'
,'f'
, or'u'
for unknown – you might also use aboolean
variable calledmale
having value oftrue
orfalse
). - One constructor to initialize the
name
,email
andgender
with the given values.
(There is no default constructor forAuthor
, as there are no defaults forname
,email
andgender
.) - Public getters/setters:
getName()
,getEmail()
,setEmail()
, andgetGender()
.
(There are no setters forname
andgender
, as these attributes cannot be changed.) - A
toString()
method that returns “author-name (gender) at email
“, e.g., “Tan Ah Teck (m) at ahTeck@somewhere.com
“.
Author.java
1 | // The Author class definition |
A Test Driver Program: TestAuthor.java
1 | // A test driver for the Author class |
A Book is written by an Author – Using an “Object” Member Variable
Hãy thiết kế một lớp Book. Giả sử rằng một cuốn sách được viết bởi một và chỉ một tác giả. Lớp Book (như thể hiện trong sơ đồ lớp) có chứa các thành viên sau:
- Four
private
member variables:name
(String
),author
(an instance of the classAuthor
you have just created, assume that each book has one and only one author),price
(double
), andqtyInStock
(int
). - Two overloaded constructors.
- Getters/Setters:
getName()
,getAuthor()
,getPrice()
,setPrice()
,getQtyInStock()
,setQtyInStock()
. - A
toString()
that returns “‘book-name' by author-name (gender) at email
“.
You should reuse theAuthor
‘stoString()
method, which returns “author-name (gender) at email
“.
Book.java
1 | // The Book class definition |
A Test Driver Program – TestBook.java
1 | // A test driver program for the Book class |
3.4 The Student Class
Giả sử rằng ứng dụng của chúng ta đòi hỏi chúng ta để mô hình một nhóm sinh viên. Một sinh viên có tên và địa chỉ. Chúng tôi được yêu cầu phải theo dõi các khóa học lấy của mỗi học sinh, cùng với các lớp (giữa 0 và 100) cho mỗi khóa học. Học sinh không phải mất hơn 30 khóa học cho toàn bộ chương trình. Chúng tôi được yêu cầu phải in tất cả các lớp học, và cũng là điểm trung bình tổng thể.
We can design the
Student
class as shown in the class diagram. The class contains:- Private member variables
name
(String
),address
(String
),numCourses
,course
andgrades
. ThenumCourses
maintains the number of courses taken by the student so far. Thecourses
andgrades
are two parallel arrays, storing the courses taken (e.g.,{"IM101", "IM102", "IM103"}
) and their respective grades (e.g.{89, 56, 98}
). - A constructor that constructs an instance with the given
name
andAddress
. It also constructs thecourses
andgrades
arrays and set thenumCourses
to 0. - Getters for
name
andaddress
; setter foraddress
. No setter is defined forname
as it shall not be changed. - A
toString()
, which prints “name(address)
“. - A method
addCourseGrade(course, grade)
, which appends the givencourse
andgrade
into thecourses
andgrades
arrays, respectively, and incrementsnumCourses
. - A method
printGrades()
, which prints “name(address) course1:grade1, course2:grade2,...
“. You should reuse thetoString()
here. - A method
getAverageGrade()
, which returns the average grade of all the courses taken.
UML Notations: In UML notations, a variable is written as
[+|-]varName:type
; a method is written as[+|-]methodName(arg1:type1, arg2:type2,...):returnType
, where '+'
denotes public
and '-'
denotes private
.Student.java
The source code for
Student.java
is as follows:1 | // The student class definition |
TestStudent.java
Hãy để chúng tôi viết một chương trình thử nghiệm để tạo ra một sinh viên tên là “Tân Ah Teck”, người đã 3 khóa học, “IM101″, “IM102″ và “IM103″ với điểm số 89, 57, và 96 tương ứng. Chúng tôi sẽ in tất cả các lớp học, và bậc trung bình.
1 | // A test driver program for the Student class |
Tan Ah Teck(1 Happy Ave) IM101:89 IM102:57 IM103:96
The average grade is 80.67
3.5 The MyPoint and MyCircle class
A class called
MyPoint
, which models a 2D point with x and y coordinates, is designed as shown in the class diagram. It contains:- Two private member variables
x
(int
) andy
(int
). - A default (no-arg) constructor that construct a point at
(0,0)
. - A constructor that constructs a point with the given
x
andy
coordinates. - Getter and setter for the private variables
x
andy
. - A method
setXY()
to set bothx
andy
. - A
toString()
method that returns a string description of the instance in the format “(x,y)
“. - A method
distance(int x, int y)
, which returns the distance from this point to another point at the given(x,y)
coordinates indouble
. - An overloaded
distance(MyPoint another)
method, which returns the distance from this point to the givenMyPoint
instance calledanother
.
MyPoint.java
1 | // The MyPoint class definition |
Test Driver Program: TestMyPoint.java
1 | // A test driver for MyPoint class |
A class called
MyCircle
is designed as shown in the class diagram. It contains:- Two
private
member variables: aradius
(double) and acenter
(an instance ofMyPoint
, which we created earlier). - A default (no-arg) constructor that construct a
Circle
at(0,0)
withradius
of 1.0. - A constructor that constructs a
Circle
with the givenxCenter
,yCenter
andradius
. - A constructor that constructs a
Circle
with the given instance ofMyPoint
as center; andradius
. - Getter and setter for the private variables
center
andradius
. - Methods
getCenterX()
,setCenterX()
,setCenterXY()
, etc. - A
toString()
method that returns a string description of the instance in the format “center=(x,y) radius=r
“. - A
distance(MyCircle another)
method that returns the distance from thisCircle
to the givenMyCircle
instance calledanother
.
MyCircle.java
1 | // The MyCircle class definition |
TestMyCircle.java
1 | // A test driver for MyCircle class |
3.6 The MyTime class
A class called
MyTime
, which models a time instance, is designed as shown in the class diagram.It contains the following private instance variables:
hour
: between00
to23
.minute
: between00
to59
.Second
: between00
to59
.
The constructor shall invoke the
setTime()
method (to be described later) to set the instance variable.It contains the following public methods:
setTime(int hour, int minute, int second)
: It shall check if the givenhour
,minute
andsecond
are valid before setting the instance variables.
(Advanced: Otherwise, it shall throw anIllegalArgumentException
with the message “Invalid hour, minute, or second!
“.)Setters setHour(int hour)
,setMinute(int minute)
,setSecond(int second)
: It shall check if the parameters are valid, similar to the above.- Getters
getHour()
,getMinute()
,getSecond()
. toString()
: returns “HH:MM:SS
“.nextSecond()
: Update this instance to the next second and return this instance. Take note that thenextSecond()
of23:59:59
is00:00:00
.nextMinute()
,nextHour()
,previousSecond()
,previousMinute()
,previousHour()
: similar to the above.
MyTime.java
1 | // The MyTime class definition |
Xử lý ngoại lệ -Exception
Phải làm gì nếu một giờ không hợp lệ, hoặc phút thứ hai được đưa ra trong các nhà xây dựng hoặc setter? In thông báo lỗi? Đột ngột chấm dứt chương trình? Tiếp tục hoạt động bằng cách thiết lập các thông số mặc định của nó? Đây là một quyết định khó khăn.
Trong Java, thay vì in một thông báo lỗi, bạn có thể ném một cái gọi là đối tượng ngoại lệ (như IllegalArgumentException) cho người gọi, và để cho người gọi xử lý các trường hợp ngoại lệ. Ví dụ,
void setHour(int hour) {
if (hour >= 0 && hour <= 23) {
this.hour = hour;
} else {
throw new IllegalArgumentException("Invalid hour!");
}
}
The caller can use the
try-catch
construct to handle the exception (in the test driver below). For example,try {
MyTime t3 = new MyTime(12, 69, 69);
// skip remaining statements in try, goto catch
System.out.println(t1);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} // after catch, continue next statement
Các câu lệnh trong các thử-khoản sẽ được thực thi. Nếu tất cả các câu lệnh đều thành công, các khoản catch-được bỏ qua. Tuy nhiên, nếu một trong các báo cáo trong các thử-mệnh đề throws anIllegalArgumentException, phần còn lại của try-khoản sẽ bị bỏ qua, và thực hiện chuyển giao cho các catch-clause. Chương trình luôn luôn tiếp tục các lệnh tiếp theo sau try-catch.
A Test Driver Class: TestMyTime.java
1 | // A test driver program for MyTime |
Nếu không có sự hợp try-catch, “MyTime t2″ đột ngột sẽ chấm dứt chương trình (ví dụ, các phần còn lại của chương trình sẽ không được chạy). Với hợp xử lý try-catch, chương trình có thể tiếp tục hoạt động (ví dụ, xử lý duyên dáng của ngoại lệ).
Lập trình Java đối tượng theo định hướng
0 nhận xét:
Đăng nhận xét