Выбрать главу

И хотя списки аргументов у обоих вариантов метода vaTest () отличаются, компилятор все равно не может правильно выбрать вариант для следующего вызова: vaTest (1)

В самом деле, не понятно, нужно ли преобразовать этот вызов в vaTest (int . . .) с одним аргументом переменной длины или же в вызов vaTest (int, int . . .) без аргументов переменной длины? В итоге возникает неоднозначная ситуация.

Вследствие ошибок, подобных описанным выше, в ряде случаев приходится отказываться от перегрузки и присваивать методам разные имена. Кроме того, ошибки неоднозначности вскрывают концептуальные просчеты в программировании, которые можно исправить, более тщательно обдумав структуру программы. Упражнение для самопроверки по материалу главы 6

Допустим, имеется следующий фрагмент кода:class X { private int count; Является ли допустимым приведенный ниже фрагмент кода?class Y { public static void main(String args[]) { X ob = new X(); ob.count = 10;.

Модификатор доступа должен __ объявлению члена класса.

Помимо очереди, в программах часто используется структура данных, которая называется стеком. Обращение к стеку осуществляется по принципу “первым пришел — последним обслужен44. Стек можно сравнить со стопкой тарелок, стоящих на столе.Последней берется тарелка, поставленная на стол первой. Создайте класс Stack, реализующий стек для хранения символов. Используйте методы push () и pop () для манипулирования содержимым стека. Пользователь класса Stack должен иметь возможность задавать размер стека при его создании. Все члены класса Stack, кроме методов push () и pop (), должны быть объявлены как private. (.Подсказка: в качестве заготовки можете воспользоваться классом Queue, изменив в нем лишь способ доступа к данным.)

Допустим, имеется следующий класс:class Test { int а; Test(int i) { a = i; } } Напишите метод swap (), реализующий обмен содержимым между двумя объектами типа Test, на которые ссылаются две переменные данного типа.

Правильно ли написан следующий фрагмент кода?class X { int meth(int a, int b) { ... } String meth(int a, int b) { ... }

Напишите рекурсивный метод, отображающий строку задом наперед.

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

Для чего может понадобиться статический блок?

Что такое внутренний класс?

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

Имя метода и список его параметров вместе составляют __ метода.

Если методу передается значение типа int, то в этом случае используется передача параметра по __.

Создайте метод sum () с аргументами переменной длины для суммирования передаваемых ему значений типа int. Метод должен возвращать результат суммирования. Продемонстрируйте его в действии.

Можно ли перегружать метод с аргументами переменной длины?

Приведите пример неоднозначного вызова перегружаемого метода с переменным числом аргументов.

Глава 7 Наследование

Основные навыки и понятия

Основы наследования

Вызов конструктора суперкласса

Обращения к членам суперкласса с помощью ключевого слова super

Создание многоуровневой иерархии классов

Порядок вызова конструкторов

Представление о ссылках на объекты подкласса из переменной суперкласса

Переопределение методов

Применение переопределяемых методов для организации динамического доступа

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

Использование ключевого слова final

Представление о классе Object

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

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

Наследование одних классов от других отражается в Java при объявлении класса. Для этой цели служит ключевое слово extends. Подкласс дополняет суперкласс, расширяя его.

Рассмотрим простой пример программы, демонстрирующий некоторые свойства наследования. В этой программе определен суперкласс TwoDShape, хранящий сведения о ширине и высоте двумерного объекта. Там же определен и его подкласс Triangle. Обратите внимание на то, что в определении подкласса присутствует ключевое слово extends. // Простая иерархия классов. // Класс, описывающий двумерные объекты, class TwoDShape { double width; double height; void showDim() { System.out.println("Width and height are " + width + " and " + height); } } // Подкласс класса TwoDShape для представления треугольников. // Класс Triangle наследует от класса TwoDShape class Triangle extends TwoDShape { String style; double area() { //Из класса Triangle можно обращаться к членам класса // TwoDShape таким же обраэом, как и к собственным членам. return width * height / 2; } void showStyle() { System.out.println("Triangle is " + style); } } class Shapes { public static void main(String args[]) { Triangle tl = new Triangle(); Triangle t2 = new Triangle(); // Все члены класса Triangle, даже унаследованные от класса // TwoDShape, доступны из объектов типа Triangle. tl.width = 4.0; tl.height = 4.0; tl.style = "isosceles"; t2.width = 8.0; t2.height = 12.0; t2.style = "right"; System.out.println("Info for tclass="underline" "); tl.showStyle(); tl.showDim(); System, out .println ("Area is " + tl.area()); System.out.println(); System.out.println("Info for t2: "); t2.showStyle(); t2.showDim(); System.out.println("Area is " + t2.area()); } }

Ниже приведен результат выполнения данной программы. Info for tclass="underline" Triangle is isosceles Width and height are 4.0 and 4.0 244 Java 7: руководство для начинающих, 5-е издание Area is 8.0 Info for t2: Triangle is right Width and height are 8.0 and 12.0 Area is 48.0

Здесь в классе TwoDShape определены атрибуты обобщенной двумерной фигуры, конкретным воплощением которой может быть квадрат, треугольник, прямоугольник и т.д. Класс Triangle представляет конкретную разновидность объекта типа TwoDShape, в данном случае — треугольник. Класс Triangle включает в себя все элементы класса TwoDObject, а в дополнение к ним — поле style и методы area () и showStyle (). Описание треугольника хранится в переменной экземпляра style, метод area () вычисляет и возвращает площадь треугольника, а метод showStyle () отображает геометрическую форму треугольника.

В класс Triangle входят все члены суперкласса TwoDShape, и поэтому в теле метода area () доступны переменные экземпляра width и height. Кроме того, с помощью объектов tl и t2 в методе main () можно непосредственно обращаться к переменным width и height, как будто они принадлежат классу Triangle. На рис. 7.1 схематически показано, каким образом суперкласс TwoDShape включается в состав класса Triangle.

Рис. 7.1. Схематическое представление класса Triangle

Несмотря на то что TwoDShape является суперклассом для класса Triangle, он по-прежнему остается независимым классом. Тот факт, что один класс является суперклассом другого класса, совсем не означает, что он не может быть использован самостоятельно. Например, следующий фрагмент кода считается вполне допустимым: TwoDShape shape = new TwoDShape(); shape.width = 10; shape.height = 20; shape.showDim();

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

Ниже приведена общая форма объявления класса, наследующего от суперкласса. class имя_подкласса extends имя_суперкласса { // тело класса }