Java добавить поля класса

Java для школьников. Занятие №10. Инициализация полей класса, использование экземпляров класса в качестве полей (метод композиции). Примитивные типы данных в Java

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

  • метод композиции как вариант повторного использования кода в Java (использование экземпляров класса другим классом);
  • инициализация переменных класса или, по-другому: как присвоить переменной класса какое-либо начальное значение.

Еще поговорим о методе toString() и о «примитивных» типах.

Занятие построено на переработанном примере, который подсмотрен в книге: Б.Эккель «Философия Java», 4 издание — «Синтаксис композиции» — [1] в списке литературы.

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

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

Читайте также:  Kotlin для чего sealed class

Давайте разберем один из вариантов повторного использования кода в Java, который называется «композиция».

Листинг 1. Файл SprinklerSystem.java

class WaterSource <
private String s ;
WaterSource ( ) <
System . out . println ( «WaterSource()» ) ;
s = «designed» ;
>
public String toString ( ) < return s ; >
>
public class SprinklerSystem <
private String valve1, valve2, valve3, valve4 ;
WaterSource source = new WaterSource ( ) ;
private int i ;
private double f ;
SprinklerSystem ( ) < f = 15.3 ; valve2 = "2-way valve" ; >;
public String toString ( ) <
return «valve1 color: #339933;»>+ valve1 + » valve2 color: #339933;»>+ valve2 + » valve3 color: #339933;»>+ valve3 + » valve4 color: #339933;»>+ valve4 + » \n » + » i color: #339933;»>+ i + » f color: #339933;»>+ f + » source color: #339933;»>+ source ;
>
public static void main ( String args [ ] ) <
SprinklerSystem sprinklers = new SprinklerSystem ( ) ;
System . out . println ( sprinklers ) ;
>
>

Итак, смотрим файл SprinklerSystem.java из Листинга 1. Наша программа состоит из двух классов: основного — SprinklerSystem (собственно сама система орошения) и вспомогательного WaterSource (источник воды). И в качестве поля класса SprinklerSystem, наряду с строковыми полями valve1, valve2, valve3, valve4 (valve — это кран или вентиль в нашей системе), полем целочисленного типа int — i и полем типа double — f используется поле с названием source, являющееся экземпляром класса WaterSource.

Оказывается, наряду с полями, являющимися так называемыми «примитивными» типами языка Java (int, double и т.д.), в качестве поля класса может быть использован экземпляр другого класса. Если быть честным, то тип String — это тоже представитель классов Java, только этот класс разработан уже не нами, а создателями языка. В Занятии 5 мы говорили также о выделении памяти для объектов. И если в состав класса входит экземпляр другого класса, то точно также, при создании нового объекта, память выделяется и для него. А код «внедряемого» объекта просто включается в новый класс (отсюда собственно и название такого метода повторного использования кода).

Для простоты наш класс WaterSource, который используется для композиции, содержит всего два метода — конструктор, который просто выводит с помощью System.out.println() строку с названием конструктора класса «WaterSource()» и метод toString(), который возвращает значение строковой переменной s. Интересно, что метод toString() мы определили и для основного класса. Ничего удивительного, ведь этот метод используется в Java в тех случаях, когда компилятор располагает не объектом, а, процитируем Эккеля:

«хочет получить его строковое представление в формате String. Поэтому в выражении метода SprinklerSystem.toString() » source source=» прибавляется объект класса WaterSource. Компилятор не может это сделать, поскольку к строке можно «добавить» такую же строку, и преобразует объект source в String вызывая метод toString(). Чтобы подобное поведение поддерживалось вашим классом, достаточно включить в него метод toString().»

Поговорим теперь о значениях по умолчанию для полей классов. В терминах ООП процесс присвоения полю или переменной к.л. начального значения называют «инициализацией». Если скомпилировать этот пример и посмотреть на вывод программы , то мы увидим, что примитивные типы, определенные в качестве полей класса (переменная i) автоматически инициализируются нулевыми значениями. Ссылки на объекты заполняются значениями null, и при попытке вызова метода по этой ссылке произойдет исключение или по-просту — «произойдет ошибка во время исполнения программы». Однако, как оказалось, такую ссылку можно вывести на экран с помощью метода System.out.println.

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

Компилятор не создает объекты для переменных класса и ссылок «по-умолчанию», и это логично, потому что во многих случаях это привело бы к лишним затратам ресурсов. Если нужно проинициализировать переменную — присвойте ей значение в конструкторе (как для f, valve2), ссылку на объект (класс) — воспользуйтесь оператором new.

В заключении, приведем в таблице примитивные типы Java, хоть мы еще и не со всеми познакомились:

Примитивный тип Размер занимаемой памяти, бит Минимум Максимум
boolean (логическое значение)
char (символьное значение) 16 0 2 16 -1
byte (байт) 8 -128 +127
short (короткое целое) 16 -2 15 +2 15 -1
int (целое) 32 -2 31 +2 31 -1
long (длинное целое) 64 -2 63 +2 63 -1
float (число с плавающей запятой) 32 IEEE754 IEEE754
double (число с повышенной точностью) 64 IEEE754 IEEE754
void («пустое» значение)

Примечания: * для определения максимального значений переменных примитивных типов используется известная в информатике формула Хартли N = 2 i , где i — размер переменной в битах, плюс необходимо учитывать еще знак переменной;
* IEEE754 — стандарт для представления чисел с плавающей запятой
Числа с плавающей точкой/запятой согласно стандарту IEEE754-2008, исчерпывающая информация

По ссылке ниже можно скачать пример класса Car, подсмотренного на просторах Интернета и немного переработанного, где с помощью нескольких вспомогательных классов показаны различные способы выполнения полезных действий в программе с использованием метода композиции. Скачать файл Car.java

1. Брюс Эккель «Философия Java», 4-е издание, Глава 7 «Повторное использование классов», параграф — «Синтаксис композиции» с.170

Источник

Declaring Member Variables

The Bicycle class uses the following lines of code to define its fields:

public int cadence; public int gear; public int speed;

Field declarations are composed of three components, in order:

  1. Zero or more modifiers, such as public or private .
  2. The field’s type.
  3. The field’s name.

The fields of Bicycle are named cadence , gear , and speed and are all of data type integer ( int ). The public keyword identifies these fields as public members, accessible by any object that can access the class.

Access Modifiers

The first (left-most) modifier used lets you control what other classes have access to a member field. For the moment, consider only public and private . Other access modifiers will be discussed later.

  • public modifier—the field is accessible from all classes.
  • private modifier—the field is accessible only within its own class.

In the spirit of encapsulation, it is common to make fields private. This means that they can only be directly accessed from the Bicycle class. We still need access to these values, however. This can be done indirectly by adding public methods that obtain the field values for us:

public class Bicycle < private int cadence; private int gear; private int speed; public Bicycle(int startCadence, int startSpeed, int startGear) < gear = startGear; cadence = startCadence; speed = startSpeed; >public int getCadence() < return cadence; >public void setCadence(int newValue) < cadence = newValue; >public int getGear() < return gear; >public void setGear(int newValue) < gear = newValue; >public int getSpeed() < return speed; >public void applyBrake(int decrement) < speed -= decrement; >public void speedUp(int increment) < speed += increment; >>

Types

All variables must have a type. You can use primitive types such as int , float , boolean , etc. Or you can use reference types, such as strings, arrays, or objects.

Variable Names

All variables, whether they are fields, local variables, or parameters, follow the same naming rules and conventions that were covered in the Language Basics lesson, Variables—Naming.

In this lesson, be aware that the same naming rules and conventions are used for method and class names, except that

  • the first letter of a class name should be capitalized, and
  • the first (or only) word in a method name should be a verb.

Источник

Initializing Fields

As you have seen, you can often provide an initial value for a field in its declaration:

public class BedAndBreakfast < // initialize to 10 public static int capacity = 10; // initialize to false private boolean full = false; >

This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate. Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.

Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.

Static Initialization Blocks

A static initialization block is a normal block of code enclosed in braces, < >, and preceded by the static keyword. Here is an example:

A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

There is an alternative to static blocks — you can write a private static method:

The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.

Initializing Instance Members

Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods.

Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:

The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.

A final method cannot be overridden in a subclass. This is discussed in the lesson on interfaces and inheritance. Here is an example of using a final method for initializing an instance variable:

This is especially useful if subclasses might want to reuse the initialization method. The method is final because calling non-final methods during instance initialization can cause problems.

Previous page: Understanding Class Members
Next page: Summary of Creating and Using Classes and Objects

Источник

Оцените статью