© 2008 Наталия Македа
Все материалы блога защищены авторским правом. Любая перепечатка или использование материалов этого блога в коммерческих целях возможна лишь с письменного согласия автора. При некоммерческом использовании ссылка на блог обязательна.

понедельник, 26 января 2009 г.

protected (Выпуск 16)

Название protected (защищённый) слегка сбивает с толку. Читатель может подумать, что защищённый доступ имеет очень ограничивающую натуру, что-то вроде приватного. В реальности же защищённые элементы являются более доступны, чем, скажем, элементы с доступом по умолчанию.

Только переменные и методы могут иметь защищённый модификатор доступа. Защищённый элемент доступен всем остальным классам из того же пакета, как и в случае с доступом по умолчанию. Кроме того, защищённый элемент класса доступен всем его подклассам, даже если они находятся в других пакетах.

В качестве примера рассмотрим фрагмент кода:

1. package sportinggoods;
2. class Ski {
3. void applyWax() { . . . }
4. }

У метода applyWax() доступ по умолчанию. Теперь рассмотрим подкласс:

1. package sportinggoods;
2. class DownhillSki extends Ski {
3. void tuneup() {
4. applyWax();
5. // продолжение кода
6. }
7. }

Подкласс вызывает унаследованный метод applyWax(). Всё идёт, как надо, поскольку оба класса Ski и DownhillSki находятся в одном и том же пакете. Но если один из этих классов по какой-то причине будет перемещён в другой пакет, DownhillSki больше не будт иметь доступа к наследуемому методу applyWax() и код не откомпилируется. Данная проблема решается при добавлении защмщённого модификатора доступа к методу applyWax() в строке 3:

1. package adifferentpackage; // Класс Ski в
// другом пакете
2. class Ski {
3. protected void applyWax() { . . . }
4. }


Читать далее!

Default (Выпуск 16)

Default (по умолчанию)- это способ доступа к классам, переменным и методам, если иной другой модификатор доступа не указан. Данные класса или его методы могут быть доступны по умолчанию, равно как и сам класс может быть доступен по умолчанию.

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

Когда вы пишете приложение, для которого нужно разработать несколько классов, то скорее всего вы размещаете ваши файлы с расширением .java, а байткоды соответствующий классов (.class) - в другой директории. И вот эта другая директория с точки зрения JRE (Java Runtime Environment) является пакетом.

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

Все классы в одном пакете с модификатором доступа по умолчанию могут доступаться к данным и методам друг друга.

Классы из других пакетов не могут получить доступ к вашим классам, поскольку у ваших классов можификатор доступа default, а не public! Даже если у классов вне вашего пакета есть подклассы из вашего пакета (например, такая ситуация характерна для апплетов), то и подклассы не могут доступаться по умолчанию, потому что модификатор default, а не protected или public. Рисунок ниже иллюстрирует разные ситуации с доступом по умолчанию внутри пакета и вне его:


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


Читать далее!

пятница, 9 января 2009 г.

private

Самый ограничивающий модификатор – private (приватный). Приватный метод или переменная могут быть использованы только внутри объекта класса, в котором они объявлены. Например, у нас имеется следующий фрагмент кода:

1. class Complex {
2. private double real, imaginary;
3.
4. public Complex(double r, double i) {
5. real = r; imaginary = i;
6. }
7. public Complex add(Complex c) {
8. return new Complex(real + c.real,
9. imaginary + c.imaginary);
10. }
11. }
12.
13. class Client {
14. void useThem() {
15. Complex c1 = new Complex(1, 2);
16. Complex c2 = new Complex(3, 4);
17. Complex c3 = c1.add(c2);
18. double d = c3.real; // Illegal!
19. }
20. }

В строке 17 мы вызываем c1.add(c2). Объект c1 вызывает метод add и использует при этом объект c2 в качестве параметра. Смотрите дальше, в строке 8 c1 имеет доступ к своим приватным переменным и к приватным переменным объекта c2! И это не ошибка.

Объявление переменных real и imaginary с модификатором private означает, что эти переменные могут быть доступны только в экземплярах (instance) класса Complex для любых экземпляров класса Complex. Таким образом c1 имеет доступ не только к своим собственным полям real и imaginary но и к полям real и imaginary любого экземпляра класса Complex. Модификаторы доступа определяют какие классы могут доступаться к разным элементам (поля, методы и т.д.), но не какие экземпляры классов.

Строка 18 нелегальна и приведёт к ошибке компиляции с сообщением: “Variable real in class Complex not accessible from class Client”. (Переменная real в классе Complex недоступна из класса Client) .Приватная переменная real может быть доступна только для экземпляра класса Complex.

Приватные данные могут быть скрыты от любого объекта. Если у класса Complex есть подкласс SubComplex, то любой экземпляр класса SubComplex будет наследовать переменные real и imaginary. И тем не менее, ни один экземпляр класса SubComplex не сможет получить доступ к значениям тех переменных. Поэтому, например, следующий код не откомпилируется:

1. class Complex {
2. private double real, imaginary;
3. }
4.
5.
6. class SubComplex extends Complex {
7. SubComplex(double r, double i) {
8. real = r; // Trouble!
9. }
10. }

В конструкторе класса SubComplex (строка 8), мы обращаемся к переменной real. И в этой строке возникает ошибка компиляции с сообщением: “Undefined variable: real.” (Не определена переменная real.) Модификатор private переменной real предотврашает к ней доступ из экземпляра класса SubComplex, то есть SubComplex не может доступиться к собственной переменной!


Читать далее!

public

Модификатор, который обеспечивает максимальную свободу в использовании классов, их полей и методов, - это public (публичный). Публичный класс, переменная или метод могут использоваться в любых Java программах без каких-либо ограничений. Например, если апплет (подкласс класса java.applet.Applet) объявлен публичным, то он может быть инстанциирован в браузерах. Приложение декларирует свой метод main() публичным, чтобы этот метод мог быть легко вызван из любого JRE (Java runtime Environment).


Читать далее!

понедельник, 24 ноября 2008 г.

3.2 Модификаторы доступа (Выпуск 14)

Модификаторы доступа определяют, могут ли классы использовать разнообразные элементы (сами классы, переменные-поля классов, методы классов и коснтрукторы) и как они могут их использовать.

Существует три модификатора доступа:

  • public
  • private
  • protected

Элементы (см. выше) могут иметь один и более модификаторов, либо не иметь их вовсе. Однако, среди всевозможных модификаторов элемента количество модификаторов доступа долно быть не больше одного.

Если элемент не имеет модификатора, то доступ к нему определяется по умолчанию, то есть default. Однако, ключевого слова default не существует! Другие наименования доступа по умолчанию, которые вы можете встретить в литературе, включают в себя friendly, package.

Ниже мы приводим примеры легально объявленых элементов с модификаторами или без них. Легальность некоторых объявлений зависит от контекста.

class Parser { ... }
public class EightDimensionalComplex { ... }
private int i;
Graphics offScreenGC;
protected double getChiSquared() { ... }
private class Horse { ... }

А вот примеры нелегальных объявлений элементов:

public protected int x; // Не более одного модификатора доступа!
default Button getBtn() {...} // "default" - это не ключевое слово


Читать далее!

Глава 3: Модификаторы (Выпуск 14)

Модификаторы - это ключевые слова в Java, которые сообщают компилятору информацию о природе кода, данных или классов. Например, модификаторы определяют, является ли некий элемент (класс, метод, переменная) приватным или публичным, статичным или финальным.

3.1 Обзор модификаторов

Наиболее распространённые модификаторы - модификаторы доступа: public, protected, private. О них мы поговорим сразу в следующей статье. Все остальные модификаторы не подпадают ни под какую чёткую классификацию. Мы их просто перечислим:

  • final
  • abstract
  • static
  • native
  • transient
  • synchronized
  • volatile

Каждому из этих модификаторов будет посвящена отдельная статья в будущем.


Читать далее!

среда, 5 ноября 2008 г.

Ответы на тест по операторам (Выпуск 13)

Вопросы теста можно посмотреть здесь.
  1. Ответ: С
    Вычисление производится в таком порядке: x = a + b; a = a + 1; b = b + 1; Поэтому x = 6 + 7 то есть 13. После чего переменные a и b инкрементируются до значений 7 и 8 соответственно.
  2. Ответ: B, С
    В варианте A использование оператора ! незаконно, поскольку x является переменной типа int, а не boolean. На этом часто попадаются C и C++ программисты. В варианте B выражение (x<3) имеет тип boolean, поэтому перед ним можно использовать оператор !. В ответе C поразрядный оператор ~ применен к целочисленному x, значение которого равно 6, что в битовом виде имеет форму 0..0110 (на месте двух точек должны стоять 27 нулей). После применения оператора ~ x примет значение 1..1001 (на месте двух точек подставьте 27 единиц).
  3. Ответ: A
    Битовое представление -1 состоит из единиц во всех разрядах. В варианте A эта строка из единиц сдвигается вправо на 5 позиций и освободившиеся 5 первых позиций заполняются нулями. Это в десятичном выражении имеет положительное значение 134217727. В варианте B аналогичный сдвиг происходит на 32 разряда и результат состоит из строки, у которой во всех позициях нули, то есть 0. Вариант C недопустим, потому что результат выражения x <<< 5 имеет тип int и не может быть присвоен переменной типа byte без явного приведения типов, которое в данном случае отсутствует. Наконец, в варианте D при сдвиге все освободившиеся позиции принимают значение наиболее значимого разряда исходного значения, то есть -1. Результат операции не отличается от исходного значения и равен -1.
  4. Ответ: A, C, E
    Варианты A и C эквивалентны, поскольку x+=y эквивалентно x = x+y. Выражение x+y "суммирует" строки и целое число, в результате из целого числа будет создан объект строкового типа и потом будет создана новая строка (ещё один новый объект строкового типа) со значением "Hello9". В варианте B сравнение x == y незаконно, потому что целочисленный тип не может сравниваться с указателем. В варианте D в результате вычисления выражения y+x также, как и в вариантах A и C создаётся новая строка. Но в последствии она присваивается переменной целочисленного типа, а это недопустимо. Вариант E самый оригинальный. В нём важны два момента: условный оператор :? и укороченный оператор &&. Левый операнд укороченого оператора, то есть выражение (x != null), всегда равен false. Следовательно правый операнд, то есть выражение (x.length() > 0), никогда не будет вычисляться, поскольку всё выражение заведомо равняется значению false. Это значение false затем используется в выражении условного оператора, результат которого будет равен 0 (операнд после двоеточия).
  5. Ответ: A, E
    Хотя int и float и не являются совместимыми с точки зрения присваиваний, они могут легко использоваться в левых и правых частях операторов сравнения, коим и является оператор ==. При этом int 100 приводится к float 100.0 и запросто сравнивается с другим float 100.0F. Поэтому вариант A проходит. В варианте B код не откомпилируется, потому что int и Integer (указатель) не могут быть приведены даже в случае оператора сравнения. В варианте C код компилируется и сравнение может быть проведено. Но выражение x == y сравнивает два различных указателя, и поэтому результат теста равен false. Аналогичные рассыждения можно провести для варианта D. Вариант E кажется эквивалентным варианту D, но это на самом деле не так. В варианте E для строковой константы "100" создаётся объект строкового типа, а x и y являются указателями на этот объект. То есть тест (x == y) равняется true и мы получаем сообщение "Equal".
  6. Ответ: AВ четвёртой строке кода результат вычисления (s.length()>5) равен false (поскольку длина строки "Hello" равна 5). Таким образом, всё выражения условия if равно false. В результате никаких манипуляций над строкой не производится и она остаётся прежней.
  7. Ответ: B
    Побитовый XOR оператор ^ возвращает 0, если оба биты одинаковы (оба равны 0 или оба равны 1), и 1 - в противном случае. Таким образом 00001010^00001111=00000101, то есть 5 в десятичном исчислении.
  8. Ответ: CВ операторе ?: используются операнды различных типов: 99.99 (double) и 9 (int). Поэтому int приводится к double и результат всего выражения будет типа double. Поскольку x = 4, то тест (x > 4) равен false. Следовательно, результат равен значению после двоеточия, то есть 9.0 (то есть типа double).
  9. Ответ: B
    Вычисление достаточно очевидно, поскольку участвуют только положительные числа. Деление 10 на 3 даёт 3 и в остатке 1, что и является ответом. Если бы мы имели дело с дробными числами, то алгоритм вычисления остатка от деления y на x был бы таким: вычитать x из y до тех пор, пока y не станет меньше x. Как только это случится, y - остаток от деления. Для отрицательных чисел можно забыть о знаках, но иметь в виду, что знак остатка от деления равен знаку делимого (левого операнда).
  10. Ответ: AОператор присваивания op= высчитывает левое выражение только один раз. Таким образом, декремент --x происходит только раз и в результате получается 0, а не -1. То есть не возникает никаких ошибок выхода за границы (out-of-bounds). В нулевой позиции массива находится значение Fred. При этом декремент имеет место перед операцией +=. Хотя объекты типа String не могут изменять своего значения (immutable), указатели, коими являются элементы массивы, могут изменяться. То есть мы можем создать новый объект в нулевой позиции массива name, который будет иметь значение "Fred.", то есть строка Fred, заканчивающаяся точкой.


Читать далее!