Опубликован: 01.11.2004 | Уровень: для всех | Доступ: свободно | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 13:

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

< Лекция 12 || Лекция 13: 123 || Лекция 14 >
Аннотация: Вводится понятие класса и интерфейса в языке Java. Рассматривается применение вложенных и абстрактных классов. Приводится пример реализации раннего и позднего связывания. Рассматривается эквивалентность объектов в языке Java.

Механизмы наследования

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

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

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

Интерфейс может быть объявлен для расширения одного или нескольких интерфейсов.

Наследование позволяет определять новые классы в терминах существующих классов.

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

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

Язык Java разрешает несколько уровней наследования, определяемых непосредственным суперклассом и косвенными суперклассами. Наследование можно использовать для создания иерархии классов.

При создании подкласса на основе одного или нескольких суперклассов возможны следующие способы изменения поведения и структуры класса:

  • расширение суперкласса путем добавления новых данных и методов;
  • замена методов суперкласса путем их переопределения;
  • слияние методов из суперклассов вызовом одноименных методов из соответствующих суперклассов.

Объявление класса

Объявление класса вводит новый ссылочный тип и определяет или часть, или всю его реализацию.

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

Объявление класса может иметь следующее формальное описание:

МодификаторыКласса  class  ИмяКласса 
extends ИмяСуперКласса  
implements СписокРеализуемыхИнтерфейсов 
{ТелоКласса}

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

Например:

public class A implements B {
  public A() {   }
   public int Metod1(){return 0;}
}
  interface B {
 public int Metod1();
}

Вложенный класс описывается так же, как и внешний.

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

Класс может иметь более одного модификатора класса.

В языке программирования Java существуют следующие модификаторы класса:

  • abstract, являющийся модификатором реализации класса и определяющий, что класс может иметь абстрактные методы (методы, не имеющие реализации);
  • final, являющийся модификатором ограничения иерархии классов и указывающий, что класс не может иметь подклассов (не должен никогда появляться во фразе extends объявления класса). Класс с модификатором final обязан реализовать все свои интерфейсы.
  • public является модификатором доступа и указывает, что к данному классу разрешен доступ из других пакетов. Доступ может быть выполнен или непосредственно указанием квалифицированного имени класса, или с использованием оператора import.

Для указания модификаторов класса применяются следующие правила:

  • если класс, имеющий абстрактные методы, объявлен без модификатора abstract, то возникает ошибка компиляции;
  • для абстрактных классов нельзя создавать экземпляры класса;
  • если при объявлении класса не указан модификатор public, то класс доступен только внутри своего пакета;
  • при компиляции каждый общедоступный класс всегда записывается в отдельный файл с расширением .CLASS. Такой файл называется модулем компиляции;
  • имя общедоступного класса должно совпадать с именем файла, содержащего код класса на языке Java;
  • один модуль компиляции может содержать только один класс или интерфейс, имеющие модификатор public ;
  • один модуль компиляции может одновременно содержать объявление общедоступного класса и нескольких интерфейсов или классов, не имеющих модификатора public ;
  • один модуль компиляции не может одновременно содержать объявление общедоступного класса ( public class ) и общедоступного интерфейса ( public interface );
  • объявление класса одновременно с модификаторами final и abstract вызывает ошибку компиляции.

Любой класс может иметь только один суперкласс, указываемый ключевым словом extends. Наследуемый суперкласс должен быть доступным классом и не иметь модификатора final.

По умолчанию предполагается, что в том случае, если для класса не указано никакого суперкласса, то его непосредственным суперклассом станет класс Object из пакета java.lang, который всегда является корневым классом в любой формируемой иерархии классов.

Раннее и позднее связывание

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

В следующем примере оператор b.MyPrint() будет вызывать различные методы в зависимости от типа объекта, для которого он выполняется:

class B{    void MyPrint () {     }}
class B1 extends B{
    void MyPrint () {    
        //Переопределение метода
                }
}
class B2 extends B{
    void MyPrint () {    
        //Переопределение метода
    }
}
class B3 extends B{
    void MyPrint () {        
        //Переопределение метода
    }
}
class PrintB{
    B DoBObject () {    
        // Метод, реализующий класс B
        B b;
            b= new B1();
            …
            b= new B2();
            …
            b= new B3();
            …
            return b;
    }
...
B b= new PrintB().DoBObject();
    b.MyPrint();      
    // Выполняет вызов метода MyPrint в 
    // соответствии с типом объекта  b
< Лекция 12 || Лекция 13: 123 || Лекция 14 >
Александр Демьяненко
Александр Демьяненко

Можно ли сдавать один и тот же тест несколько раз?
Или же один и тот же тест можно сдать лишь однажды?

Максим Стогний
Максим Стогний

Добрый день!

Скажите, пожалуйста, если в терминологии объектно-ориентированного программирования функции также называются методами или методами - членами класса, в примере объявления указателя на метод использовали в формальном описании оба названия:

тип_метода (имя_класса::*имя_метода_указателя)
    (список параметров);
тип_функции (*имя_ функции_указателя)
    (список параметров);

при этом можно было  тип_функции во втором описании заменить на тип_метода? Т.е.:

тип_метода (*имя_ метода_указателя)
    (список параметров);