Синтаксис языка и базовые процедуры
Когда мы говорим о Java-программе, то имеем в виду совокупность объектов, которые вызывают методы друг друга.
Давайте рассмотрим ключевые элементы Java-программы:
Класс
Сущность, которая характеризуется полями (атрибутами) и поведением (методами). Например, разработчик имеет имя, фамилию, специализацию, зарплату и т.д.
Объект
Объект – это экземпляр класса. Например, конкретный разработчик.
- Имя: Иван
- Фамилия: Иванов
- Специализация: Java–разработчик
- Зарплата: 100500 долларов в час
Метод
Метод — это сущность, описывающая поведение класса. Например, разработчик пишет код, метод writeSomeCode() является выражением этого поведения в нашей программе.
Переменная
Переменная – это значения, которые характеризуют поля (атрибуты) класса. Например: Имя разработчика – это его свойство (поле), а если мы говорим, что этого разработчика зовут Иван, то “Иван” является переменной, которая характеризует такое свойство класса разработчик, как имя. В будущем мы будем создавать более сложные программы, чем в этом уроке, а сегодня мы напишем простую программу, которая выводит консольное приложение.
Приступим.
Открываем наш текстовый редактор. Пишем внутри следующий код:
public class MyFirstProgram{
public static void main(String[] args){
System.out.println("This is my first Java program.");
}
}
Сохраняем файл как "MyFirstProgram.java". Открываем терминал Ctrl + Alt + T.
Прописываем путь к расположению файла и нажимаем ‘Enter’.
В данном случае это выглядит так:
cd Desktop
Пишем:
javac MyFirstProgram.java
Если все было выполнено верно, будет создан файл MyFirstProgram.class.
В терминале снова пишем:
java MyFirstProgram
Будет выведено следующее:
This is my first Java program
This is my first Java program
Поздравляю, Вы создали вашу первую программу на языке Java! С полным описанием синтаксиса языка Java вы можете ознакомиться в Java Language Specification (JLS). Здесь описаны некоторые сущности языка.
Идентификаторы
Все компоненты в Java должны иметь имя
Существует ряд требований к идентификаторам:
Все идентификаторы должны начинаться с букв (A – Z или a – z), знака доллара ($) или подчеркивания (_).
После первого символа, идентификатор может иметь любую последовательность символов. В качестве идентификатора не могут использоваться ключевые слова. Все идентификаторы чувствительны к регистру.
Пример неправильного идентификатора:
123Developer, +first, int
Пример правильного идентификатора:
developer, $second, _third
Переменные
Переменные могут быть:
– локальными
– статическими
– не статическими
Модификаторы
В Java есть два типа модификаторов:
модификаторы доступа: default, public, protected, private;
другие модификаторы: final, abstract, stictfp.
Начиная с Java 5.0, в язык добавлена сущность Enum (перечисления). Например, мы можем сделать перечисление специализаций разработчиков (JAVA, C#, C++ и т.д.).
В обычном случае это выглядит вот так: у нас есть класс, который представляет разработчика:
Developer.java
package net.proselyte.javacore.basics;
public class Developer {
private Specilaty specilaty;
/*Default constructor*/
public Developer() {
}
/*Getter and Setter to get and to set specialty field value*/
public Specilaty getSpecilaty() {
return specilaty;
}
public void setSpecilaty(Specilaty specilaty) {
this.specilaty = specilaty;
}
/*toString() method to show Developer's info*/
@Override
public String toString() {
return "======================\n" +
"Developer " +
"\nSpecilaty: " + specilaty +
"\n======================\n";
}
}
У этого класса есть только один атрибут – специализация разработчика.
Другой класс является перечислением (Enum), в котором есть два варианта – JAVA или CPP, которые представляют языки Java и C++ соответственно.
Specialty.java
package net.proselyte.javacore.basics;
public enum Specilaty {
JAVA,
CPP
}
И, наконец, главный класс приложения, в котором создается два разработчика (javaDeveloper и cppDeveloper), специализация которых выбирается из перечисления Specialty.
DeveloperRunner.java
package net.proselyte.javacore.basics;
public class DeveloperRunner {
public static void main(String[] args) {
Developer javaDeveloper = new Developer();
Developer cppDeveloper = new Developer();
javaDeveloper.setSpecilaty(Specilaty.JAVA);
cppDeveloper.setSpecilaty(Specilaty.CPP);
System.out.println("Java Developer's Info:");
System.out.println(javaDeveloper);
System.out.println("C++ Developer's Info");
System.out.println(cppDeveloper);
}
}
В результате работы программы получим следующее:
/*Some system messages*/
Java Developer's Info:
======================
Developer
Specilaty: JAVA
======================
C++ Developer's Info
======================
Developer
Specilaty: CPP
======================
Массивы
Массивы – это объекты, которые хранят несколько переменных одного типа. Массив является объектом и хранится в heap (более подробно в разделе о JVM).
Комментарии
Язык Java поддерживает комментарии. Комментарии - это фрагменты кода, которые не обрабатываются компилятором, являются информацией, цель которой – объяснить, для чего необходим тот или иной фрагмент кода.
В классе Developer.java они показаны в таком виде:
/*toString() method to show Developer's info*/
//!!!This is comments!!!
@Override
public String toString() {
return "======================\n" +
"Developer " +
"\nSpecilaty: " + specilaty +
"\n======================\n";
}
Ключевые слова
В языка Java зарезервированы следующие ключевые слова:Помимо этих слов, зарезервированными являются слова goto и const, хотя и не используются в языке Java.
Слова true, false и null также нельзя использовать в качестве идентификаторов.
Более подробно с языком Java можно ознакомиться в Java Language Specification.
Операторы ветвления
Структуры ветвления и выбора – это структуры, которые принимают одно из более логических значений, которые оцениваются программой, и, в зависимости от истинности или ложности этого логического значения, выполняются различные фрагменты кода.
В виде блок-схемы операторы ветвления выглядят так:
В языке Java существует два вида операторов ветвления и один оператор выбора.
- if Оператор if состоит из логического выражения и фрагмента кода, который выполняется, если оно истинно.
- if… else После оператора if может идти ключевое слово else, которое выполняется в том случае, если логическое выражение ложно (false).
- вложенные if… else
- switch
Кроме этого, существует тернарный оператор ветвления, который имеет следующую форму:
Условие ? Вариант 1 : Вариант 2
, где:
- Условие – выражение, которое возвращает логический тип boolean (true / false).
- Вариант 1 – выражение, которое будет вызвано, если Условие истинно (true).
- Вариант 2 – выражение, которое будет вызвано, если Условие ложно (false).
Для понимания того, как это работает на практике, рассмотрим пример простого выражения.
Пример:
Допустим, что нам необходимо выбрать максимальное и минимальное значение из двух.
TernaryIfExample
public class TernaryIfExample {
public static void main(String[] args) {
int x = 5;
int y = 10;
int minValue, maxValue;
minValue = x
<
y ? x : y; maxValue = x
>
y ? x : y;
System.out.println("Minimum value is " + minValue);
System.out.println("Maximum value is " + maxValue);
}
}
В результате работы программы получим следующий результат:
/*Some System messages*/
Minimum value is 5
Maximum value is 10
Циклы
Во время разработки программного обеспечения, мы очень часто сталкиваемся с ситуацией, когда нам необходимо выполнить один и тот же фрагмент кода несколько раз.
В языке программирования Java для этих целей предусмотрены различные виды циклов.
Циклы позволяют нам выполнять команду или несколько команд много раз. В виде блок-схемы цикл выглядит следующим образом:
Виды циклов
В языке программирования Java есть 3 вида циклов:
while
Выполняет выражение или группу выражений до тех пор, пока указанное условие истинно (true). Если условие больше не выполняется (false), то программа выходит из цикла (выполнение цикла прекращается).for Выполняет выражение или группу выражений несколько раз и сокращает количество кода, необходимое для управления цикла.
do while Выполняет выражение или группу выражений до тех пор, пока указанное условие истинно (true). Если условие больше не выполняется (false), то программа выходит из цикла (выполнение цикла прекращается). Главное отличие от цикла while заключается в том, что проверка истинности условия находится в конце цикла, это означает, что цикл будет выполнен минимум один раз, независимо от истинности условия.
Управление циклом
В Java предусмотрены специальные управляющие выражения, с помощью которых мы можем изменить нормальный ход выполнения цикла в зависимости от условий.
Примечание: все объекты, которые создаются внутри цикла, видны только внутри этого цикла и уничтожаются после выхода из этого цикла.
В языке Java есть 2 управляющих выражения:
- break Прекращает выполнение цикла или оператора выбора switch (будет рассмотрен далее) передает выполнение программы выражению, которое следует сразу после цикла и оператора выбора switch
- continue Пропускает операторы тела цикла, которые еще не были выполнены на данной итерации и передает управление коду, который проверяет истинность условия завершения цикла.
Цикл for each
Начиная с Java 5, введен новый вид цикла for each. Он используется для “прохода” по всем элементам коллекций.
Объявление такого цикла состоит из 2 частей:
- Декларация Объявляется переменная такого же типа, как и коллекция, которую мы хотим использовать. Область видимости этой переменной лимитируется границами цикла.
- Выражение Определяет, какую именно коллекцию мы хотим использовать.
Пример:
public class ForEachRunner {
public static void main(String[] args) {
String[] strings = {"Proselyte", "Java Core", "Tutorial"};
System.out.println("Array of strings:");
for (String string : strings) {
System.out.print(string + " ");
}
System.out.println("\n============================\n");
System.out.println("Array of integers:");
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int element : array) {
System.out.print(element + " ");
}
}
}
В результате работы программы получим следующий результат:
/*Some system messages*/
Array of strings:
Proselyte Java Core Tutorial
============================
Array of integers:
1 2 3 4 5 6 7 8 9 10
Типы данных
Переменные – это зарезервированное место в памяти для хранения значения. Другими словами, когда мы объявляем переменную, мы резервируем место в памяти.
В зависимости от типа переменной (целые числа, строки, байт и т.д.) выделяется определенное количество памяти.
В языке Java все типы данных делятся на две большие группы:
- Примитивные типы данных
- Ссылочные типы данных (Объекты)
Примитивные типы данных
В Java есть 8 примитивных типов данных:
byte
- 8-битное целое число
- Максимальное значение: -128 (-2 ^ 7)
- Минимальное значение: 127 (2 ^ 7 -1)
- Значение по умолчанию: 0
- Используется для экономии места в больших массивах. Чаще всего вместо int.
- Пример: byte c = 65
short
- 16-битное целое цисло
- Максимальное значение: -32,768 (-2 ^ 15)
- Минимальное значение: 32,767 (2 ^ 15 – 1)
- Значение по умлочанию: 0
- Используется для экономии места вместо int.
- Пример: short a = 20000, short b = -10000
int
- 32-битное целое цисло
- Максимальное значение: -2,147,483,648 (-2 ^ 31)
- Минимальное значение: 2,147,483,647 (-2 ^ 31 – 1)
- Значение по умолчанию: 0
- Используется для целых значений в случае, если нет дефицита памяти.
- Пример: int i = 2000000000, int h = -1500000000
long
- 64-битное целое число
- Максимальное значение: -9,223,372,036,854,775,808 (-2 ^ 63)
- Минимальное значение: 9,223,372,036,854,775,807 (-2 ^ 63 – 1)
- Значение по умолчанию: 0L
- Используется для хранения больших целочисленных значений
- Пример: long l = 5000000000L, long k = -4000000000L
float
- 32-битное число с плавающей точкой IEEE 754
- Значение по умолчанию: 0.0f
Используется для экономии памяти в больших массивах чисел с плавающей точкой
Никогда не используется для хранения точных значений (например, денег).
Пример: float f = 112.3f
double
- 64-битное число двойной точности с плавающей точкой IEEE 754
- Значение по умлочанию: 0.0d
- Используется для хранения чисел с плавающей точкой (в большинстве случаев)
- Никогда не используется для хранения точных значений (например, денег)
- Пример: double d = 121.5
boolean
- В спецификации размер не указан. Зависит от типа JVM.
- Возможные значения: true/false
- Значение по умолчанию: false
- Используется для определения того, является ли условие истинным.
- Пример: boolean flag = true
char
- Символ кодировки Unicode 16-bit
- Максимальное значение: ‘\u0000’ (или 0)
- Минимальное значение: ‘uffff’ (или 65б535)
- Используется для хранения любого символа
- Пример: char c = ‘C’
Ссылочные типы данных
- К ссылочным типам данных относятся все типы данных, которые создаются с помощью конструкторов. К ним также относятся все классы, создаваемые разработчиками, например, Developer, Car, Person и т.д.
- Массивы являются ссылочными типами данных.
- Ссылочная переменная может использоваться в качестве ссылки на любой объект определенного типа данных.
- Все ссылочные типы имеют значение по умолчанию: null
Пример:
Developer developer = new Developer(“Java Developer”);
Литералы
Литералы – это представление фиксированных значений в виде кода. Они не требуют каких-либо вычислений. Например:
char c = 'C'
Значения int, long, short, byte могут быть выражены с помощью десятичной, шестнадцатеричной и восьмеричной систем.
Пример:
int decimal = 500;
int octal = 0168;
int hexa = 0x32;
Для строк в языке Java используется класс String. String может содержать как простые символы, так и символы Unicode:
char c = '\uffff';
String str = "\uffff";
В языке Java также существует ряд управляющих последовательностей для отображения некоторых символов:
\n | Новая строка (0x0a) |
---|---|
\r | Возврат каретки (0x0d) |
\f | Прогон страницы (0x0c) |
\b | Возврат на символ назад (0x08) |
\s | Проблем (0x20) |
\t | Табуляция |
\” | Двойная кавычка |
\’ | Одинарная кавычка |
\ | Обратный слэш |
\xxx | Восьмиричный символ (xxx) |
\uxxxx | Шестнадцатиричный символ UNICODE (xxxx) |
Виды модификаторов
Модификаторы – это ключевые слова, которые мы используем для того, чтобы изменить (модифицировать) переменную.
В языке Java есть два типа модификаторов:
- Модификаторы доступа
В языке Java есть 4 вида модификаторов доступа:
- default Доступен внутри пакета.
- private Доступен внутри класса
- protected Доступен внутри класса и для всех подклассов.
- public Доступен всем
Рассмотрим каждый их них отдельно.
default
Этот модификатор присваивается переменной, методу или классу в том случае, если явно его не указываем.
В этом случае переменная, метод или класс доступны всем классам внутри пакета.
private
Если мы используем модификатор доступа private для переменной, метода или конструктора, то они будут видны только внутри этого класса.
Классы и интерфейсы не могут иметь модификатор доступа private.
Доступ к переменным возможен только через getters и setters.
Пример:
public class Company {
private String companyName;
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
}
В этом примере переменная company Name (имя компании) объявлена как private, поэтому для доступа к ней созданы 2 метода: setCompanyName() и getCompanyName.
protected
Переменные, методы и конструкторы с модификатором доступа protected доступны в подклассах других пакетов и в любых классах в том же пакете.
Пример:
package net.proselyte.javacore.modifiers;
public class Developer {
protected String writeCode(){
return "Developer is writing code...";
}
}
И другой класс:
package net.proselyte.javacore.modifiers;
public class JavaDeveloper extends Developer{
@Override
protected String writeCode() {
return "Java Developer is writing Java code...";
}
}
Второй класс-наследник может перезаписать метод. Если бы мы объявили метод writeCode() в родительском классе, как private, то не смогли бы этого сделать.
public
Переменные, методы, класс и т.д. с модификатором доступа public доступны из любого класса.
Единственный нюанс заключается в том, что если мы пытаемся получить доступ к публичному классу из другого пакета, то должны импортировать класс с помощью ключевого слова import.
Пример:
public void setId(int id){
this.id = id;
}
Другие (non-access) модификаторы:
Также в Java предусмотрены 4 других (non-access) модификатора:
- final Делает переменную, метод или класс финальным (неизменяемым).
- static Используется для создания методов и переменных.
- abstract Используется для создания абстрактных классов.
- synchronized Используется в многопоточном программировании.
- volatile Используется в многопоточном программировании
- transient Используется для пропуска переменной во время ее сериализации.
Давайте рассмотрим каждый из них отдельно.
final
Метод c модификатором final не может быть перезаписан любым подклассом. Финальные методы и переменные не могут быть изменены.
Пример:
public class Company {
public final void showCompanyDirector(){
System.out.println("Company director is Ivan Ivanov for all times.");
}
}
Если же мы объявляем класс как final, то мы не можем от него наследоваться.
Пример:
public final class SecretClass {
private String secretInfo;
//some other fields and methods...
}
static
Статические переменные
Если переменная класса объявлена как статическая, то она будет существовать независимо от экземпляров данного класса. Существует одна копия статической переменной, независимо от количества экземпляров.
Локальные переменные не могут быть статическими.
Статические методы
Если метод класса объявлен как статический, то он будет существовать независимо от экземпляров данного класса. Существует одна копия статического метода, независимо от количества экземпляров.
Статические методы не используют никакие переменные, объявленные в классе, в котором они созданы.
Вызов статического метода происходит написанием самого метода, а не в виде:
экземпляр\класса.статический_метод()_
Пример:
package net.proselyte.javacore.modifiers.nonaccess;
public class CarFactory {
private static int carAmount = 0;
private static int getCarAmount() {
return carAmount;
}
private static void buildCar() {
carAmount++;
}
public CarFactory() {
CarFactory.buildCar();
}
public static void main(String[] args) {
System.out.println("Before working day on factory there is: " + getCarAmount() + " cars.");
for (int i = 0; i
<
10; i++) {
new CarFactory();
}
System.out.println("After one working day on factory there are: " + getCarAmount() + " cars.");
}
}
В результате работы программы мы получим следующий результат:
/*Some system messages*/
Before working day on factory there is: 0 cars.
After one working day on factory there are: 10 cars.
abstract
Абстрактный класс
Абстрактный класс – это класс, который не имеет экземпляра. Если мы создаем абстрактный класс, то его назначение состоит в том, чтобы от него наследовались другие классы.
Абстрактный класс не может иметь модификатор final.
Если класс содержит абстрактные методы, то он должен быть объявлен как абстрактный.
Пример:
package net.proselyte.javacore.modifiers.nonaccess.abstractclasses;
public abstract class Beast {
private String beastName;
public Beast(String beastName) {
this.beastName = beastName;
}
public abstract void toBreath();
public abstract void toEat();
}
Здесь мы видим абстрактный класс Beast (зверь). Есть понятие "зверь", но нет такого животного под названием "зверь". Поэтому это прекрасный пример для абстрактного класса.
Абстрактный метод
Абстрактный метод – это метод, который объявлен, но который не имплементирован, т.е. не имеет внутри никакой логики. Классы-наследники абстрактного класса будут имплементировать этот метод.
Любой класс, который наследует абстрактный класс, должен имплементировать все его абстрактные методы. За исключением случая, когда класс-наследник также является абстрактным классом.
Абстрактный класс не обязательно должен содержать абстрактные методы.
Рассмотрим пример.
Выше мы уже приводили пример класса Beast, а теперь мы создадим класс, который будет наследоваться от него.
Все звери едят и дышат, каждый по-своему, но у всех есть такое поведение.
Рассмотрим класс Cat (Кот), который является частным случаем зверя.
package net.proselyte.javacore.modifiers.nonaccess.abstractclasses;
public class Cat extends Beast{
private String color;
public Cat(String beastName) {
super(beastName);
}
@Override
public void toBreath() {
System.out.println("Cat uses lungs for breathing");
}
@Override
public void toEat() {
System.out.println("Cat eats fish.");
}
}
Как мы видим, в методах toBreath() и toEat() мы конкретизируем, что кот дышит используя легкие, а также питается рыбой.
synchronized
Модификатор synchronized говорит о том, что данный метод может быть задействован только одним потоком одновременно.
Пример:
public synchronized void showCompanyName(){
System.out.println("Company name is SkybleSoft.");
}
volatile
Модификатор volatile используется для того, чтобы указать JVM, что поток, который образуется к переменной, должен всегда сливать (merge) свою собственную копию переменной с главной копией в памяти.
Обращение к волатильной переменной синхронизирует все кешированные копии переменной в памяти. Модификатор volatile может применяться только к переменным.
Пример:
package net.proselyte.javacore.modifiers.nonaccess.volatilemodifier;
public class Transaction implements Runnable{
private volatile boolean isActive;
@Override
public void run() {
isActive = true;
while (isActive){
System.out.println("Transaction is active...");
}
}
public void stop(){
isActive = false;
System.out.println("Transaction stopped.");
}
}
В этом примере у нас есть некая транзакция, которая активизируется методом run() и прекращается вызовом метода stop().
transient
Модификатор transient дает команду JVM пропустить данную переменную во время сериализации содержащего её объекта.
Пример:
public transient String remarks = "Some remarks."; //This variable will not be resisted
public transient String name; //This variable will be persisted.
В этом примере переменная remarks (примечания) не будет сохранена, а переменная name (имя) – будет.
Классы-обертки
До этого мы с Вами использовали примитивные типы данных (далее – примитивы) для работы с числами. Это были такие типы данных, как int, long, byte и т.д.
Тем не менее, во время разработки реальных программ, мы сталкиваемся с ситуациями, когда нам необходимы объекты, а не примитивы. С этой целью в языке Java созданы классы-обертки.
Все эти классы являются наследниками класса Number.
Вот так выглядит иерархия класса Number:
Эти объекты “обертывают” соответствующий им примитив и преобразовывают его в объект (ссылочный тип данных). Этот процесс называется автоупаковкой (boxing). Обратный процесс называется распаковкой (unboxing).
Рассмотрим простой пример:
public class BoxingNumbersDemo {
public static void main(String[] args) {
Double number = 8.0; //This is boxing of double by Double class
number += 5.0; //This is unboxing Double to double
System.out.println("number = " + number);
}
}
В результате работы программы получим следующий результат:
/*Some system messages*/
number = 13.0
Выше мы рассмотрели, как происходит упаковка и распаковка чисел с использованием класса Number. Далее мы увидим, как происходит тот же процесс для символов.
Для обеспечения boxing/unboxing символов, в языке Java существует класс Character.
Как в ситуации с числами, мы часто сталкиваемся с ситуацией, когда нам нужны объекты, а не примитивы. В этом случае мы будем делать следующее.
Пример:
public class BoxingCharacterDemo {
public static void main(String[] args) {
Character character = 'C'; //Boxing char to Character
char a = character; //Unboxing Character to char
System.out.println("character: " + character);
System.out.println("char a: " + a);
}
}
В результате работы программы мы получим следующий результат:
/*Some system messages*/
character: C
char a: C
Методы
Метод – это набор выражений, которые объединены вместе для выполнения определенной операции.
Например, когда мы вызываем метод System.out.println(), начинается выполнение целого ряда операций для того, чтобы в итоге отобразить "вывести сообщение в консоль".
В этом уроке мы более подробно изучим, как создавать собственные методы. Рассмотрим методы, которые возвращают определенное значение, а которые – нет. Также мы поговорим о том, что такое перезагрузка метода.
В целом, методы выглядят следующим образом:
modifier returnValue methodName (parameters of the method){
body of the method...
}
Метод состоит из следующих сущностей:
Модификатор
Модификатор метода говорит компилятору, как вызывать данный метод и определяет уровень доступа данного метода. Модификатор не является обязательной частью объявления метода.
Возвращаемый тип
Метод возвращает значение. Возвращаемый тип – это тип данных, который будет возвращен данным методом. Если нам не нужно, чтобы метод возвращал значение, то мы должны использовать ключевое слово
void в качестве возвращаемого типа.Имя метода
Имя метода является его идентификатором.
Параметры
Если нам необходимо выполнить определенные вычисления, например, получить сумму двух чисел, то мы должны передать методу эти два числа. Передать эти числа мы можем с помощью параметров метода. Мы должны указать тип данных этих параметров. Метод также может не иметь параметров.
Тело метода
Тело метода включает в себя набор выражений, которые определяют поведение метода. В случае со сложением двух чисел, метод выполнит операцию сложения.
Для понимания того, как это работает на практике, рассмотрим пример простого приложения.
Пример:
public class MethodsDemo {
public static void main(String[] args) {
int a = 5;
int b = 10;
int c;
c = calculateSum(a, b);
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("Calculate the sum, using method calculateSum()...");
System.out.println("c = " + a + " + " + b + " = " + c);
System.out.println("Find the max number, using method findMaxNumber()...");
findMaxNumber(a, b);
}
static int calculateSum(int a, int b) {
int c = a + b;
return c;
}
static void findMaxNumber(int a, int b) {
if (a == b) {
System.out.println("This numbers are equal.\n");
} else if (a
>
b) {
System.out.println("First number " + a + " is larger than " + b + "\n");
} else {
System.out.println("Second number " + b + " is larger than " + a + "\n");
}
}
}
В результате работы программы мы получим следующий результат:
/*Some system messages*/
a = 5
b = 10
Calculate the sum, using method calculateSum()...
c = 5 + 10 = 15
Find the max number, using method findMaxNumber()...
Second number 10 is larger than 5
Как мы видим, первый метод принимает два параметра и возвращает значение (сумму этих чисел). Второй метод также принимает два параметра, но не возвращает никакого значения. Вместо этого, он определяет максимальное число и выводит текстовое сообщение.
Перезагрузка методов
Иногда нам необходимо выполнять одни и те же операции для разных типов данных. Например, нам необходимо определять сумму как для целых чисел, так и для чисел с плавающей точкой. Перегруженный метод должен иметь такое же название, как и первый, но список параметров должен отличаться (либо типы данных, либо количество параметров, либо то и другое).
Рассмотрим пример простого приложения:
public class OverloadingMethodDemo {
public static void main(String[] args) {
int a = 5;
int b = 10;
double c = 3.3;
double d = 4.4;
System.out.println("Initial variables: ");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
System.out.println("Calculate sum of integers using method calculateSum(): ");
int integerSum = calculateSum(a,b);
System.out.println("Sum of integers is: " + integerSum);
System.out.println("\n========================\n");
System.out.println("Calculate sum of floating point numbers using method calculateSum(): ");
double doubleSum = calculateSum(c,d);
System.out.println("Sum of floating point numbers is: " + doubleSum);
System.out.println("\n========================\n");
}
static int calculateSum(int a, int b) {
return a + b;
}
static double calculateSum(double a, double b) {
return a + b;
}
}
В результате работы программы получим следующий результат:
/*Some system messages*/
Initial variables:
a = 5
b = 10
c = 3.3
d = 4.4
Calculate sum of integers using method calculateSum():
Sum of integers is: 15
========================
Calculate sum of floating point numbers using method calculateSum():
Sum of floating point numbers is: 7.7
========================
Конструкторы
Конструктор, по своей сути, тоже метод, который имеет такое же название, как и класс, в котором он создан. Его задача – создавать экземпляры данного класса (объекты).
Все классы имеют конструктор. Даже если он не объявлен явно, то используется конструктор по умолчанию (без аргументов – всем переменным согласно спецификации присваиваются значения по умолчанию).
Рассмотрим пример простого приложения с использованием конструктора.
Класс Developer:
public class Developer {
int id;
String firstName;
String lastName;
String specialty;
int experience;
/**
* Default constructor
*/
public Developer() {
}
/**
* Simple constructor
*/
public Developer(int id, String firstName, String lastName, String specialty, int experience) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.specialty = specialty;
this.experience = experience;
}
@Override
public String toString() {
return "Developer Info: " +
"\nid: " + id +
"\nFirst Name: " + firstName +
"\nLast Name: " + lastName +
"\nSpecialty: " + specialty +
"\nExperience: " + experience + "\n";
}
}
Класс DeveloperRunner:
public class DeveloperRunner {
public static void main(String[] args) {
Developer emptyDeveloper = new Developer();
Developer filledDeveloper = new Developer(1, "First", "Developer", "Java", 3);
System.out.println(emptyDeveloper);
System.out.println(filledDeveloper);
}
}
В результате работы программы получим следующий результат:
/*Some system messages*/
Developer Info:
id: 0
First Name: null
Last Name: null
Specialty: null
Experience: 0
Developer Info:
id: 1
First Name: First
Last Name: Developer
Specialty: Java
Experience: 3