JavaRush /Blog Java /Random-VI /Các phương thức mặc định trong giao diện

Các phương thức mặc định trong giao diện

Xuất bản trong nhóm
Mỗi phiên bản Java mới đều khác với các phiên bản trước. Đây là ví dụ về những thay đổi so với tài liệu mà chúng tôi đã đề cập: Trước Java 5, không có enumngôn ngữ nào.
Các phương thức mặc định trong giao diện - 1
Tương tự như vậy, Java 8 có sự khác biệt đáng kể so với Java 7. Hầu hết các bài giảng của chúng tôi được viết bằng phiên bản thứ 7 của ngôn ngữ này, nhưng tất nhiên, chúng tôi sẽ không bỏ qua những đổi mới quan trọng. Vì chúng ta đang nói về giao diện trong bài giảng này nên hãy xem xét một bản cập nhật - các phương thức mặc định trong giao diện . Bạn đã biết rằng một giao diện không triển khai các tệp . Nhiệm vụ của nó là mô tả hành vi mà tất cả các đối tượng thực hiện nó phải có . Nhưng khá thường xuyên, các nhà phát triển gặp phải tình huống trong đó việc triển khai một phương thức trong tất cả các lớp là như nhau. Hãy xem ví dụ về chiếc xe cũ của chúng tôi:
public interface Car {

   public void gas();

   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class Truck implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class F1Car implements Car {
   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}
Bạn nghĩ vấn đề chính của mã này là gì? Bạn có thể nhận thấy rằng chúng tôi đã viết rất nhiều mã giống nhau! Vấn đề này thường gặp trong lập trình và nên tránh. Một điều nữa là trước khi phát hành Java 8 không có tùy chọn giải pháp đặc biệt nào. Khi phiên bản này xuất hiện, có thể xác định các phương thức mặc định và triển khai chúng ngay bên trong giao diện! Đây là cách nó được thực hiện:
public interface Car {

   public default void gas() {
       System.out.println("Газ!");
   }

   public default void brake() {
       System.out.println("Тормоз!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
Giờ đây, các phương thức gas()brake(), giống nhau cho tất cả các máy, đã được đưa vào giao diện và không cần mã trùng lặp. Hơn nữa, các phương thức đều có sẵn trong mỗi lớp!
public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
Điều gì sẽ xảy ra nếu có 100 lớp có một phương thức gas()nhưng chỉ có 99 lớp có hành vi tương tự? Điều này làm hỏng mọi thứ và phương thức mặc định sẽ không hoạt động trong trường hợp này? Tất nhiên là không :) Các phương thức giao diện mặc định có thể bị ghi đè.
public class UnusualCar implements Car {
   @Override
   public void gas() {
       System.out.println("Эта машина газует по-другому!");
   }

   @Override
   public void brake() {
       System.out.println("Эта машина тормозит по-другому!");
   }
}
Tất cả 99 loại máy khác sẽ triển khai phương thức mặc định và lớp UnusualCar- ngoại lệ - sẽ không làm hỏng bức tranh tổng thể và sẽ bình tĩnh xác định hành vi của nó. Đa kế thừa trong giao diện Như bạn đã biết, không có đa kế thừa trong Java. Có nhiều lý do cho việc này, chúng ta sẽ xem xét chúng một cách chi tiết trong một bài giảng riêng. Trong các ngôn ngữ khác, chẳng hạn như trong C++, thì ngược lại. Nếu không có nhiều kế thừa, một vấn đề nghiêm trọng sẽ nảy sinh: cùng một đối tượng có thể có một số đặc điểm và "hành vi" khác nhau. Một ví dụ từ cuộc sống: đối với cha mẹ chúng ta là con cái, đối với giáo viên chúng ta là học sinh, đối với bác sĩ chúng ta là bệnh nhân. Trong cuộc sống, chúng ta xuất hiện với những vai trò khác nhau và do đó, cư xử khác nhau: rõ ràng chúng ta sẽ nói chuyện với giáo viên khác với bạn bè thân thiết. Hãy thử dịch tình huống này thành mã. Hãy tưởng tượng rằng chúng ta có hai lớp: Pond và Aviary. Đối với một cái ao, bạn cần những con chim biết bơi, và đối với một chuồng chim, bạn cần những con chim biết bay. Để làm điều này, chúng tôi đã tạo hai lớp cơ sở - FlyingBirdWaterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
Theo đó, chúng tôi sẽ gửi đến chuồng chim những con chim có lớp được kế thừa từ FlyingBird, và gửi đến ao - những con thuộc lớp Waterfowl. Mọi thứ có vẻ đơn giản. Nhưng chúng ta sẽ làm gì nếu cần xác định con vịt ở đâu đó? Cô ấy vừa bơi vừa bay. Nhưng chúng tôi không có nhiều kế thừa. May mắn thay, Java cung cấp nhiều triển khai giao diện. Nếu một lớp không thể kế thừa từ nhiều lớp cha thì việc triển khai nhiều giao diện thật dễ dàng! FlyingBirdCon vịt của chúng ta có thể vừa bay vừa bơi :) Chỉ cần sử dụng các giao diện thay vì các lớp là đủ Waterfowlđể đạt được kết quả mong muốn.
public class Duck implements FlyingBird, Waterfowl {

   //методы обоих интерфейсов легко объединяются в одном классе

   @Override
   public void fly() {
       System.out.println("Летим!");
   }

   @Override
   public void swim() {

       System.out.println("Плывем!");
   }
}
Nhờ đó, chương trình của chúng tôi duy trì được khả năng quản lý lớp linh hoạt và kết hợp với việc triển khai các phương thức mặc định, khả năng xác định hành vi của các đối tượng của chúng tôi gần như trở nên vô hạn! :)
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION