Đa hình và Các mức truy cập

Ngày đăng: 23/12/2020   -    Cập nhật: 23/12/2020


Ở phần trước chúng ta đã tìm hiểu qua về kế thừa trong Java, vậy còn đa hình trong Java thì sao? Thực ra nó cũng quan trọng như kế thừa vậy đó – nhưng bạn đa biết gì về nó chưa? Nào chúng ta hãy cùng nhau tìm hiểu nhé.


Trong Java, tính đa hình liên quan đến hai tính năng:


  • Ghi đè phương thức (Method Overriding)
  • Nạp chồng phương thức (Method Overloading)

1. Tìm hiểu về đa hình trong JAVA


Theo nghĩa tổng quát, đa hình là khả năng tồn tại ở nhiều hình thức. Trong hướng đối tượng, đa hình đi kèm với quan hệ thừa kế và có hai đặc điểm sau:


  • (1) Các đối tượng thuộc các lớp dẫn xuất khác nhau có thể được đối xử như nhau, như thể chúng là các đối tượng thuộc lớp cơ sở, chẳng hạn có thể gửi cùng một thông điệp tới đối tượng.
  • (2) Khi nhận được cùng một thông điệp đó, các đối tượng thuộc các lớp dẫn xuất khác nhau hiểu nó theo những cách khác nhau.


Xét xem hai đoạn code sau để làm rõ vấn đề nêu trên.


File ConBo.java trong package content




package niit.content;

public class ConBo {
    void keu() {
        System.out.println("Moo...!");
    }

    void lamGiDo(ConBo c) {
        c.keu();
    }
}
 


Sau đó ta tạo một file ConBe.java cùng package



package niit.content;

public class ConBe extends ConBo {

    // Ghi đè phương thức keu()
    public void keu() {
        System.out.println("Umbooo...");
    }

    public static void main(String[] args) {

        ConBo conBo = new ConBo();
        conBo.lamGiDo(conBo);; // Moo...!

        ConBo conBe = new ConBe();
        conBe.lamGiDo(conBe); // Umbooo...
    }
}
 


Như vậy, với đa hình, ta có thể viết những đoạn code không phải sửa đổi khi ta bổ sung lớp con mới vào chương trình.


Ví dụ như lớp ConBe bên trên, do sử dụng tham số kiểu ConBo nên có thể sử dụng cho bất kì lớp con nào của ConBo.


Khi muốn thêm một lớp con mới, ta cũng hoàn toàn có thể tận dụng các phương thức của lớp ConBe mà không cần phải viết lại.


2. Ghi đè (Override) và Nạp chồng (Overload) trong Java


Khi ta muốn ghi đè thương thức (Method Overriding) của lớp cha trong Java, ta phải tuân thủ các quy tắc sau:


  • Phương thức lớp con ghi đè Phương thức lớp cha phải có danh sách tham số phải trùng nhau, kiểu giá trị trả về phải tương thích.


Lớp cha quy định quy cách mà các phần code khác sử dụng các phương thức của nó. Phương thức của lớp cha có thể được gọi với danh sách đối số như thế nào thì cũng có thể gọi phương thức của lớp con với danh sách đối số đó.


Phương thức của lớp cha tuyên bố kiểu trả về là gì, thì phương thức của lớp con cũng phải khai báo chính kiểu trả về đó hoặc một kiểu lớp con của kiểu đó.


Nhớ lại rằng một đối tượng thuộc lớp con phải được đảm bảo có thể làm được bất cứ thứ gì mà lớp cha đã tuyên bố, do đó, việc trả về đối tượng lớp con ở vị trí của đối tượng lớp cha là việc an toàn.



  • Phương thức đè không được giảm quyền truy cập so với phiên bản của lớp cha.


Nói cách khác, quyền truy cập mà phiên bản của lớp con cho phép phải bằng hoặc rộng hơn phiên bản của lớp cha.


Ta không thể ghi đè một phương thức public (của lớp cha) bằng một phiên bản private (ở lớp con).


Nếu không, tình huống xảy ra là một lời gọi phương thức đã được trình biên dịch chấp nhận vì tưởng là phương thức public nhưng đến khi nó chạy lại bị máy ảo từ chối vì phiên bản được gọi lại là private.



Nạp chồng phương thức (Method Overloading) chỉ đơn giản là có một vài phương thức trùng tên nhưng khác danh sách đối số.


Nạp chồng phương thức cho phép ta tạo nhiều phiên bản của một phương thức, mỗi phiên bản chấp nhận một danh sách đối số khác nhau, nhằm tạo thuận lợi cho việc gọi phương thức.


Ví dụ, khi định nghĩa class ConBo ta tạo ra 2 phương thức trùng tên nhưng khác tham số như sau:




    // Phương thức lamGiDo không tham số
    void lamGiDo() {
        System.out.println("ahihi....");
    }
    
    // Phương thức lamGiDo có một tham số
    void lamGiDo(String x) {
        System.out.println(x);
    


Sau đó, trong main, chúng ta có thể gọi cùng một hàm lamGiDo() nhưng nếu có truyền đối số thì kết quả khác nhau.



package niit.content;

public class ConBo {
    
    // Phương thức lamGiDo không tham số
    void lamGiDo() {
        System.out.println("ahihi....");
    }
    
    // Phương thức lamGiDo có một tham số
    void lamGiDo(String x) {
        System.out.println(x);
    }

    public static void main (String[] args) {
        
        // Tạo đối tượng của ConBo
        ConBo conBo = new ConBo();
        
        // Thử gọi hàm lamGiDo mà không truyền đối số
        conBo.lamGiDo();

        String x = "Moo....!";
        // Gọi hàm lamGiDo có truyền đối một chuỗi
        conBo.lamGiDo(x);
    }

}
 


Kết quả khi chạy chương trình:



ahihi....
Moo...!
 


Do cơ chế nạp chồng phương thức, các phương thức trong Java có tính linh hoạt cao hơn.


  • Kiểu trả về có thể khác nhau. Ta có thể tùy ý thay đổi kiểu trả về tại các phương thức chồng, miễn là danh sách đối số khác nhau.
  • Nếu bạn định nghĩa không chuẩn, trình biên dịch sẽ cho rằng ta đang định ghi đè phương thức. Để overload, ta nhất định phải sửa lại
  • Có thể nới rộng hoặc hạn chế quyền truy cập tùy ý. Ta có thể tùy ý thay đổi quyền truy cập của phương thức chồng vì phương thức mới không bị buộc phải tuân theo hợp đồng đa hình, nếu có, của phương thức cũ

3. Các mức độ truy cập trong JAVA


Trong JAVA, ta có bốn mức truy cập (access level / Access Modifier) và ba từ khóa tương ứng private, protectedpublic, mức còn lại là mức mặc định (default) không cần chỉ định.


Các mức truy nhập được liệt kê theo thứ tự từ hẹp nhất tới rộng nhất như sau:



  • private: chỉ có code bên trong cùng một lớp mới có thể truy nhập được những thứ private. private ở đây có nghĩa "của riêng lớp" chứ không phải "của riêng đối tượng".


Một đối tượng Dog có thể sửa các biến private hay gọi phương thức private của một đối tượng Dog khác, nhưng một đối tượng Cat thì thậm chí không 'nhìn thấy' các thứ private của Dog.


Các đối tượng Dog cũng không thể 'nhìn thấy' các biến / phương thức private của các đối tượng Animal mà nó thừa kế. Vậy nên người ta nói rằng lớp con không thừa kế các biến / phương thức private của lớp cha



  • default: các biến/phương thức với mức truy nhập mặc định của một lớp chỉ có thể được truy nhập bởi mã nằm bên trong cùng một gói với lớp đó.

  • protected: các biến/phương thức với mức protected của một lớp chỉ có thể được thừa kế bởi các lớp con cháu của lớp đó, kể cả nếu lớp con đó không nằm trong cùng một gói với lớp cha.

  • public: mã ở bất cứ đâu cũng có thể truy nhập các thứ public (lớp, biến thực thể, biến lớp, phương thức, hàm khởi tạo...)



package niit.content;

public class ConBo {
    public String ten;
    private String giong;
    int tuoi;
    protected boolean gioiTinh;
}
 


publicprivate là hai mức truy cập được sử dụng nhiều nhất.


Mức public thường dùng cho các lớp, hằng (biến static final), các phương thức dành cho mục đích tương tác với bên ngoài (ví dụ các phương thức get và set), và hầu hết các hàm khởi tạo.


Mức private được dùng cho hầu hết các biến thực thể và cho các phương thức mà ta không muốn được gọi từ bên ngoài lớp (các phương thức dành riêng cho các phương thức public của lớp đó sử dụng).


Mức default được dùng để giới hạn phạm vi trong một gói. Người ta dùng giới hạn này vì gói được thiết kế là một nhóm các lớp cộng tác với nhau như là một tập hợp gắn bó với nhau.


Trong khi tất cả các lớp bên trong cùng một gói thường cần truy nhập lẫn nhau, chỉ có một nhóm trong số đó cần phải để lộ ra ngoài gói, nhóm này sẽ dùng các mức public hay protected theo một cách thích hợp.


Lưu ý rằng nếu lớp có mức protected, thì các phương thức bên trong nó dù có thuộc mức public thì bên ngoài cũng không thể 'nhìn thấy', do không thể nhìn thấy lớp chứa các phương thức đó.


Mức protected gần như giống hệt với mức mặc định, chỉ khác ở chỗ:



  • Nó cho phép các lớp con thừa kế các thứ protected của lớp cha, kể cả khi lớp con nằm ngoài gói chứa lớp cha.


Như vậy, mức này chỉ áp dụng cho quan hệ thừa kế. Nếu một lớp con nằm ngoài gói có một tham chiếu tới một đối tượng thuộc lớp cha, và giả sử lớp cha này có một phương thức protected, lớp con cũng không thể gọi phương thức đó từ tham chiếu đó.


Cách duy nhất để một lớp con có khả năng truy nhập một phương thức protected là thừa kế phương thức đó.


Nói cách khác, lớp con ngoài gói không thể truy nhập phương thức protected, nó chỉ sở hữu phương thức đó qua quan hệ thừa kế.


Tổng kết


Như vậy, qua phần này bạn đã có các hiểu biết cơ bản về các nội dung liên quan đến đa hình trong Java. Để hiểu sâu bạn cần tiếp xúc nhiều và luyện tập thường xuyên, đồng thời đừng quên theo dõi các bài viết tiếp theo trong Series này nhé.


> Nếu bạn thích Java thì tham gia HỌC JAVA ngay để bắt đầu sử dụng Java tạo ra thứ gì đó thú vị!


---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học thực tế + Tuyển dụng ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0914939543
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
 
#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp
Bình luận Facebook
Đăng ký tư vấn
Nhân viên gọi điện tư vấn miễn phí sau khi đăng ký
Được cập nhật các ưu đãi sớm nhất
Hotline: 0383180086
Tên không được để trống
Số điện thoại không được để trống
Email không được để trống
Hãy đăng ký để nhận những thông tin mới nhất về học bổng mới nhất tại NIIT - ICT Hà Nội
top
Đóng lại Đăng ký học tại NIIT - ICT Hà Nội
6260+ học viên đã theo học tại NIIT - ICT Hà Nội và có việc làm tốt trong ngành lập trình. Nắm lấy cơ hội ngay hôm nay!
Chọn khóa học
  • KHÓA HỌC LẬP TRÌNH FRONT END VỚI REACT.JS
  • KHÓA HỌC LẬP TRÌNH PHP WEB
  • Khóa học PHP Full stack [2023] cho người mới bắt đầu
  • Khóa học BIG DATA với Hadoop và Spark
  • Khóa học Lập trình Android tại Hà Nội
  • [Tuyển sinh 2023] Lập trình viên Quốc tế DigiNxt
  • Khóa học Tiền lương & Phúc lợi (C&B Excel) tại Hà Nội
  • LẬP TRÌNH GAME
    • Khóa học Lập trình Game Unity
  • LẬP TRÌNH WEB FRONT END
    • KHÓA HỌC PYTHON HƯỚNG ĐỐI TƯỢNG
    • KHÓA HỌC ANGULAR & TYPESCRIPT (FRONT END)
  • LẬP TRÌNH WEB BACK END
    • LẬP TRÌNH JAVA WEB VỚI FRAME WORK
    • Lập trình Web với Django
    • Lập trình PHP với Laravel Framework
  • CHƯƠNG TRÌNH ĐÀO TẠO ỨNG DỤNG CÔNG NGHỆ
    • Khóa học Tiền lương & Phúc lợi (C&B Excel) tại TP HCM
  • LẬP TRÌNH WEB FULL STACK
    • Khóa học Java Full stack (IJFD)
  • LẬP TRÌNH MOBILE
    • FRONT-END VỚI REACTJS VÀ REACT NATIVE
    • Lập trình Android Nâng cao
  • ĐÀO TẠO CHO DOANH NGHIỆP
    • KHÓA HỌC BUSINESS ANALYSIC TỪ CƠ BẢN ĐẾN NÂNG CAO 2023
    • Khóa học Magento: Làm chủ CMS TMĐT lớn nhất
    • Khóa học IOT: Xây dựng Sản phẩm IOT với Raspberry Pi
    • Khóa học Automation Testing Chuyên nghiệp
  • KHÓA HỌC DỰ ÁN
    • Học sử dụng bộ Office: Word, Excel, Power Point, Mail chuyên nghiệp
  • KHÓA HỌC KHÁC
    • VBA Excel Toàn Tập (Cơ Bản - Nâng Cao)
    • VBA Excel Nâng cao
    • Khóa học JMeter: Performance Testing
    • Khóa học Tester đạt chuẩn Quốc tế ISTQB Foundation Level
    • Khoá Học Tester đạt chuẩn quốc tế ISTQB Advanced Level
Bạn chưa chọn khóa học cần đăng ký
Tên không được để trống
Số điện thoại không được để trống
Email không được để trống
Đăng ký học thành công!
Cảm ơn bạn đã đăng ký học tại NIIT - ICT HÀ NỘI!