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

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

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


person ryanzec    schedule 05.07.2010    source источник
comment
Не могли бы минусаторы объяснить, почему вы минусуете ответы?!?!   -  person jyoungdev    schedule 07.07.2010


Ответы (9)


Строго с точки зрения дизайна, лучше все упростить. Я считаю, что лучший способ упростить ситуацию — использовать простую аналогию. Проведем аналогию с птицами...

Интерфейс: используйте это, когда вы хотите применить определенные функции, которые необходимо определить. например У IBird есть контракт на ScreamLikeABird и Fly (функции интерфейса). Но вы можете получить более конкретную информацию и иметь IOstrich с контрактом Run. У вас также может быть IHawk с контрактом на атаку и т. д.

Аннотация: используйте это, когда вы хотите применить базовые функции и иметь базовые свойства. например Avian может быть базовым классом для птиц, который может иметь функцию LayEgg, а также свойства Age, Species, NumberOfChicks и т. д. Эти вещи не меняют/не должны менять поведение птиц, так как все птицы откладывают яйца... и т.д. Но не все птицы звучат одинаково, когда кричат ​​или летают одинаково (некоторые даже не летают)... и т.д.... поэтому они должны быть реализованы через интерфейс(ы).

person AlvinfromDiaspar    schedule 05.07.2010
comment
Непрактичная аналогия с животными была использована, чтобы облегчить путаницу между интерфейсом и абстракцией. Кстати, насколько непрактично любое исполнение Hello World? Практичность здесь ни при чем. Кроме того, я вижу, что эта аналогия чрезвычайно удобна во многих приложениях и/или играх. - person AlvinfromDiaspar; 19.07.2010
comment
@AlvinfromDiaspar +1 Ну, я думаю, это самое простое объяснение в мире. - person Rohit; 07.09.2013
comment
Не совсем отвечая на вопрос. Вопрос заключался в разнице между абстрактными и обычными классами, поскольку он знал разницу между интерфейсом и абстрактным... - person Calin Bolea; 26.06.2014
comment
Я люблю приложение к животному миру. Я думаю, что это один из лучших примеров, которые я когда-либо видел! - person Tom Russell; 29.11.2015
comment
Согласитесь с Калином Болеа, даже не близко к вопросу, автор прямо говорит, что я понимаю разницу между интерфейсом и абстрактным классом. Вопрос был об обычном и абстрактном классе. - person ggat; 10.05.2016

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

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

person Jani Hartikainen    schedule 05.07.2010
comment
Даже если класс не имеет каких-либо абстрактных членов и созданные экземпляры имеют четко определенное поведение, может быть разумно определить класс как абстрактный, если он не содержит ничего, что отличало бы экземпляры друг от друга. Например, можно определить базовый класс ImmutableList<T> с подклассами для ArrayBackedImmutableList<T>, ComputedImmutableList<T>, LazyImmutableList<T> и т. д. Хотя экземпляры базового класса могут вести себя как список с нулевыми элементами, было бы чище определить конкретный класс EmptyImmutableList<T>. для такой цели. - person supercat; 17.06.2013

В мире OO абстрактные классы накладывали некоторые ограничения на дизайн и реализацию. Больше ничего. Вам никогда не придется использовать абстрактные классы в любом случае. Но могут быть случаи, когда вам лучше наложить эти ограничения. Так что же это такое? Давайте посмотрим, сравнив его оо-аналоги.

Абстрактные классы и интерфейсы

Как вы знаете, это две основные концепции наследования.

По сути, интерфейс используется только для того, чтобы объявить, что вы хотите наследовать базовую службу, и все. Не содержит реализации и не имеет функциональности. В этом смысле интерфейс абстрактен. Вот почему это больше ограничение дизайна, чем ограничение реализации. Подумайте о разъеме для наушников на динамике. В каждом наушнике должен быть реализован интерфейс разъема (с методами start, stop, listen, TurnDown, TurnUp). Каждый наушник должен переопределить этот интерфейс, чтобы наследовать функциональные возможности, предоставляемые динамиком, и реализовывать их соответствующим образом.

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

Конечно, не говоря уже о том, что вы можете расширить только один класс в java, в котором вы можете реализовать несколько интерфейсов.

Абстрактные классы и обычные классы

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

person stdout    schedule 10.11.2015
comment
Под братьями вы подразумеваете дочерний элемент, учитывая, что абстракция будет унаследована классом, что сделает его родителем. Верно ? - person Daniyal Nasir; 08.02.2018
comment
@DaniyalNasir да. - person stdout; 08.02.2018
comment
Вы только что объяснили мне то, что другие не смогли. Спасибо - person Mrs.Brightside; 07.09.2018
comment
Согласен с Брайтом. Это ответ! Я удивлен, как выдающиеся участники, такие как Эл и Яни (на основании их представителей), полностью обошли проблему, поднятую ОП. Ответ стандартного вывода (особенно последний абзац) напрямую касается вопроса и отвечает на него. - person Shashank Sawant; 03.06.2020

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

abstract class Test
{
    abstract void show();//method provided
}
class Child extends Test
{
    void show()//coding 
    {
        System.out.println("saurav");
    }
}
class main
{
    public static void main(String[] args) 
    {
    Test c = new Child();
    c.show();   
    }
}
person saurav    schedule 19.06.2017

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

person No name    schedule 25.04.2017

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

person Gleb M    schedule 13.12.2015

С точки зрения автомобильного производства, интерфейс — это спецификация «автомобиля», в котором говорится, что у него четыре колеса, пять сидений, двигатель и т. д., а абстрактный класс — это частично собранный автомобиль в ящике, который вы должны довести до конца. ваши собственные требования. Например. Subaru использует точно такое же шасси для Impreza, Forester и XV/Crosstrek. Таким образом, шасси — это «абстрактный класс», который имеет общие черты и функции, но еще не является «автомобилем». Кузов и интерьер ДОЛЖНЫ быть добавлены постфактум, прежде чем вы сможете сказать, что построили машину. Двигатель также является общим для всех трех, хотя вы можете заменить его на версию с турбонаддувом, если хотите.

person Captain Kenpachi    schedule 03.06.2020

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

abstract class Avehicle    
{  
        string fuel;  
        public void move()  
{  
 sysout("moving");  
}   
} 

но у всех автомобилей тормозная система разная

interface Ivehicle    
{  

        public void breakorstop();  
}  
class Traveler    
{  
  Ivehicle v; 
//Settrers and getters   
 public drive()  
{  
v.move();  
}  
public break()  
{  
v.breakorstop();  
}  
}

Итак, наконец, классы Car, Cycle или Bike могут расширять Avehicle и могут реализовывать интерфейс Vehicle.

person MyStack    schedule 28.02.2013

Абстрактные классы могут использоваться для хранения методов в «библиотеке» на основе ООП; поскольку экземпляр класса не нужно создавать, и в этом нет особого смысла, сохранение общих статических методов внутри абстрактного класса является обычной практикой.

person amphetamachine    schedule 05.07.2010
comment
В Java вы также можете объявить класс окончательным, чтобы он не расширялся. Нет, ты не можешь. abstract + final не допускается. Если ваш класс предназначен исключительно для статических служебных методов, он, вероятно, должен быть конечным классом с частным (неиспользуемым) конструктором. - person Matthew Flaschen; 06.07.2010
comment
@Matthew Flaschen: точка зрения принята. Спасибо за разъяснения. - person amphetamachine; 06.07.2010
comment
Статические методы не являются основной причиной создания абстрактных классов. - person jyoungdev; 07.07.2010