Назад Зміст Вперед

7.7. Covariant Returns

У Java 5, є функція, яка повертає коваріантний тип. До Java5, ми не могли змінювати тип повертання перевизначеного методу. Це означає, що якщо ви перевизначите метод в підкласі, то необхідно зворотне приведення його до типу підкласу.

Коваріантний тип повернення в Java, дозволяє звузити тип повертання перевизначеного методу. Ця функція допоможе уникнути кастингу на стороні клієнта. Це дозволяє програмісту запрограмувати без необхідності перевірки типу. Коваріантний тип повертається завжди, працює тільки для непримітивних типів повернення.

В системі типів мови програмування, є конструктори таких типів:
  • коваріантні — якщо конструктор зберігає порядок типів (від похідних до базового);
  • контраваріантні — якщо конструктор змінює порядок типів на протилежний;
  • біваріантні — якщо прямий і обернений порядок є справедливими одночасно.
  • інваріантні чи неваріантні — якщо конструктор не підпадає під попередні варіанти.
Наприклад, якщо типи Cat та Dog наслідують тип Animal, конструктором масивів з типу Animal утворимо тип Animal[] ("масив звірів"). Ми можемо використовувати його:
  • коваріантно: вважаючи що Cat[] є представником Animal[]
  • контраваріантно: вважаючи що Animal[] є представником Cat[]
  • інваріантно: вважаючи що Animal[] не є представником Cat[] а також Cat[] не є представником Animal[].
Розглянемо сценарій, де у нас є два типи: виробник мобільних телефонів і пральна машина. На підставі вимог замовника, якщо користувач хоче купити мобільний телефон метод перевизначення поверне об'єкт мобільний телефон. Тут метод Get Тип продукту поверне мобільний - об'єкт телефон замість цільового продукту (мобільний телефон реалізує інтерфейс продукту). Тобто повертає об'єкт підкласу замість суперкласу. Точно так -метод клон в Mobile Phone класу поверне об'єкт Мобільний телефон замість об'єкта класу Object. Те ж саме правило відноситься і до пральної машини класу.


Product.Java

public interface Product {
 public void makeProduct(String productName, String ProductOwner, int IMEINo);
}

MobilePhone.Java

public class MobilePhone implements Product, Cloneable {

 String _productName;
 String _ownerName;
 int _IMEINo;
 MobilePhone _clonedProduct;

 @Override
 public void makeProduct(String productName, String ownerName, int IMEINo) {
  // TODO Auto-generated method stub
  _productName = productName;
  _ownerName = ownerName;
  _IMEINo = IMEINo;
 }

 protected MobilePhone clone() throws CloneNotSupportedException {
  _clonedProduct = (MobilePhone) super.clone();
  return _clonedProduct;
  // return super.clone();
 }
}

WasingMachine.java

public class WasingMachine implements Product {

 String _productName;
 String _ownerName;
 int _modelNo;

 @Override
 public void makeProduct(String productName, String ownerName, int modelNo) {
  // TODO Auto-generated method stub
  _productName = productName;
  _ownerName = ownerName;
  _modelNo = modelNo;
 }

}

Manufacture.java

public interface Manufacture {

 public Product getProductType();

}

Apple.java

public class Apple implements Manufacture {

 @Override
 public MobilePhone getProductType() {
  // TODO Auto-generated method stub
  return new MobilePhone();
 }

}

Samsung.java

public class Samsung implements Manufacture {

 @Override
 public WasingMachine getProductType() {
  // TODO Auto-generated method stub
  return new WasingMachine();
 }

}

ManufactureImpl.java

public class ManufactureImpl {

 /**
  * @param args
  * @throws CloneNotSupportedException
  */
 public static void main(String[] args) throws CloneNotSupportedException {
  // TODO Auto-generated method stub

  Apple s1 = new Apple();
  MobilePhone b1 = s1.getProductType();
  b1.makeProduct("Iphone5S", "XXXX", 1234);
  MobilePhone b2 = b1.clone();
  b2._IMEINo = 6789;
  System.out.println("IMEI Number Of Phone1->" + b1._IMEINo);
  System.out.println("IMEI Number Of Phone2->" + b2._IMEINo);
  Samsung f1=new Samsung();
  WasingMachine c1=f1.getProductType();
  c1.makeProduct("samsungWashingMachine","XYZ", 2014);
  System.out.println("Owner Name Of WasingMachine->" + c1._ownerName);
 }

}
Джерело
2. Covariant Returns.

.