В чем главное преимущество создания абстрактного класса - PullRequest
3 голосов
/ 12 января 2011

Почему мы объявляем класс абстрактным? Я знаю, что это невозможно создать, но зачем давать специальное ключевое слово для этого. Даже «нормальный» класс будет работать так же хорошо и может быть легко разделен на подклассы. так в чем же главное преимущество создания абстрактного класса?

Ответы [ 9 ]

6 голосов
/ 12 января 2011

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

3 голосов
/ 12 января 2011

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

Вы предположили, что абстрактные классы являются избыточными, потому что вы можете определить неполные методы, используя public void methodname(){} - что, безусловно, нормально. Однако, скажем, ваши клиенты наследуют от класса, определенного таким образом, как они узнают, какие методы переопределить? Что произойдет, если они забудут переопределить метод? Теперь у их производного класса есть неполное определение - вы не хотите этого.

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

2 голосов
/ 12 января 2011

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

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

2 голосов
/ 12 января 2011

Абстрактный класс может иметь абстрактные методы и «конкретные» методы.

«Конкретные» методы могут использовать абстрактные методы и могут быть уверены, что они (правильные) выполняются во время выполнения.Потому что каждый (не абстрактный) подкласс должен их реализовывать.(И это не будет экземпляром абстрактного класса itselfe).

Так что все дело в сохранности!- Это гарантирует, что программист, который хочет создать подкласс абстрактного класса, должен реализовать абстрактный метод (ы).

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

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

2 голосов
/ 12 января 2011

Объявление абстрактного класса не позволяет любому коду создавать экземпляр класса.

Это обеспечивает соблюдение руководства по проектированию для абстрагирования не листовых классов.

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

Ключевое слово abstract работает даже в том случае, если в классе без листьев нет абстрактных методов.

0 голосов
/ 10 января 2015

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

Если вы просто используете классы Abstract только из-за наследования, вы можете столкнуться с проблемами, если код сильно изменится.Это очень подробно описано в приведенном здесь примере: Интерфейсы против абстрактных классов в Java , для различных типов доменных объектов двигателей.Для одного из них требовался двигатель с двойным питанием, а не отдельный тип, например, двигатель с автономным питанием или двигатель с батарейным питанием.Это потребовало использования нескольких методов реализации подкласса от обоих типов двигателей в одном подклассе, и именно здесь абстрактные классы могут запутаться.объекты будут делать) с интерфейсами, а не в абстрактных классах.На мой взгляд, основным преимуществом абстрактных классов является то, что в центре внимания варианта использования находится иерархия реализации и повторное использование кода из подклассов.

0 голосов
/ 12 января 2011

Вы бы объявили класс абстрактным, если создавать его экземпляр практически бессмысленно (вы бы создавали экземпляры подклассов).

public abstract class Shape {
    public double calculateArea();
}

public class Square : Shape {
    private double side;

    double calculateArea() {
        return side*side;
    }
}

public class Circle: Shape {
    private double radius;

    double calculateArea() {
        return 3.1415 * radius * radius;
    }
}

public class MainClass() {
    public static void Main() {
        Shape myShape = new Square();
        system.out.print(myShape.calculateArea());
        myShape = new Circle();
    }
}

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

0 голосов
/ 12 января 2011

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

Абстрактные классы также могут вызывать абстрактные методы, которые в результате вызывают метод расширения объекта. В любом случае, существует много дискуссий о том, когда использовать абстрактные классы, когда отдавать предпочтение интерфейсу. Сделайте поиск в Google, это эпическое обсуждение :) интерфейсы против абстрактных классов.

0 голосов
/ 12 января 2011

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

Вы должны увидеть это как скелетный класс.

Например, я однажды сделал класс с такими характеристиками:

  1. Управляет процессом выполнения команды в другом потоке и передает события этого процесса.

  2. Сам класс не имел какой-либо функциональности сам по себе (не реализовал фактическую функцию work ())

Таким образом, результатом является абстрактный класс, который может быть унаследован, который уже имеет встроенный элемент управления потоком, и все, что вам нужно сделать, это просто реализовать метод work ().

...