N.B. вы должны иметь четкие знания как о примитивных, так и о классовых типах данных. В конце серии из двух частей вы сможете читать и создавать универсальные коды, подобные приведенному ниже.

Или вы можете просто перейти к Части 2 для Конца игры😉😉😉

class Planet<T,S,U>{
}
//instantiating a generic class
Planet<Land,Water<Ocean,Fresh>,Air<Wind,Cloud>> = new Planet<>();

Раньше я выкладывал в Интернет статью, в которой подробно описывалась часть Официального примера кода Android по варианту использования… в нем используется слишком много Generics - это для тех, кто не совсем доволен Generics. Сама загадка начинается с ее определения.

АННОТАЦИЯ ВИДОВ !!! ИЛИ ТИПЫ ШАБЛОНОВ !!!

поскольку он называется Generics class или Generic method, все дело в полях и аргументе типы данных !!! Остальное избыточно как восход солнца.

Но какие проблемы породили дженерики? вы можете спросить.

Generics, как упомянуто выше, является шаблоном для типа данных !!! На ранних уроках алгоритмов мы использовали тип данных String ... но реальные проблемы - это не только строки. Это означает, что мы должны переконфигурировать наши алгоритмы, чтобы разрешить использование нестроковых данных.

public class MyNonGenericClass {
    Object data1;
    Object data2;
    public Object getData1() {
        return data1;
    }
    public Object getData2() {
        return data2;
    }
      public static void main(String[] args) {
        MyNonGenericClass nonGenericClass = new MyNonGenericClass("dart",new Integer(12));
        Integer result2 = (Integer)nonGenericClass.data2;
        String result1 = (String)nonGenericClass.data1;
               //no compile time error but runtime error🧐
	Integer resultErr = (Integer)nonGenericClass.data1;
	
    }
}

Один из способов заключался в том, чтобы заставить класс принимать тип объекта, поскольку каждый объект является подклассом класса объекта, а затем после вычисления результат приводится к предполагаемому типу.

Это может вызвать скрытие времени компиляции и скачок времени выполнения 🐅 ошибку.

У класса, который принимает наши входные данные, нет инструментов для проверки совместимости типов (он видит только Object, и все является типом Object)… мы можем вставить объект String, затем попытаться преобразовать результат в Integer, но компилятор не может жаловаться! !! что приведет к ужасной ошибке во время выполнения.

Дженерики спешат на помощь:

Имеет шаблон по классу и обеспечивает тип данных о создании объекта.

Он использует типы параметров с разделителями, которые будут использоваться для типов данных полей или аргументов, ожидающих назначения💦… когда вы создаете объект этого класса, вам необходимо определить тип данных в этих угловых скобках.

Class Air<T>{
     T unitMass;
}

Если у вас есть несколько переменных для работы в качестве универсальных, добавьте другие типы параметров, разделенные запятыми, известные как переменные типа.

class Air<T,S,U,V>{/* rest of the code*/}

Чтобы создать конкретный объект Air, нам нужно назначить тип данных, который будет использоваться переменной unitMass, которую мы выбрали тип String для замены универсального типа, или вы можете выбрать любой другой конкретный тип (примитивные типы не допускаются !! !)

// we have created Air Object with an intention of making
Air<String> myAir  = new Air<String>();

тип данных T изменяется на тип String.

после Java 7 избыточность ‹String› правой части ключевого слова new вычитается в ромбовидный оператор. Эта техника называется логическим выводом.

Air<String> myAir  = new Air<>();

есть две краткие категории универсальных шаблонов: Generics классов и Method Generics.

Раньше мы хорошо владели универсальным классом, давайте перейдем к универсальным методам.

Это шаблон типа данных, как и наши общие классы, но шаблон ограничен только параметрами метода.

public <E,S> E getElements(E element, S set){
    //computation
    return element;
}

параметры типа - E и S, записанные в угловых скобках перед типом возвращаемого значения, тип возвращаемого значения - E.

Параметры ограниченного типа

Далее мы ограничиваем тип конкретного значения, которое мы заменяем на общий тип, называемого параметрами ограниченного типа, но я называю его параметрами расистского типа, потому что это вроде как.

Это похоже на бар, куда допускаются только белые мужчины, или теннисный клуб, куда допускаются только члены xyz Bank.

Вы хотите, чтобы тип поля или тип аргумента был подклассом некоторого класса, абстрактного класса или реализующего определенный интерфейс. Если это не расизм, то что нет🤣.

public <T extends Cat> void runOrJump(T t){
}

поле должно быть семейством типа Cat, больше ничего не разрешено.

Множественные границы:

Ограничивает тип класса подклассом одного класса и реализует несколько интерфейсов, что означает ограничение множеством типов данных.

На собеседовании, когда вас не хотят нанимать, требования могут быть пилотом, морским пехотинцем, выпускником Массачусетского технологического института, свободно владеющим 5 языками, нырял с аквалангом в Марианской впадине. Это пример множественной привязки.

Любопытный случай наследования на родителях

В объектно-ориентированном программировании отношения «есть-а» - это отношения родитель-потомок; например, String - это объект (поскольку каждый класс является подклассом класса Object) или Male - это Human (класс Male является подклассом класса Human), поэтому мы можем присвоить любой объект ссылочному типу родительского класса.

Male person = "Adamu";
Human aHuman = person; // compiles fine

НО для общего класса

Planet<Human> planetWithHuman;

а также

Planet<Male> planetWithMale;

НЕ в каких-либо отношениях

поначалу может показаться нелогичным, но мы не можем создать отношения подтипов на основе общих типов, то есть мы не можем иметь отношения «есть-а» между двумя классами только потому, что оба класса имеют поля с одинаковым типом данных, теперь, что в интуитивном…. Я бы надеюсь.

Следите за обновлениями части 2. хлопайте, комментируйте и делитесь.