1. Новый язык программирования

Почему вам нужно изучать новый язык программирования Java?

Если ответить на этот вопрос кратко, то потому, что он специально ориентирован на самые передовые технологии, связанные с сетью Internet. Растущая популярность Internet и, в особенности, серверов WWW, создает для программистов новые возможности для реализации своих способностей. Затратив всего пару-тройку недель на чтение нашей книги, вы сможете проникнуться идеологией Java и, как мы надеемся, сумеете по достоинству оценить возможности этого языка программирования.

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

Мобильность Java

В свое время вы слышали, что язык программирования С является мобильным в том смысле, что имеется принципиальная возможность переноса программ, составленных на этом языке, на различные платформы.

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

Вспомните хотя бы проблемы, связанные с переносом 16-разрядных приложений Windows в 32-разрядную среду Microsoft Windows 95 и Microsoft Windows NT. Даже если вы тщательно следовали всем рекомендациям Microsoft, разрабатывая приложения так, чтобы они могли работать в будующих версиях Windows, едва ли вам удасться просто перекомпилировать исходные тексты, не изменив в них ни строчки. Ситуация еще больше ухудшается, если вам нужно, например, перенести исходные тексты приложения Windows в среду операционной системы IBM OS/2 или в оболочку X-Windows операционной системы UNIX. А ведь есть еще компьютеры Apple, рабочие станции с процессором RISC и другие!

Как нетрудно заметить, даже если стандартизовать язык программирования для всех платформ, проблемы совместимости с программным интерфейсом операционной системы значительно усложняют перенос программ на различные платформы. И, конечно, вы не можете мечтать о том, чтобы загрузочный модуль одной и той же программы мог работать без изменений в среде различных операционных систем и на различных платформах. Если программа подготовлена для процессора Intel, она ни за что не согласится работать на процессоре Alpha или каком-либо другом.

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

На рис. 1.1 мы показали, как приложение, изначально разработанное для Microsoft Windows NT, переносится на платформу Apple Macintosh.

Рис. 1.1. Перенос приложения с платформы Windows NT на платформу Apple Macintosh

Вначале программист готовит исходные тексты приложения для платформы Microsoft Windows NT и отлаживает их там. Для получения загрузочного модуля исходные тексты компилируются и редактируются. Полученный в результате загрузочный модуль может работать на процессоре фирмы Intel в среде операционной системы Microsoft Windows NT.

Для того чтобы перенести приложение в среду операционной системы компьютера Apple Macintosh, программист вносит необходимые изменения в исходные тексты приложения. Эти изменения необходимы из-за различий в программном интерфейсе операционной системы Microsoft Windows NT и операционной системы, установленной в Apple Macintosh. Далее эти исходные тексты транслируются и редактируются, в результате чего получается загрузочный модуль, способный работать в среде Apple Macintosh, но не способный работать в среде Microsoft Windows NT.

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

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

Сказанное иллюстрируется на рис. 1.2.

Рис. 1.2. Подготовка приложения Java для работы на разных платформах

Таким образом, приложение Java компилируется и отлаживается только один раз, что уже значительно лучше. Остается, правда, вопрос - как быть с программным интерфейсом операционной системы, который отличается для разных платформ?

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

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

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

Еще одна проблема, возникающая при переносе программ, составленных на языке программирования С, заключается в том, что размер области памяти, занимаемой переменными стандартных типов, различный на разных платформах. Например, в среде операционной системы Microsoft Windows версии 3.1 переменная типа int в программе, составленной на С, занимает 16 бит. В среде Microsoft Windows NT этот размер составляет 32 бита.

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

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

Базовые типы данных

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

Тип данных Размер занимаемой области памяти Значение по умолчанию
boolean 8 false
byte 8 0
char 16 ‘x0’
short 16 0
int 32 0
long 64 0
float 32 0.0F
double 64 0.0D

Для каждого базового типа данных отводится конкретный размер памяти, который, как мы говорили в предыдущем разделе, не зависит от платформы, на которой выполняется приложение Java. Фактический размеры памяти, отведенные для хранения переменной, могут отличаться от приведенных выше, например, для хранения переменной типа short может быть зарезервировано слово размером 32 бита. Однако язык Java сделан таким образом, что это никак не повлияет на мобильность приложения. Забегая вперед, скажем, что в языке Java нет указателей, поэтому вы не можете адресоваться к элементам массива чисел по относительному смещению этих элементов в оперативной памяти. Следовательно, точный размер элемента в данном случае не играет никакой роли.

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

int nCounter = 0;
int i;
i = 8;

Переменные типа boolean могут находиться только в двух состояниях - true и false, причем эти состояния никаким образом нельзя соотнести с целыми значениями. Вы не можете, как это было в языке С, выполнить преобразование типа boolean, например, к типу int - компилятор выдаст сообщение об ошибке.

Переменная типа byte занимает восемь бит памяти и про нее больше нечего сказать.

Что же касается типа char, то он используется для хранения символов в кодировке Unicode. Эта кодировка позволяет хранить национальные наборы символов, что очень удобно для интернациональных приложений, предназначенных для работы в Internet.

Переменные типа byte, short, int и long являются знаковыми. В языке Java нет беззнаковых переменных, как это было в языке С.

Приложение Java может оперировать числами в формате с плавающей точкой, определенным в спецификации IEEE 754. Тип float позволяет хранить числа с одинарной точностью, а формат double - с двойной.

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

int x;
void ChangeX(int x)
{
  x = 5;
}
. . .
x = 0;
ChangeX(x);

После вызова функции ChangeX содержимое переменной x останется равным нулю.

Проблему можно решить, если вместо базовых переменных использовать объекты встроенных классов, соответствующие базовым переменным. О встроенных классах вы узнаете из следующего раздела.

Библиотеки классов Java

Если предоставить в распоряжение программиста только язык программирования и не снабдить его набором готовых модулей, предназначенных для решения самых распространенных задач, ему придется отвлекаться на множество мелких деталей. Обычно все профессиональные системы разработки приложений содержат в своем составе набор стандартных библиотечных функций или библиотеки классов, таких как Microsoft MFC или Borland OWL. В комплекте со всеми средствами разработки Java поставляются достаточно развитые библиотеки классов, значительно упрощающие программирование. В этом разделе мы кратко расскажем о составе и назначении библиотек классов Java.

Встроенные классы

В языке Java все классы происходят от класса Object, и, соответственно, наследуют методы этого класса. Некоторые библиотеки классов подключаются автоматически, и мы будем называть их встроенными. К таким относится, в частности, библиотека с названием java.lang. Другие библиотеки классов вы должны подключать в исходном тексте приложения Java явным образом с помощью оператора import, о котором мы еще расскажем.

Замещающие классы

Очень часто в наших приложениях вместо базовых типов переменных мы будем использовать объекты встроенных классов, которые называются замещающими классами (wrapper classes). Ниже мы перечислили названия этих классов и названия базовых типов данных, которые они замещают:

Базовый тип данных Замещающий класс
boolean Boolean
char Character
int Integer
long Long
float Float
double Double

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

Класс String

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

Хотя в языке Java не допускается перезагрузка (переопределение) операторов, для объектов класса Stirng и объектов всех произошедших от него классов сделана встроенная перезагрузка операторов “+” и “+=”. С помощью этих операторов можно выполнять слияние текстовых строк, например:

System.out.println(“x = “ + x + ‘\n’);

Здесь в качестве параметра функции println передается текстовая строка, составленная из трех компонент: строки “x = “, числа x и символа перехода на следующую строку ‘\n’. Значение переменной x автоматически преобразуется в текстовую строку (что выполняется только для текстовых строк) и полученная таким образом текстовая строка сливается со строкой “x = “.

Другие встроенные классы

Среди других встроенных классов отметим класс Math, предназначенный для выполнения математических операций, таких как взятие синуса, косинуса и тангенса.

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

Библиотека встроенных классов содержит очень важные классы для работы с исключениями. Эти классы нужны для обработки ошибочных ситуаций, которые могут возникнуть (и возникают!) при работе приложений или аплетов Java.

Подключаемые библиотеки классов

Ниже мы кратко перечислим подлкючаемые библиотеки классов для того чтобы вы могли оценить возможности набора классов Java. Подробное описание этих классов есть в справочной системе Microsoft Visual J++ и в литературе, список которой приведен в конце книги. Мы же ограничимся описанием тех классов, которые будем использовать в наших примерах приложений.

Библиотека классов java.util

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

Библиотека классов java.io

В библиотеке классов java.io собраны классы, имеющие отношение к вводу и выводу данных через потоки. Заметим, что с использованием этих классов можно работать не только с потоками байт, но также и с потоками данных других типов, например числами int или текстовыми строками.

Библиотека классов java.net

Язык программирования Java разрабатывался в предположении, что им будут пользоваться для создания сетевых приложений. Поэтому было бы странно, если бы в составе среды разработки приложений Java не поставлялась библиотека классов для работы в сети. Библиотека классов java.net предназначена как раз для этого. Она содержит классы, с помощью которых можно работать с универсальными сетевыми адресами URL, передавать данные с использованием сокетов TCP и UDP, выполнять различные операции с адресами IP. Эта библиотека содержит также классы для выполнения преобразований двоичных данных в текстовый формат, что часто бывает необходимо.

В качестве примера приложения, составленного на языке программирования Java и ориентированного на работу в сети Internet, можно привести игру Java Color Lines (рис. 1.3).

Рис. 1.3. Сетевая игра Java Color Lines, расположенная на сервере http://spektr.orc.ru

Это сетевая версия извстной игры Lines, которая выполнена в виде нескольких аплетов, взаимодействующих между собой и между сервером WWW с адресом http://spektr.orc.ru, на котором они расположены. Так как список имен игроков и достигнутых ими результатов хранится на сервере, вы можете поучаствовать в мировом турнире, сразившись с игроками из разных стран.

В следующем томе “Библиотеки системного программиста”, посвященном Java, мы расскажем о том, как организовать взаимодействие между аплетами и сервером WWW.

Библиотека классов java.awt

Для создания пользовательского интерфейса аплеты Java могут и должны использовать библиотеку классов java.awt. AWT - это сокращение от Abstract Window Toolkit (инструментарий для работы с абстрактными окнами).

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

Библиотека классов java.awt.image

В среде любой операционной системы работа с графическими изображениями является достаточно сложной задачей. В 14 томе “Библиотеки системного программиста”, который называется “Графический интерфейс GDI в MS Windows” мы детально рассмотрели вопросы, связанные с рисованием графики и обработкой графических файлов в среде операционной системы Microsoft Windows. Если вы будете рисовать графические изображения в среде IBM OS/2 или X-Windows, вам, очевидно, придется использовать другие методики и другой программный интерфейс. Большую сложность также вызывает разбор заголовков графических файлов, так как они могут иметь различный формат и иногда содержат неправильную или противоречивую информацию.

Когда вы программируете на Java, рисование и обработка графических изображений выполняется намного проще, так как вам доступна специально предназначенная для этого библиотека классов java.awt.image. Помимо широкого разнообразия и удобства определенных в ней классов и методов, отметим способность этой библиотеки работать с графическими изображениями в формате GIF. Этот формат широко используется в Internet, так как он позволяет сжимать файлы графических изображений во много раз без потери качества за счет устранения избыточности.

Библиотека классов java.awt.peer

Библиотека классов java.awt.peer служит для подключения компонент AWT (например, кнопок, списков, полей редактирования текстовой информации, переключателей и так далее) к реализациям, зависящим от платформы, в процессе создания этих компонент.

Библиотека классов java.applet

Как нетрудно догадаться из названия, библиотека классов java.applet инкапсулирует поведение аплетов Java. Когда вы будете создавать свои аплеты, вам будет нужен класс Applet, расположенный в этой библиотеке классов. Дополнительно в библиотеке классов java.applet определены интерфейсы для подключения аплетов к содержащим их документам и классы для проигрывания аудиофрагментов.

Указатели, которых нет

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

Спешим успокоить - вы сможете успешно составлять приложения Java и без указателей, несмотря на то что вам, возможно, придется немного изменить стиль программирования.

Вы можете спросить: как же передавать функциям ссылки на объекты, если нет указателей?

Если вам нужно передать ссылку на переменную базового типа, такого, например, как int или long, то ничего не получится - мы уже говорили, что переменные базовых типов передаются по значению, а не по ссылке. Поэтому вы не сможете напрямую создать на языке Java эквивалент следующей программы, составленной на языке С:

// Некоторая переменная
int  nSomeValue;

// Функция, изменяющая значение переменной,
//   заданной своим адресом
void StoreValue(int *pVar, int nNewValue)
{
  pVar->nNewValue;
}
. . .
StoreValue(&nSomeValue, 10);

Выход, однако, есть.

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

Что же касается данных базовых типов, если вам нужно передавать на них ссылки, то следует заменить базовые типы на соответствующие встроенные классы. Например, вместо типа int используйте класс Integer, вместо типа long - класс Long и так далее.

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

Integer nSomeValue;
nSomeValue = new Integer(10);

Первая строка создает неинициализированную ссылку с именем nSomeValue и типом Integer. При попытке использования такой ссылки возникнет исключение.

Вторая строка создает объект класса Integer, вызывая конструктор. Этот конструктор определяет начальное значение. После выполнения оператора присваивания ссылка nSomeValue будет ссылаться на реальный объект класса Integer и ее можно будет использовать.

Имя объекта nSomeValue типа Integer вы можете передавать функциям в качестве параметра, причем это будет ссылкой на объект.

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

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

Массивы в Java

Для создания массива вы можете пользоваться квадратными скобками, расположив их справа от имени массива или от типа объектов, из которых составлен массив, например:

int nNumbers[];
int[] nAnotherNumbers;

Допустимы оба варианта, поэтому вы можете выбрать тот, который вам больше нравится.

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

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

int[] nAnotherNumbers;
nAnotherNumbers = new int[15];

Как выполнить инициализацию ячеек таблицы?

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

int[] nColorRed = {255, 255, 100, 0, 10};

Динамическая инициализация выполняется с использованием индекса массива, например, в цикле:

int nInitialValue = 7;
int[] nAnotherNumbers;
nAnotherNumbers = new int[15];
for(int i = 0; i < 15; i++)
{
  nAnotherNumbers[i] = nInitialValue;
}

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

Массивы могут быть многомерными и, что интересно, несимметричными.

Ниже создается массив массивов. В нулевом и первом элементе создается массив из четырех чисел, а во втором - из восьми:

int[][] nDim = new int[5][10];
nDim[0] = new int [4];
nDim[1] = new int [4];
nDim[2] = new int [8];

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

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

int[] nAnotherNumbers;
nAnotherNumbers = new int[15];
for(int i = 0; i < nAnotherNumbers.length; i++)
{
  nAnotherNumbers[i] = nInitialValue;
}

Для определения размера массива вам не нужен такой оператор как sizeof из языка программирования С, так как существует другой способ определения размера массива.

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

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

Создавая объекты в Java, вы можете руководствоваться принципом “Создай и забудь”, так как система сборки мусора позаботится об удалении ваших объектов. Объект будет удален из памяти, как только на него не останется ни одной ссылки из других объектов.

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

Особенности реализации классов в Java

Если вы умеете программировать на языке С++, у вас не возникнет никаких проблем с программированием на Java, так как эти языки очень похожи. Однако есть и некоторые отличия, которые следует учитывать. Мы приведем только краткое перечисление основных отличий. Более подробную информацию вы найдете в литературе, список которой есть в конце книги.

Определение класса

Для создания классов вы можете использовать только ключевое слово class. Что же касается union, то это ключевое слово в Java не применяется для создания классов.

В языке программирования С++ описание класса может быть отделено от его определения. Для Java это не так - описание класса не допустимо. Все методы должны быть определены внутри определения класса.

Недопустимо определение вложенных классов.

В Java также нет шаблонов. Вы можете создавать классы только на базе других классов.

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

При определении класса вы не можете указать деструктор. Функции удаления объектов Java из памяти выполняет система сборки мусора.

Внутри одного исходного файла вы можете определить только один общедоступный класс public.

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

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

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

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

Если в базовом классе метод определен с ключевым словом final, его нельзя переопределить в дочернем классе, созданном на базе данного метода.

Методы не могут быть определены как inline.

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

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

В языке С++ вы могли переопределить операторы, такие как +, -, ++ и так далее. Язык Java не допускает такое переопределение, что сделано для упрощения программирования. Тем не менее, операторы “+” и “+=” перегружены по умолчанию для выполнения операции слияния текстовых строк класса String.

Интерфейсы

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

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

Ссылки на методы класса

Так как в Java нет указателей, нет возможности ссылаться на методы с помощью оператора ->. Для ссылки на метод класса используется только оператор “точка”.

Оператор “::” также не определен в Java. Если вам необходимо вызвать метод из базового класса, следует использовать ключевое слово super.

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

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

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

Для ссылки на методы базового класса вы должны использовать ключевое слово super.

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