1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wizardforcel-thinking-in-java-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
7.4 抽象类和方法.md 8.9 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 11.03.2025 09:15 d56454c

7.4 Абстрактные классы и методы

Во всех наших примерах с музыкальными инструментами (Instrument), методы внутри базового класса Instrument являются обязательно "фиктивными". При вызове этих методов возникают ошибки. Это происходит потому, что цель класса Instrument — создание общего интерфейса для всех производных от него классов.

Основной причиной создания этого общего интерфейса является возможность представления различных подтипов различными способами. Он предоставляет нам базовый шаблон, который позволяет определять некоторые вещи как "общие" для всех производных классов. Чтобы проиллюстрировать эту идею, можно назвать класс Instrument "абстрактным базовым классом" (АБК). Для работы со множеством классов через этот общий интерфейс требуется создать абстрактный класс. Все методы производных классов, соответствующие сигнатуре метода в базовом классе, могут быть вызваны через механизм динамической привязки (хотя, как было указано ранее, если имя метода совпадает с именем метода в базовом классе, но отличается набором аргументов, это может привести к перегрузке).Если есть абстрактный класс, такой как Instrument, объекты этого класса практически всегда не имеют смысла. Другими словами, роль класса Instrument заключается в том, чтобы представлять интерфейс, а не конкретную реализацию. Таким образом, создание объекта типа Instrument не имеет смысла, и мы обычно должны запрещать пользователям делать это. Для достижения этой цели все методы внутри класса Instrument могут выводить сообщение об ошибке. Однако такое решение замедляет получение информации до этапа выполнения программы и требует полного и надёжного тестирования со стороны пользователя. В любом случае, лучшим решением является выявление проблемы во время компиляции.Для решения этой задачи Java предлагает специальный механизм, называемый абстрактным методом. Это метод, который содержит только объявление, но не имеет тела метода. Ниже представлен синтаксис объявления абстрактного метода:

abstract void X();

Класс, содержащий один или несколько абстрактных методов, сам должен быть объявлен как abstract. В противном случае компилятор сообщит об ошибке.

Что произойдет, если кто-то попытается создать объект от неполного абстрактного класса? Поскольку безопасно создать объект от абстрактного класса невозможно, компилятор сообщит об ошибке. Такой подход гарантирует "чистоту" абстрактного класса, и мы можем быть уверены, что он не будет использоваться некорректно. Если производить наследование от абстрактного класса и хотеть создать объект нового типа, то необходимо предоставить реализацию всех абстрактных методов, объявленных в базовом классе. В противном случае (что вполне возможно), производный класс также будет считаться абстрактным, а компилятор заставит нас пометить этот класс как «абстрактный» с помощью ключевого слова abstract.

Даже если класс не содержит ни одного абстрактного метода, его можно объявить как «абстрактный». Это может оказаться полезным, когда нам требуется запретить создание экземпляров данного класса.Класс Instrument легко можно преобразовать в абстрактный класс. Только некоторые из его методов станут абстрактными, поскольку превращение класса в абстрактный не требует автоматического объявления всех его методов как абстрактных. Вот как это выглядит:

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

//: Music4.java
// Абстрактные классы и методы
import java.util.*;

public abstract class Instrument4 {
  protected int i; // Хранение, выделенное для каждого
  public abstract void play();
  public String what() {
    return "Instrument4";
  }
  public abstract void adjust();
}

public class Wind4 extends Instrument4 {
  @Override
  public void play() {
    System.out.println("Wind4.play()");
  }

  @Override
  public String what() {
    return "Wind4";
  }

  @Override
  public void adjust() {}
}

public class Percussion4 extends Instrument4 {
  @Override
  public void play() {
    System.out.println("Percussion4.play()");
  }

  @Override
  public String what() {
    return "Percussion4";
  }

  @Override
  public void adjust() {}
}

public class Stringed4 extends Instrument4 {
  @Override
  public void play() {
    System.out.println("Stringed4.play()");
  }

  @Override
  public String what() {
    return "Stringed4";
  }

  @Override
  public void adjust() {}
}

public class Brass4 extends Wind4 {
  @Override
  public void play() {
    System.out.println("Brass4.play()");
  }

  @Override
  public void adjust() {
    System.out.println("Brass4.adjust()");
  }
}

public class Woodwind4 extends Wind4 {
  @Override
  public void play() {
    System.out.println("Woodwind4.play()");
  }
}
```  @Override
  public String what() {
    return "Дудочник4";
  }
}
``````markdown
публичный класс Music4 {
  // Независим от типа, поэтому новые типы,
  // добавленные в систему, всё ещё работают правильно:
  статический void tune(Instrument4 i) {
    // ...
    i.play();
  }
  статический void tuneAll(Instrument4[] e) {
    для(int i = 0; i < e.length; i++)
      tune(e[i]);
  }
  публичный статический void main(String[] args) {
    Instrument4[] оркестр = новый Instrument4[5];
    int i = 0;
    // Поднятие типа при добавлении в массив:
    оркестр[i++] = новый Wind4();
    оркестр[i++] = новый Percussion4();
    оркестр[i++] = новый Stringed4();
    оркестр[i++] = новый Brass4();
    оркестр[i++] = новый Дудочник4();
    tuneAll(оркестр);
  }
} ///:~

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

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/wizardforcel-thinking-in-java-zh.git
git@api.gitlife.ru:oschina-mirror/wizardforcel-thinking-in-java-zh.git
oschina-mirror
wizardforcel-thinking-in-java-zh
wizardforcel-thinking-in-java-zh
master