JAVA 8
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Khi nào dùng Default Methods trong Java 8

Ở 2 bài trước chúng ta đã tìm hiểu 2 tính năng mới của Java 8 là Lambda ExpressionsMethod References (phương thức tham chiếu) trong java 8. Hôm nay chúng ta sẽ tìm hiểu thêm 1 tính năng nữa của java 8 là default methods (tạm dịch là phương thức mặc định).

1. Đặt vấn đề

Như chúng ta đã biết, Java có tính chất trừu tượng và được thể hiện thông qua abstract class và interface. Trong interface, chúng ta có thể đa kế thừa các class với nhau và thực hiện implement các phương thức đến các class khác nhau.

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Bây giờ, chúng ta cùng xét một ví dụ dưới đây:

Ở ví dụ trên tôi có một interface là IA và một lớp AImpl thực hiện cài đặt các phương thức từ IA.

package com.company.example.freetus;


interface IA{
    void A1();
    void A2();
    void A3();
}



public class AImpl implements IA{
    @Override
    public void A1() {

    }

    @Override
    public void A2() {

    }

    @Override
    public void A3() {

    }
}

Bây giờ tôi bổ sung thêm phương thức A4 vào interface IA

void A4(){
  System.out.println("A4");
}

Chương trình báo lỗi ở "void A4()" vì trong theo lý thuyết là interface chỉ chứa các phương thức không chứa xử lý logic hoặc code bên trong phương thức.

Vậy có cách nào sử dụng được phương thức A4 mà chương trình không vi phạm tính chất của interface không?

2. Default Methods là gì trong Java?

Trước khi tìm hiểu xem phương thức mặc định là gì? Chúng ta cùng xem ví dụ dưới đây:

package com.company.example.freetus;

class Square {

    private int canh;

    public Square(int canh) {
        this.canh = canh;
    }

    public int getCanh() {
        return canh;
    }

    public void setCanh(int canh) {
        this.canh = canh;
    }
}

interface ShapeInterface{
    //in ra tên hình
    void show(String name);
    //tinh dien tich
    float area(Square square);

}
class SquareImpl implements ShapeInterface{

    @Override
    public void show(String name) {
        System.out.println("Ten hình: "+name);
    }

    @Override
    public float area(Square square) {
        return square.getCanh() * square.getCanh();
    }
}
public class TestSquare {
    public static void main(String[] args) {
        Square square = new Square(5);
        ShapeInterface shapeInterface = new SquareImpl();
        shapeInterface.show("Hình vuông");
        System.out.println("Diện tích hình vuông: "+ shapeInterface.area(square));
    }
}

Kết quả:

  • Tên hình: Hình vuông
  • Diện tích hình vuông: 25.0

Chúng ta thấy class Square sẽ thực hiện implements lại các phương thức có trong lớp ShapeInteface đúng theo tính chất của trừu tượng trong Java.

Nhưng bây giờ nếu tôi muốn thêm một phương thức nữa vào ShapInterface mà không muốn implements vào lớp Square thì chúng ta phải làm như thế nào? Đó chính là dùng phương thức mặc định (default methods).

Phương thức mặc định là khi thêm vào một hoặc nhiều phương thức mặc định khác nhau mà không gây ảnh hưởng đến interface và các lớp liên quan đến chính lớp Interface đó.

Phương thức mặc định sẽ không bắt buộc phải implements từ interface nếu có một class đang cài đặt các phương thức từ một lớp Interface .(Nghĩa là nếu tôi có 1 lớp Interface A có chứa phương thức mặc định là B. Bây giờ tôi tạo ra một Class C thực hiện implements từ Interface A thì phương thức mặc định B của tôi sẽ không bắt buộc phải có trong Class C mà nó sẽ là một phương thức tự do).

Để sử dụng được phương thức default chúng ta sẽ thêm từ khóa “default” vào trước phương thức mà mình mong muốn phương thức đó là phương thức mặc định.

default  [Kiểu trả về] [tên phương thức] {
	//code xử lý
}

Ví dụ mẫu:

default void squareInfo(Square square){
    System.out.println("Hình vuông có cạnh: "+ square.getCanh());
}

Lưu ý: Phương thức mặc định này viết giống như 1 phương thức thông thường. Nghĩa là nó có phần xử lý code trong phương thức mặc định đó.

Ví dụ code mẫu:

package com.company.example.freetus;

class Square {

    private int canh;

    public Square(int canh) {
        this.canh = canh;
    }

    public int getCanh() {
        return canh;
    }

    public void setCanh(int canh) {
        this.canh = canh;
    }
}

interface ShapeInterface{
    //Thông tin về hình vuông
    default void squareInfo(Square square){
        System.out.println("Hình vuông có cạnh: "+ square.getCanh());
    }
    //in ra tên hình
    void show(String name);
    //tinh dien tich
    float area(Square square);

}
class SquareImpl implements ShapeInterface{

    @Override
    public void show(String name) {
        System.out.println("Tên hình: "+name);
    }

    @Override
    public float area(Square square) {
        return square.getCanh() * square.getCanh();
    }
}
public class TestSquare {
    public static void main(String[] args) {
        Square square = new Square(5);
        ShapeInterface shapeInterface = new SquareImpl();
        shapeInterface.squareInfo(square);
        shapeInterface.show("Hình vuông");
        System.out.println("Diện tích hình vuông: "+ shapeInterface.area(square));
    }
}

Kết quả:

  • Hình vuông có cạnh: 5
  • Tên hình: Hình vuông
  • Diện tích hình vuông: 25.0

3. Phương thức mặc định và đa kế thừa

Trong java hay trong các phiên bản trước java 8, chúng ta đã tìm hiểu và biết về đa kế thừa.

Đa kế thừa trong java là trong một lớp có thể thực hiện một hoặc nhiều interface kế thừa tới lớp mà mình muốn thực hiện. Trong java chỉ có mỗi Interface hỗ trợ đa kế thừa. Đa kế thừa chỉ thực hiện với các class và interface liên quan với nhau.

Ví dụ về đa kế thừa:

package com.company.example.freetus;

interface Dog{
    void run();
}
interface Bird{
    void fly();
}
public class Animal implements Dog, Bird {
    @Override
    public void run() {
       
    }

    @Override
    public void fly() {

    }
}

Ở ví dụ trên, con chó có thể chạy, con chim có thể bay và động vật sẽ thực hiện đa kế thừa cả 2 hoạt động của chó và mèo. Để tạo ra 1 lớp chung thực hiện 2 hoạt động của cả chó và chim.

Giờ chúng ta sẽ thực hiện thêm phương thức mặc định cho ví dụ trên. Nhưng lần này tôi sẽ thêm 1 phương thức mặc định cho cả 2 interface.

package com.company.example.freetus;

interface Dog{
    default void show(){
       
    }
    void run();
}
interface Bird{
    default void show(){

    }
    void fly();
}
public class Animal implements Dog, Bird {
    @Override
    public void run() {

    }

    @Override
    public void fly() {

    }
}

Lúc này ở lớp Animal sẽ báo lỗi vì có 2 phương thức có cùng 1 hành động là show().

Và lỗi này trong java thường gọi là lỗi phương thức bị xung đột.

Xung đột là một lớp có 2 hoặc nhiều nhiệm vụ và hành động giống nhau cùng được gọi đến mà bản thân lớp đó không biết xử lý như nào thì khi đó xảy ra lỗi.

Vậy làm thế nào giải quyết được vấn đề này?

Có 2 cách:

Cách đầu tiên chúng ta sẽ thực hiện Override lại phương thức show() vào lớp Animal.

public class Animal implements Dog, Bird {
    @Override
    public void show() {

    }
    ...
}

Cách thứ 2 chúng ta sẽ gọi trực tiếp phương thức show() từ một trong hai interface thông qua từ khóa “super”. Để thực hiện được trước hết chúng ta sẽ Override lại phương thức show() rồi thực hiện gọi trực tiếp phương thức show() từ Interface nào.

public class Animal implements Dog, Bird {

    public void show(){
        Dog.super.show();
    }
    ...
}

Ở đây tôi thực hiện gọi phương thức show() từ Interface Dog.

Dưới đây là code hoàn chỉnh của chương trình trên:

package com.company.example.freetus;

interface Dog{
    default void show(){
        System.out.println("Đây là show Dog");
    }
    void run();
}
interface Bird{
    default void show(){
        System.out.println("Đây là show Bird");
    }
    void fly();
}
public class Animal implements Dog, Bird {

    public void show(){
        Dog.super.show();
    }

    @Override
    public void run() {

    }

    @Override
    public void fly() {

    }

    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.show();
    }
}

Kết quả:

  • Đây là show Dog

Sau đây là những điểm quan trọng của phương thức mặc định (default method) trong java 8:

  • Các interface sẽ có các phương thức mặc định với việc triển khai trong java 8 và những bản java sau này
  • Các interface sẽ có thể có các phương thức tĩnh( static methods) tương tự như các phương thức tĩnh trong các lớp.
  • Các phương thức mặc định cung cấp khả năng tương thích với các interface cũ đang dùng để chúng có các phương thức mới mà không ảnh hưởng đến interface đang có. Nghĩa là chúng ta có thể thêm các phương thức mặc định mà không làm ảnh hưởng đến interface và phương thức đang có cũng như là class thực hiện việc implements từ interface đó.

Trên đây là một vài khái quát cũng như là cách sử dụng phương thức mặc định được java 8 giới thiệu để sử dụng trong các Interface.

Bài tiếp theo chúng ta sẽ tìm hiểu là Optional trong Java 8.

Cùng chuyên mục:

Cách chuyển chữ hoa thành chữ thường trong Java

Cách chuyển chữ hoa thành chữ thường trong Java

Trong bài viết này chúng ta sẽ tìm hiểu về cách chuyển đổi chữ in…

Bài tập tính tổng các số tự nhiên trong Java

Bài tập tính tổng các số tự nhiên trong Java

Các số dương 1, 2, 3, 4, ... được gọi là các số tự nhiên,…

Cách chuyển chữ thường thành chữ hoa trong Java

Cách chuyển chữ thường thành chữ hoa trong Java

Trong chuỗi có thể vừa có ký tự thường vừa có ký tự hoa, nhưng…

Cách viết hoa ký tự đầu tiên trong Java

Cách viết hoa ký tự đầu tiên trong Java

Để hiểu được bài này, các bạn cần có kiến thức căn bản về Java…

Hướng dẫn chuyển đổi giờ phút giây trong Java

Hướng dẫn chuyển đổi giờ phút giây trong Java

Để hiểu được chương trình, các bạn cần có kiến thức cơ bản về Java.…

Cách lấy thời gian hiện tại trong Java

Cách lấy thời gian hiện tại trong Java

Để hiểu được bài viết này, các bạn cần có kiến thức cơ bản sau…

Cách làm tròn số trong Java

Cách làm tròn số trong Java

Khi thực hiện tính toán, việc kết quả ra một con số thập phân dài…

Cách tìm ma trận chuyển vị trong Java

Cách tìm ma trận chuyển vị trong Java

Quá trình hoán đổi giữa hàng và cột được gọi là chuyển vị của ma…

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Để hiểu được bài này, các bạn cần có kiến thức cơ bản về mảng…

Cách nối hai mảng trong Java

Cách nối hai mảng trong Java

Mình sẽ thực hiện hai chương trình nối mảng. Chương trình thứ nhất nối hai…

Cách xóa khoảng trắng của chuỗi trong Java

Cách xóa khoảng trắng của chuỗi trong Java

Mình sẽ thực hiện hai chương trình khác nhau để các bạn có thể hiểu…

In ra tam giác bằng ký tự * và số trong Java

In ra tam giác bằng ký tự * và số trong Java

Mình sẽ giới thiệu cách để in ra các tam giác bằng ký tự *…

Tìm số lớn nhất trong mảng Java

Tìm số lớn nhất trong mảng Java

Các bạn cần tìm hiểu về mảng, cách khởi tạo và in mảng trong Java…

Tìm ước của một số nguyên trong Java

Tìm ước của một số nguyên trong Java

Trong bài viết này chúng ta sẽ tìm hiểu cách tìm tất cả các ước…

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số đối xứng trong Java

Cách kiểm tra số đối xứng trong Java

Trong bài viết này chúng ta sẽ kiểm tra một số có phải là số…

Đảo ngược một số trong Java

Đảo ngược một số trong Java

Mình sẽ giới thiệu các bạn cách đảo ngược một số sử dụng vòng lặp…

Tìm bội chung nhỏ nhất trong Java

Tìm bội chung nhỏ nhất trong Java

Mình sẽ sử dụng hai cách khác nhau để tìm BCNN. Cách thứ nhất mình…

Cách hoán đổi hai số trong Java

Cách hoán đổi hai số trong Java

Trong phần này mình sẽ sử dụng một biến tạm temp() làm biến trung gian…

Các phương thức xử lý Object trong Java

Các phương thức xử lý Object trong Java

Trong bài viết này mình sẽ giới thiệu các phương thức xử lý Object trong…

Top