Chuyển đến nội dung chính

tính chất đặc thù của hướng đối tượng trong Java

1. Tính đóng gói (encapsulation) và che giấu thông tin (information hiding) :
  • Trong Java, tính đóng gói được thể hiện thông qua phạm vi truy cập (access modifier). Ngoài ra, các lớp liên quan đến nhau có thể được gom chung lại thành package.
  • Tính chất này không cho phép người sử dụng các đối tượng thay đổi trạng thái nội tại của một đối tượng. Chỉ có các phương thức nội tại của đối tượng cho phép thay đổi trạng thái của nó. Việc cho phép môi trường bên ngoài tác động lên các dữ liệu nội tại của một đối tượng theo cách nào là hoàn toàn tùy thuộc vào người viết mã. Đây là tính chất đảm bảo sự toàn vẹn, bảo mật của đối tượng, 
  • Đóng gói là sự che giấu bên trong dữ liệu riêng của mỗi đối tượng của lớp được khai báo và chỉ được truy xuất thông qua hệ thống các phương thức có sẵn của lớp (chỉ có thể gọi những phương thức có sẵn của lớp). Vì vậy, nó còn được gọi là data hiding (nghĩa là che giấu dữ liệu).
  • Tính đóng gói có những đặc điểm như sau:
    • Tạo ra cơ chế để ngăn ngừa việc gọi phương thức của lớp này tác động hay truy xuất dữ liệu của đối tượng thuộc về lớp khác.
    • Dữ liệu riêng (khi được khai báo là private) của mỗi đối tượng được bảo vệ khỏi sự truy xuất không hợp lệ từ bên ngoài.
    • Người lập trình có thể dựa vào cơ chế này để ngăn ngừa việc gán giá trị không hợp lệ vào thành phần dữ liệu của mỗi đối tượng.
    • Cho phép thay đổi cấu trúc bên trong của một lớp mà không làm ảnh hưởng đến những lớp bên ngoài có sử dụng lớp đó.
    Để cài đặt tính đóng gói, chúng ta có 2 bước như sau:
    • Khai báo các thuộc tính của đối tượng trong lớp là private để các lớp khác không thể truy cập trực tiếp/sửa đổi được.
    • Cung cấp các phương thức getter/setter có phạm vi truy cập là public để truy cập và sửa đổi các giá trị của thuộc tính trong lớp. Phương thức getter là phương thức truy cập vào thuộc tính của đối tượng và trả về các thuộc tính của đối tượng, còn phương thức setter là phương thức truy cập vào thuộc tính của đối tượng và gán giá trị cho các thuộc tính của đối tượng đó.
    • Ví dụ sau sẽ minh họa tính đóng gói trong Java:
      Person.java
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      package vidu;
      public class Person {
          // khai báo các thuộc tính của đối tượng là private
          private String cmnd;
          private String hoTen;
           
          // tạo các phương thức getter/setter
          // 2 phương thức getCmnd() và getHoTen() là phương thức getter
          // dùng để trả về số chứng minh nhân dân và họ tên của đối tượng
          // và kiểu trả về của hai phương thức này tương ứng với kiểu dữ liệu của thuộc tính
          // 2 phương thức setCmnd() và setHoTen() là phương thức setter
          // dùng để gán giá trị cho thuộc tính chứng minh nhân dân và họ tên của đối tượng
          // trong đó tham số truyền vào của 2 phương thức này được gọi là tham số (biến cục bộ)
          // và có kiểu dữ liệu tương ứng với kiểu dữ liệu của thuộc tính (biến đối tượng)
          public String getCmnd() {
              return cmnd;
          }
           
          // this là từ khóa có ý nghĩa là một tham chiếu đặc biệt
          // chiếu tới đối tượng chủ của phương thức hiện hành
          // this có thể được dùng để truy cập biến đối tượng (instance variable)
          // hoặc gọi phương thức đối với đối tượng hiện hành.
          // Thông thường, công dụng này của this chỉ có ích
          // khi tên biến đối tượng bị trùng với tham số (biến cục bộ - local variable) của phương thức
          public void setCmnd(String cmnd) {
              this.cmnd = cmnd;
          }
          public String getHoTen() {
              return hoTen;
          }
          public void setHoTen(String hoTen) {
              this.hoTen = hoTen;
          }
           
      }
      TestPerson.java
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      package vidu;
      public class TestPerson {
          public static void main(String[] args) {
              Person person = new Person();
               
              // gán giá trị họ tên cho đối tượng person vừa tạo thông qua setHoTen()
              // và gán số chứng minh nhân dân thông qua setCmnd()
              person.setHoTen("Trần Văn Bình");  
              person.setCmnd("212321678");
               
              // truy cập đến tên của đối tượng person thông qua phương thức getHoten()
              // và số chứng minh nhân dân thông qua phương thức getCmnd()
              System.out.println("Tên: " + person.getHoTen() + ", số cmnd: " + person.getCmnd());
          }
      }
      Kết quả sau khi biên dịch chương trình:
    • this là từ khóa có ý nghĩa là một tham chiếu đặc biệt chiếu tới đối tượng chủ của phương thức hiện hành. Trong lớp Person, phương thức setHoTen() lấy một tham số (hay còn gọi là biến cục bộ - Local VariablehoTen kiểu String trùng tên với thuộc tính hoTen của lớp đó, nếu chúng ta chỉ viết "hoTen" mà không có từ khóa this đằng trước thì trình biên dịch sẽ hiểu là ta đang nói đến tham số hoTen. Vì vậy, để gọi đến thuộc tính (hay còn gọi là biến đối tượng - Instance Variable), cách duy nhất là sử dụng tham chiếu this để gọi một cách tường minh
    2.Tính kế thừa (inheritance):
    • Tư tưởng của kế thừa trong java là có thể tạo ra một class mới được xây dựng trên các lớp đang tồn tại. Khi kế thừa từ một lớp đang tồn tại bạn có sử dụng lại các phương thức và thuộc tính của lớp cha, đồng thời có thể khai báo thêm các phương thức và thuộc tính khác.
    • Tính chất này cho phép một đối tượng có thể có được các đặc tính (thuộc tính, phương thức) mà đối tượng khác đã có thông qua kế thừa(extends). Điều này cho phép các đối tượng chia sẻ hay mở rộng các đặc tính sẵn có mà không phải tiến hành định nghĩa lại. 
    • Tuy nhiên vì tính bao đóng trong Java nên khuyên các bạn chúng ta nên khai báo thuộc tính là private. Java cũng khuyến cáo chúng ta như vậy và tất nhiên các lập trình viên cần phải có ý thức để thuộc tính là private.
    • Ở code trên, các bạn thấy rằng chúng ta viết lại y hệt phương thức của class cha, nhưng thây vì phải nhập lại mã , tên sách, thì tôi sẽ dùng từ khóa super để gọi phương thức của lớp cha. Khi chúng ta viết lại phương thức cùng tên,cùng phạm vi truy cập và cùng kiểu dữ liệu trả về của lớp cha. Vậy khi gọi phương thức nhap() cũng như toString() thì nó sẽ chạy phương thức của lớp con.Và loại bỏ phương thức của thằng cha đi
    • Vì sao phải ghì đè? 
      1. Để class con đảm bảo đầy đủ các chức năng để  nó hoạt động tốt.
      2. Để đồng bộ code

      Vậy theo các bạn phương thức setter và getter trong java có ghì đè được không? Qúa đơn giản, tất nhiên là được vì nó là một hàm bình thường. Tuy nhiên bây giờ theo các bạn, hàm đặc biệt (hàm khởi tạo hay constructor) trong java có ghì đè được không?
      Trước khi trả lời câu hỏi này,  gợi ý các bạn như sau:
      Constructor là hàm dùng để tạo ra object từ một class nào đấy. (đương nhiên class nào thì đi kèm với constructor của nó). 
      Chắc các bạn có thể dễ dàng đoán ra được rồi với gợi ý của mình rồi chứ? Không nhé.
      Nếu class SachLapTrinh ghì đè constructor của lớp Sach thì nó quá vô nghĩa và chả có tác dụng gì.
      Câu hỏi:hàm đặc biệt (hàm khởi tạo hay constructor) trong java có ghì đè được không?
      Trả lời :Không, nhưng lại có. (trả lời thế nhà tuyển dụng mới sợ nhé).
      Giải thích như sau:
      Khi tạo ra object lớp con, thì tất nhiên object lớp cha cũng được khởi tạo.Vì sao? các bạn suy nghĩ lại xem ở ví dụ trên, nếu không tạo ra object lớp cha thì lớp con sao lấy được mã, tên?
    • Nguyên tắc :
      Trong constructor của class con khi extends phải gọi constructor của lớp cha, nếu không có constructor  thì hệ thống sẽ tự tạo constructor mặc định và gọi constructor của lớp cha.
    •  super cũng dùng để gọi constructor của lớp cha.
      Nhưng lại có một trường hợp trơ trêu là constructor của lớp cha không có, hoặc tôi cố tình thay phạm vi truy cập thành private thì điều gì xảy ra? Nó sẽ bị lỗi ngay, vì mặc định hệ thống sẽ gọi constructor của lớp cha, mà constructor lại không có nên đơn nhiên nó bị lỗi.(Các bạn thử thay vào trong code nhé, tôi lười chụp lại ảnh quá).
      Vậy chúng ta sẽ xử lý như thế nào? 
      1. Các bạn phải tự gọi constructor của lơp cha, một constructor  nào đấy nhưng là public nhé. Ví dụ constructor  có tham số chẳn hạn.
      2. Thông thường thì chúng ta không làm như thế này, mà sẽ làm như sau:
      làm cách thứ hai thì nhìn vào code rất trong sang và đồng bộ.
      Tôi nói thêm như vậy để các bạn hiểu bản chất, chứ thật ra chả ai viết ra constructor mà để private cả ^^.

      Chưa hết , giả sử như class của lớp cha, không có constructor nào thì điều gì lại xảy ra tiếp theo?
      Cái này người ta gọi là cấm kế thừa. Một trong những cách cấm kế thừa nữa là ở class các bạn muốn cấm kế thừa thêm vào từ khóa final.
      Vì sao phải cấm kế thừa? Vì một số trường hợp chúng ta đã viết một số class rất hoản chỉnh rồi và cho người khác sử dụng, tất nhiên đã hoàn chỉnh rồi thì thằng nào muốn dùng thì copy class sử dụng, chứ nếu cho nó kế thừa thì uổng công sức bỏ ra viết quá nhỉ. @@.
      Lưu ý: Khi kế thừa các bạn phải có ý thức kế thừa chính xác, nghĩa là ví dụ class ConMeo thì không thể extends từ class SinhVat được. Tất nhiên các bạn  code thì nó vẫn chạy nhưng sai về mặt ý nghĩa. Chúng ta là lập trình viên thì phải ý thức được điều đấy
3.Tính đa hình (polymorphism):
  • Khi một tác vụ được thực hiện theo nhiều cách khác nhau được gọi là tính đa hình.
  • Đối với tính chất này, nó được thể hiện rõ nhất qua việc gọi phương thức của đối tượng. Các phương thức hoàn toàn có thể giống nhau, nhưng việc xử lý luồng có thể khác nhau. Nói cách khác: Tính đa hình cung cấp khả năng cho phép người lập trình gọi trước một phương thức của đối tượng, tuy chưa xác định đối tượng có phương thức muốn gọi hay không. Đến khi thực hiện (run-time), chương trình mới xác định được đối tượng và gọi phương thức tương ứng của đối tượng đó. Kết nối trễ giúp chương trình được uyển chuyển hơn, chỉ yêu cầu đối tượng cung cấp đúng phương thức cần thiết là đủ.
  • Trong Java, chúng ta sử dụng nạp chồng phương thức (method overloading) và ghi đè phương thức (method overriding) để có tính đa hình.
- đa hình trong phương thức
    • Nạp chồng (Overloading): Đây là khả năng cho phép một lớp có nhiều thuộc tính, phương thức cùng tên nhưng với các tham số khác nhau về loại cũng như về số lượng. Khi được gọi, dựa vào tham số truyền vào, phương thức tương ứng sẽ được thực hiện.
    • Ghi đè (Overriding): là hai phương thức cùng tên, cùng tham số, cùng kiểu trả về nhưng thằng con viết lại và dùng theo cách của nó, và xuất hiện ở lớp cha và tiếp tục xuất hiện ở lớp con. Khi dùng override, lúc thực thi, nếu lớp Con không có phương thức riêng, phương thức của lớp Cha sẽ được gọi, ngược lại nếu có, phương thức của lớp Con được gọ
- đa hình trong đối tượng:
+ nhìn nhận đối tượng theo nhiều kiểu khác nhau
4.Tính trừu tượng (abstraction):
  • Tính trừu tượng là một tiến trình ẩn các chi tiết trình triển khai và chỉ hiển thị tính năng tới người dùng. Tính trừu tượng cho phép bạn loại bỏ tính chất phức tạp của đối tượng bằng cách chỉ đưa ra các thuộc tính và phương thức cần thiết của đối tượng trong lập trình.
  • Tính trừu tượng giúp bạn tập trung vào những cốt lõi cần thiết của đối tượng thay vì quan tâm đến cách nó thực hiện.
  • Trong Java, chúng là sử dụng abstract class và abstract interface để có tính trừu tượng.
  • Ưu điểm khi sử dụng tính trừu tượng để lập trình:
    • Tính trừu tượng cho phép các lập trình viên loại bỏ tính chất phức tạp của đối tượng bằng cách chỉ đưa ra các thuộc tính và phương thức cần thiết của đối tượng trong lập trình, cải thiện khả năng bảo trì của hệ thống.
    • Tính trừu tượng giúp chúng ta tập trung vào những cốt lõi cần thiết của đối tượng thay vì quan tâm đến cách nó thực hiện.
    • Tính trừu tượng cung cấp nhiều tính năng mở rộng khi sử dụng kết hợp với tính đa hình và kế thừa trong lập trình hướng đối tượng.

Nhận xét

Bài đăng phổ biến từ blog này

Entry Test của FPT

IQ - Kiểm tra tư duy logic (8/20) - GMAT- Kiểm tra khả năng tính toán trong thời gian ngắn (8/20) - Tiếng Anh (18-> 25/50) - Các bài thi chuyên môn - FE (8/20) IQ: lên mạng tìm "IQ test" là ra đầy. + GMAT: Những câu trắc nghiệm tính toán đơn giản kiểu như sau:  1 . Một shop thời trang sale off quần jeans 15 %, quần jeans giá 450 $, người mua đưa 500 $, hỏi cashier trả lại bao nhiêu $ tiền thừa.? 2 . 100 % là 180 , vậy 150 là bao nhiêu %? Tiếng anh: Cỡ như thi TOEIC thôi. Chuyên môn: Mobile thì trắc nghiệm Java. Qúa trình tuyển như sau :v Lần 1: Test IQ, Tiếng Anh( mình làm í ẹ khoảng 50% mà vẫn được) , Java Lân 2: được gọi điện lên :)) + Gioi thiệu bản thân + Họ chỉ hỏi các câu căn bản như: -. OOP: là gì, 4 tính chất, ví dụ, khác nhau giữa interface và abstract - CODE: hầu toàn các bài toán vòng for :)) , cẩn thận mấy câu kế thừa. SQL (distinct, view, function, cursor, store procedure, ...v.v.), nhớ có câu cộng 2 số int không dùng biến đệm hơi khoai haha + Nói ch...

Java: Java Package-Thư viện trong Java

Giới thiệu về Package Các bạn mới học lập trình Java thường không dể ý tới package vì các bạn toàn tạo file .java vào cùng 1 chỗ, không cần sắp xếp, không cần quản lý truy nhập. Nhưng để tăng kỹ năng lập trình với Java, các bạn cần phải tìm hiểu về package trong Java. Các bạn có thể tham khảo định nghĩa sau: Package được dùng để đóng gói các lớp trong chương trình lại với nhau thành một khối. Đây là cách tốt nhất để lưu trữ các lớp gần giống nhau hoặc có cùng một module thành một khối thống nhất – để đáp ứng 1 khối chức năng. Từ đây mình sẽ giới thiệu thêm với các bạn các câu lệnh nhâp khẩu,nó có định dạng như sau : Định dạng :  import javaPackageNameImport;    Nó giống như khai báo thư viện ở các ngôn ngữ lập trình khác.Như vậy,chỉ khi các bạn nhập khẩu chúng,các bạn mới có thể sử dụng thư viện mà chúng cung cấp cho ta. VD :    import java.util.Date;   import java.text.SimpleDateFormat; Lưu ý : -Các câu lệnh nhập khẩu rất nhiều và...

Khác nhau giữa Array và ArrayList và HashMap

Collection bản chất là tập các lớp dùng để lưu trữ danh sách và có khả năng tự co giãn khi danh sách thay đổi : Thêm , sửa , xóa , chèn … Hai lớp Collection thường được sử dụng nhiều nhất là ArrayList và Hashmap Giới thiệu về ArrayList ArrayList sử dụng cấu trúc mảng để lưu trữ phần tử , tuy nhiên có hai đặc điểm khác mảng : Không cần khai báo trước kiểu phần tử . Không cần xác định trước số lượng phần tử ( kích thước mảng ). N ó có kh ả năng truy c ậ p ph ầ n t ử ng ẫ u nhiên (Do th ừ a k ế t ừ interface RandomAccess ). P hương thức khởi tạo ● ArrayList () ● ArrayList (Collection c) ● ArrayList ( int initialCapactity ) Các phương thức chính ● add(Object o) ● remove(Object o) ● get( int index) ● size() ● isEmpty () ● contains(Object o) ● clear() Giới thiệu về HashMap ● Là ki ể u t ậ p h ợ p t ừ đ i ể n, HashMap cho phép truy xu ấ t tr ự c ti ế p t ớ i m ộ ...