Собеседование по java

Введение

В мы оперируем такими понятиями, как и класса — объект.
— это описание методов и свойств , а — это уже инстанс класса, сущность.

Можно сказать, что класс — это как техническое описание прибора, купленного вами в электронном дискаунтере.
То, каким он должен быть: материал, форма, список составляющих и т.д.

Объект же — это сам прибор, со своим уникальным набором свойств.

Например, у него может быть цвет, материал изготовления, форма, он может состоять также из более мелких узлов(вспомогательных приборов) и т.д

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

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

Для примера можно взять обычный массив. Массив, являясь объектом, может сохранять(добавлять) элемент, удалять и т.д. Это его поведение.
В то же время, у массива есть еще и длина — это уже свойство объекта. Добавляя или удаляя элементы вы изменяете и длину массива.

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

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

В качестве примера, рассмотрим метод, который печатает в консоль число, которое передается аргументом в этот метод:

public class Printer {
    void print(int n) {
        System.out.println(n);
    }
}

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

Т.е такой метод не связан с объектом класса, он связан только с классом, в котором объявлен.

А раз он не связан с объектом, то и объект, для использования этого метода, не нужен.
Нужен только класс, в котором объявлен этот метод.

И вот тут как раз в дело вступает модификатор .

Указав модификатор у поля или метода класса, вы тем самым говорите: это поле или метод принадлежат именно классу.

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

Грубо говоря, если вы объявляете поле класса статическим, то вы как бы расшариваете это поле для всех объектов.

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

public class Counter {

private int count;

public static void printCount() {
   System.out.println(count); //compile time error
 }
}

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

У вас должен возникнуть вопрос: «А где вообще можно использовать ?»

Как работают параметризованные конструкторы

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

Важно: Класс может иметь несколько различных конструкторов. Они (кстати, как и методы) отличаются между собой количеством, типом и порядком следования параметров

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

Например, конструкторы ниже являются разными и вполне могут существовать в одном классе и иметь разную логику:

Заметьте, что конструкторы ниже для компилятора одинаковы и вызовут ошибку при запуске программы (тип, количество и порядок следования параметров идентичны):

Разберём пример применения параметризованного конструктора класса Cat с добавленным полем имени:

Как видно, в этих конструкторах очень много кода повторяется, что в целом не очень удобно и повышает вероятность ошибки: ведь если нам потребуется поменять один конструктор, необходимо будет не забыть внести изменения в другой.

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

Применять ключевое слово this для вызова другого конструктора очень удобно — нужно лишь один раз написать общий код для конструирования объекта.

Важно: вызов другого конструктора всегда должен стоять первой строкой в конструкторе. Вот пример оптимизации кода первого из конструкторов:

Вот пример оптимизации кода первого из конструкторов:

Обратите внимание: Несколько слов насчёт ключевого слова this. Синтаксис языка Java не запрещает использовать имена параметров или локальных переменных, совпадающие с именами переменных экземпляра (класса)

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

Приведённый ниже пример конструктора класса Cat показывает, каким образом лучше выполнять присваивание переданных в конструктор параметров переменным класса:

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

34. Назовите основные методы класса Object?

  • — возвращает хеш-код объекта.

  • — сравнивает объекты.

  • — возвращает строковое представление объекта.

  • — возвращает в рантайме класс данного объекта.

  • — клонирование объекта

  • — просыпается один поток, который ждет на «мониторе» данного объекта.

  • — просыпаются все потоки, которые ждут на «мониторе» данного объекта.

  • — поток переходит в режим ожидания в
    течение указанного времени.

  • — приводит данный поток в ожидание, пока другой поток
    не вызовет или методы для этого объекта.

  • — приводит данный поток в ожидание,
    пока другой поток не вызовет или для этого метода, или пока не истечет указанный промежуток времени.

  • — вызывается сборщиком мусора, когда garbage collector определил,
    что ссылок на объект больше нет.

Модификатор сигнализирует о том, что метод реализован в платформо-зависимом коде, часто на языке С.

Инициализаторы

Давайте еще раз
внимательно посмотрим на пример нашего класса и зададимся вопросом: что делает
первый конструктор без аргументов? Фактически, он выполняет начальную
инициализацию полей класса Point. Именно поэтому мы его отдельно
вызываем во втором конструкторе. Но это не лучший ход. В классах языка Java можно создавать
специальный блок, который так и называется – инициализатор. Он
автоматически выполняется один раз при создании объекта до вызова конструкторов.
Записывается инициализатор следующим образом:

class Point {
    int x, y;
    int color;
 
    // инициализатор
    {
        x = -1; y = -1;
        color = 100;
    }
 
    // конструкторы
    Point() {
    }
 
    Point(int x, int y) {
        this.x = x; this.y = y;
    }
}

Смотрите, здесь
в отдельном блоке задаются начальные значения всех переменных класса, а затем,
отдельно вызываются конструкторы. При этом, вызывать первый конструктор из
второго уже нет необходимости – данные уже инициализированы указанными
значениями. Это очень удобно.

Глядя на первый
конструктор, в котором нет никакой реализации, возникает соблазн его попросту
убрать из класса Point. Давайте попробуем это сделать и
посмотрим к чему это приведет:

class Point {
    int x, y;
    int color;
 
    // инициализатор
    {
        x = -1; y = -1;
        color = 100;
    }
 
    // конструкторы
    Point(int x, int y) {
        this.x = x; this.y = y;
    }
}

При запуске
программы компилятор выдал ошибку, что невозможно создать объект при вызове
конструктора без аргументов. Вместе с тем, нам бы хотелось иметь такую
функциональность – создавать экземпляры без указания конкретных координат.
Именно для этого следует иметь первый конструктор без аргументов.

Путь кодера

Подвиг 1. Объявить класс Rect для
представления прямоугольника, в котором хранятся две координаты: верхнего
левого и правого нижнего углов. Реализовать три конструктора: первый – без
аргументов; второй с четырьмя аргументами для двух координат; третий – с
четырьмя аргументами (координата левого верхнего угла, ширина и высота).
Создать несколько экземпляров с вызовом разных конструкторов и выводом значений
полей в консоль.

Подвиг 2. Объявить класс Triangle, хранящий три
координаты вершин. Координаты представить в виде ссылок на класс Point, который
рассмотрен на этом занятии. Реализовать два конструктора: без аргументов и с
шестью аргументами (по два на каждую координату). Создать два объекта, вывести
координаты вершин по каждому объекту в консоль.

Подвиг 3. Объявить класс Line для
представления линии на плоскости, хранящий две координаты: начало и конец
линии. Создать два объекта этого класса и в функции main() определить:
пересекаются ли эти две линии.

Видео по теме

#11 Концепция объектно-ориентированного программирования (ООП)

#12 Классы и создание объектов классов

#13 Конструкторы, ключевое слово this, инициализаторы

#14 Методы класса, сеттеры и геттеры, public, private, protected

#15 Пакеты, модификаторы конструкторов и классов

#16 Ключевые слова static и final

#17 Внутренние и вложенные классы

#18 Как делается наследование классов

#19 Ключевое слово super, оператор instanceof

#20 Модификаторы private и protected, переопределение методов, полиморфизм

#21 Абстрактные классы и методы

#22 Интерфейсы — объявление и применение

#23 Интерфейсы — приватные, статические и дефолтные методы, наследование интерфейсов

#24 Анонимные внутренние классы

#25 Перечисления (enum)

#26 Обобщения классов (Generics)

#27 Ограничения типов, метасимвольные аргументы, обобщенные методы и конструкторы

#28 Обобщенные интерфейсы, наследование обобщенных классов

Методы класса

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

Метод класса — это блок кода, состоящий из ряда инструкций, который можно вызывать по его имени. Он обязательно содержит возвращаемый тип, название, аргументы и тело метода.

Синтаксис метода в Java:

Строка возвращаемыйТип показывает, какого типа данные вернёт метод. Например, если в качестве возвращаемого типа мы поставим тип String, то метод должен будет вернуть строку, а если int — целое число.

Чтобы вернуть значение из метода, используется специальное слово return. Если мы хотим, чтобы метод ничего не возвращал, то вместо возвращаемого типа нужно использовать специальное слово void.

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

Для примера напишем простейший метод с именем sum (пока что не в нашем классе Pet), который складывает два переданных числа и возвращает их результат:

Возвращаемый тип метода int, он указан перед именем sum. Далее идут два аргумента a и b, у обоих также указан тип int

Важно помнить, что возвращаемый тип и тип переменных не обязательно должны совпадать

Аргументы метода работают как обычные переменные — за пределами метода к ним никак нельзя получить доступ. Внутри метода мы складываем значения из переменных a и b, записываем полученное значение в переменную c. После этого мы возвращаем значение переменной c — только оно доступно вне метода.

Вот пример:

Мы передали в метод sum два значения 1 и 2, а на выходе получили результат их сложения 3. Также можно создать метод, который принимает значение типа String, а возвращает длину этой строки:

В этом случае у нас возвращаемый типа int, а параметр str — типа String.

Попробуем использовать этот метод:

Также мы можем создать метод, который ничего не возвращает, а просто печатает переданное слово в консоль:

Либо метод, который ничего не принимает на вход, а просто печатает «Привет!»:

В методах, которые ничего не возвращают, слово return можно опустить.

Обратите внимание, что return полностью прекращает выполнение метода:

Теперь попробуем вызвать этот метод, передав в него число 3:

В этом случае мы ничего не увидим в консоли, так как 3 меньше 5, а значит, отработает блок if и произойдёт выход из метода с помощью слова return.

Но если передадим 6, увидим нашу надпись «Привет!»:

Конструктор копирования Java

Конструктор копирования Java принимает объект того же класса в качестве аргумента и создает его копию. Иногда нам нужна копия другого объекта, чтобы выполнить некоторую обработку. Мы можем сделать это следующими способами:

  1. реализовать клонирование
  2. предоставление служебного метода для глубокого копирования объекта.
  3. Наличие конструктора копирования

Теперь давайте посмотрим, как написать конструктор копирования. Предположим, у нас есть класс , как показано ниже.

package com.journaldev.constructor;

import java.util.ArrayList;
import java.util.List;

public class Fruits {

	private List fruitsList;

	public List getFruitsList() {
		return fruitsList;
	}

	public void setFruitsList(List fruitsList) {
		this.fruitsList = fruitsList;
	}

	public Fruits(List fl) {
		this.fruitsList = fl;
	}
	
	public Fruits(Fruits fr) {
		List fl = new ArrayList<>();
		for (String f : fr.getFruitsList()) {
			fl.add(f);
		}
		this.fruitsList = fl;
	}
}

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

package com.journaldev.constructor;

import java.util.ArrayList;
import java.util.List;

public class CopyConstructorTest {

	public static void main(String[] args) {
		List fl = new ArrayList<>();
		fl.add("Mango");
		fl.add("Orange");

		Fruits fr = new Fruits(fl);

		System.out.println(fr.getFruitsList());

		Fruits frCopy = fr;
		frCopy.getFruitsList().add("Apple");

		System.out.println(fr.getFruitsList());

		frCopy = new Fruits(fr);
		frCopy.getFruitsList().add("Banana");
		System.out.println(fr.getFruitsList());
		System.out.println(frCopy.getFruitsList());

	}

}

Результатом приведенной выше программы является:

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

Это все для конструктора в java.

Сборка мусора

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

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

Переменная Область действия

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

6.1. Переменные экземпляра и класса

Переменные экземпляра и класса не требуют от нас их инициализации. Как только мы объявляем эти переменные, им присваивается значение по умолчанию следующим образом:

Теперь давайте попробуем определить некоторые переменные, связанные с экземплярами и классами, и проверить, имеют ли они значение по умолчанию или нет:

@Test
public void whenValuesAreNotInitialized_thenUserNameAndIdReturnDefault() {
    User user = new User();
 
    assertThat(user.getName()).isNull();
    assertThat(user.getId() == 0);
}

6.2. Локальные переменные

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

Например, следующий код генерирует ошибку компилятора:

public void print(){
    int i;
    System.out.println(i);
}

Абстрактные классы

Последнее обновление: 20.04.2018

Кроме обычных классов в Java есть абстрактные классы. Абстрактный класс похож на обычный класс.
В абстрактном классе также можно определить поля и методы, но в то же время нельзя создать объект или экземпляр абстрактного класса.
Абстрактные классы призваны предоставлять базовый функционал для классов-наследников. А производные классы уже реализуют этот функционал.

При определении абстрактных классов используется ключевое слово abstract:

public abstract class Human{

    private String name;
	
	public String getName() { return name; }
}

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

Human h = new Human();

Кроме обычных методов абстрактный класс может содержать абстрактные методы. Такие методы определяются с помощью
ключевого слова и не имеют никакой реализации:

public abstract void display();

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

Зачем нужны абстрактные классы? Допустим, мы делаем программу для обслуживания банковских операций и определяем в ней три класса:
Person, который описывает человека, Employee, который описывает банковского служащего, и класс Client, который представляет клиента банка.
Очевидно, что классы Employee и Client будут производными от класса Person, так как оба класса имеют некоторые общие поля и методы. И так как
все объекты будут представлять либо сотрудника, либо клиента банка, то напрямую мы от класса Person создавать объекты не будем.
Поэтому имеет смысл сделать его абстрактным.

public class Program{
     
	public static void main(String[] args) {
			
		Employee sam = new Employee("Sam", "Leman Brothers");
		sam.display();
		Client bob = new Client("Bob", "Leman Brothers");
		bob.display();
	}
}
abstract class Person {
    
    private String name;
	
    public String getName() { return name; }
   
    public Person(String name){
    
        this.name=name;
    }
 
    public abstract void display();
}

class Employee extends Person{

    private String bank;
    
    public Employee(String name, String company) {
    
        super(name);
        this.bank = company;
    }
    
    public void display(){
        
        System.out.printf("Employee Name: %s \t Bank: %s \n", super.getName(), bank);
    }
}

class Client extends Person
{
    private String bank;
    
    public Client(String name, String company) {
    
        super(name);
        this.bank = company;
    }
    
    public void display(){
        
        System.out.printf("Client Name: %s \t Bank: %s \n", super.getName(), bank);
    }
}

Другим хрестоматийным примером является система геометрических фигур. В реальности не существует геометрической фигуры как таковой. Есть круг, прямоугольник,
квадрат, но просто фигуры нет. Однако же и круг, и прямоугольник имеют что-то общее и являются фигурами:

// абстрактный класс фигуры
abstract class Figure{
    
    float x; // x-координата точки
    float y; // y-координата точки
 
    Figure(float x, float y){
        
        this.x=x;
        this.y=y;
    }
    // абстрактный метод для получения периметра
    public abstract float getPerimeter();
    // абстрактный метод для получения площади
    public abstract float getArea();
}
// производный класс прямоугольника
class Rectangle extends Figure
{
    private float width;
    private float height;
 
    // конструктор с обращением к конструктору класса Figure
    Rectangle(float x, float y, float width, float height){
        
        super(x,y);
        this.width = width;
        this.height = height;
    }
	
    public float getPerimeter(){
        
        return width * 2 + height * 2;
    }
	
    public float getArea(){
        
        return width * height;
    }
}

НазадВперед

Параметры

Конструктор может принимать параметры, которые потом используются для инициализации внутреннего состояния (полей) вновь созданного объекта:

public class Employee {

    private String firstName = null;
    private String lastName  = null;
    private int    birthYear = 0;


    public Employee(String first,
        String last,
        int    year   ) {

        firstName = first;
        lastName  = last;
        birthYear = year;
    }
    

}

В этом примере объявлены 3 параметра: первый, последний и год. Внутри тела значения этих трех параметров присваиваются полям объекта Employee.

Разрывы строки на Java после каждого параметра являются необязательными. Компилятор здесь игнорирует разрывы строк. Вы также можете написать объявление параметра в одну строку, если хотите, например:

public Employee(String first, String last, int year ) {
    firstName = first;
    lastName  = last;
    birthYear = year;
}

Чтобы вызвать этот конструктор, который принимает три параметра, вы должны создать экземпляр объекта Employee следующим образом:

Employee employee = new Employee("Jack", "Daniels", 2000);

Параметры передаются конструктору в скобках после имени класса справа от знака равенства. Затем объект создается, и конструктор выполняется. После выполнения описанного выше конструктора поля, инициализированные им, будут иметь значения параметров, передаваемых ему.

Параметр конструктора может иметь то же имя, что и поле. В этом случае у компилятора возникают проблемы, зная, на что вы ссылаетесь. По умолчанию, если параметр (или локальная переменная) имеет то же имя, что и поле в том же классе, параметр (или локальная переменная) «затеняет» поле. Посмотрите на этот пример:

public class Employee {

    private String firstName = null;
    private String lastName  = null;
    private int    birthYear = 0;


    public Employee(String firstName,
        String lastName,
        int    birthYear ) {

        firstName = firstName;
        lastName  = lastName;
        birthYear = birthYear;
    }
    
}

Внутри конструктора класса Employee идентификаторы firstName, lastName и birthYear теперь ссылаются на параметры конструктора, а не на поля Employee с одинаковыми именами. Таким образом, конструктор теперь просто устанавливает параметры, равные им самим. Поля Сотрудника никогда не инициализируются.

Чтобы сообщить компилятору, что вы имеете в виду поля класса Employee, а не параметры, поместите ключевое слово this и точку перед именем поля:

public class Employee {

    private String firstName = null;
    private String lastName  = null;
    private int    birthYear = 0;


    public Employee(String firstName,
        String lastName,
        int    birthYear ) {

        this.firstName = firstName;
        this.lastName  = lastName;
        this.birthYear = birthYear;
    }
    
}

Теперь поля Employee правильно инициализируются внутри конструктора.

Конструкторы

Конструкторы вызываются для создания объектов. Они похожи на классы, но они не имеют возвращаемого значения (даже
void ), и они имеют то же самое имя, что и сам класс.

Пример конструктора для нашего класса
Goblin :

Java

public Goblin(int initialMoney, double initialHealth) {
money = initialMoney;
health = initialHealth;
}

1
2
3
4

publicGoblin(intinitialMoney,doubleinitialHealth){

money=initialMoney;

health=initialHealth;

}

Теперь чтобы создать экземпляр класса
Goblin  нужно вызвать конструктор с ключевым словом
new :

Java

Goblin myGoblin = new Goblin(8, 100.0);

1 Goblin myGoblin=newGoblin(8,100.0);

Эта конструкция создаст экземпляр класса
Goblin  с помощью нашего конструктора и присвоит ссылку на этот класс переменной
myGoblin.

С помощью перегрузки конструкторов можно создать несколько конструкторов. Главное чтобы они имели различное количество или тип параметров:

Goblin.java

Java

class Goblin {
private int money;
double health;
protected int diamonds = 10;
public String name;

// Конструктор без параметров.
public Goblin() {
}

// Конструктор с двумя параметрами
public Goblin(int initialMoney, double initialHealth) {
money = initialMoney;
health = initialHealth;
}

// Конструктор с одним параметром.
public Goblin(String goblinName) {
name = goblinName;
}

// Приватный конструктор. Его можно будет вызвать
// только внутри этого метода.
private Goblin(int initialDiamonds) {
diamonds = initialDiamonds;
}

//… ещё конструкторы и методы
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

classGoblin{

privateintmoney;

doublehealth;

protectedintdiamonds=10;

publicStringname;

// Конструктор без параметров.

publicGoblin(){

}

// Конструктор с двумя параметрами

publicGoblin(intinitialMoney,doubleinitialHealth){

money=initialMoney;

health=initialHealth;

}

// Конструктор с одним параметром.

publicGoblin(StringgoblinName){

name=goblinName;

}

// Приватный конструктор. Его можно будет вызвать

// только внутри этого метода.

privateGoblin(intinitialDiamonds){

diamonds=initialDiamonds;

}

//… ещё конструкторы и методы

}

Теперь мы можем создавать экземпляры класса
Goblin , используя любой из этих конструкторов, но приватный конструктор можно вызывать только внутри самого класса
Goblin  (например, в одном из его методов или полей инициализации).

Java

Goblin goblin0 = new Goblin();
Goblin goblin1 = new Goblin(«Vasya»);
Goblin goblin2 = new Goblin(3, 45.0);

1
2
3

Goblin goblin0=newGoblin();

Goblin goblin1=newGoblin(«Vasya»);

Goblin goblin2=newGoblin(3,45.0);

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

Хитрость: Операция
new  возвращает ссылку на объект. Можно сразу же вызвать какой-нибудь метод этого объекта или обратиться к свойству, не присваивая эту ссылку переменной:

Java

new Goblin(myParam1).someMethod1(myParam2);

1 newGoblin(myParam1).someMethod1(myParam2);

Если метод тоже возвращает ссылку на объект, то можно сразу вызвать метод этого объекта:

Java

new Goblin(myParam1).someMethod1(myParam2).someMethod2(); //… и т. д.

1 newGoblin(myParam1).someMethod1(myParam2).someMethod2();//… и т. д.

Ключевые слова
static ,
final  и
abstract  будут описаны позднее, но если вы перечитываете учебник второй раз, то запомните:

Конструктор НЕ может быть
static ,
final  или
abstract.

Применение метасимвольных аргументов

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

Так как параметризованный тип, какой тип параметра вы укажете для , когда создадите параметр метода типа ? Напрашивается следующий вариант:

Но это не сработает, так как в этом случае метод будет принимать аргументы только того же типа, что и существующий объект:

Чтобы создать обобщенную версию метода , следует воспользоваться другим средством обобщений Jаvа – метасимвольным аргументом. Метасимвольный аргумент обозначается знаком ? и представляет неизвестный тип.

Мета символ не оказывает никакого влияния на тип создаваемых объектов класса . Это определяется оператором в объявлении класса Average. Мета символ просто совпадает с любым достоверным объектом класса .

Метасимвольные аргументы могут быть ограничены почти таким же образом, как и параметры типов

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

1. Что такое ООП?

Подход (методология) к программированию ориентированный на объекты. Представление программы в виде совокупности объектов,
каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.

Важным элементом ООП является абстракция. Эффективным средством применения абстракции служат иерархические конструкции.
Это позволяет упрощать понимание сложных систем, разбивая их на более управляемые части.

Например, внешне автомобиль выглядит единым объектом. Но внутрион состоит из нескольких подсистем:
рулевого управления, двигатель, тормоза, аудиосистемы и т.п.
Каждая из этих подсистем, также собрана из более специализированных узлов.
Т.е. структуру автомобиля (или любой сложной системы) можно описать с помощью иерархических абстракций.
Это применимо и к компьютерным программам.

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

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: