Всяка нова version на Java се различава от предишните. Като пример за такава промяна от материала, който покрихме, езикът не е имал
Точно така, Java 8 е забележимо различна от Java 7. Разбира се, няма да пренебрегнем важни нововъведения. Тъй като в този урок говорим за интерфейси, нека разгледаме една актуализация на езика: методи по подразбиране в интерфейси . Вече знаете, че интерфейсът не прилага поведение . Целта му е да опише Howво поведение трябва да съществува във всички обекти, които имплементират интерфейса . Но разработчиците често се сблъскват със ситуации, при които внедряването на даден метод е еднакво във всички класове. Нека да разгледаме нашия пример със стара кола:
enums
преди Java 5.
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class Truck implements Car {
@Override
public void go() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void go() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
Какъв според вас е основният проблем с този code? Вероятно сте забелязали, че написахме куп дублиран code! Това е често срещан проблем при програмирането и трябва да се избягва. Друг е въпросът, че нямаше конкретни решения преди пускането на Java 8. Когато тази version излезе, стана възможно да се дефинират методи по подразбиране и да се внедрят направо в интерфейс! Ето How да го направите:
public interface Car {
public default void gas() {
System.out.println("Gas!");
}
public default void brake() {
System.out.println("Brake!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
Сега методите gas()
и brake()
, които бяха еднакви за всички автомобor, бяха преместени в интерфейса, елиминирайки необходимостта от дублиран code. И методите са налични във всеки един от класовете!
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();
}
}
Ами ако има 100 класа с gas()
метод, но само 99 от тях трябва да имат същото поведение? Това разваля ли всичко? Методът по подразбиране няма ли да работи в този случай? Разбира се, че не :) Методите на интерфейса по подразбиране могат да бъдат заменени.
public class UnusualCar implements Car {
@Override
public void go() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car slows down differently!");
}
}
Всички останали 99 типа автомобor ще използват метода по подразбиране, докатоUnusualCar
клас е изключение. Без да разваля голямата картина, то спокойно ще определи собственото си поведение. Множествено наследяване в интерфейсите. Както вече знаете, в Java няма множествено наследяване. Има много причини за това. Ще ги разгледаме подробно в отделен урок. В други езици, като C++, ситуацията е обратна. Никое множествено наследяване не представлява сериозно предизвикателство, тъй като един и същ обект може да има няколко различни характеристики и поведение. Например, ние сме деца за нашите родители, ученици за нашите учители и пациенти за нашите лекари. В реалния живот изпълняваме различни роли и съответно се държим по различен начин: очевидно взаимодействаме с учителите по различен начин, отколкото с близки приятели. Нека се опитаме да преведем тази ситуация в code. Нека си представим, че имаме два класа: езерце и волиера. Езерото се нуждае от плуващи птици, докато волиерата се нуждае от летящи. За да представим това, създадохме два базови класа:FlyingBird
и Waterfowl
.
public class Waterfowl {
}
public class FlyingBird {
}
Съответно, ние ще изпратим птици, които наследяват FlyingBird
във волиерата, докато тези, които произлизат от, Waterfowl
ще отидат в езерото. Всичко изглежда просто. Но Howво трябва да направим, ако трябва да дефинираме патица някъде? Патиците и плуват, и летят. Но ние нямаме множествено наследяване. За щастие Java поддържа множество реализации на интерфейси. Ако един клас не може да наследява множество родители, прилагането на множество интерфейси е лесно! Нашата патица може да бъде Howто летяща, така и плуваща птица :) За да постигнем желания резултат, всичко, което трябва да направим, е да създадем FlyingBird
интерфейси, Waterfowl
а не класове.
public class Duck implements FlyingBird, Waterfowl {
// Methods of both interfaces combine easily into one class
@Override
public void fly() {
System.out.println("Flying!");
}
@Override
public void swim() {
System.out.println("Swimming!");
}
}
Това означава, че нашата програма запазва възможността за гъвкаво управление на класовете. Когато комбинираме това с методите по подразбиране, способността ни да определяме поведението на обектите става почти неограничена! :)
GO TO FULL VERSION