Абстрактный class в Java

Что такое «абстрактный class» в Java?

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

  1. Определите методы, которые могут использоваться наследующим подclassом.
  2. Определите абстрактные методы, которые должен реализовать наследующий подclass.
  3. Предоставьте общий интерфейс, который позволяет переclassифицировать подclass со всеми другими подclassами.

Вот пример:

abstract public class AbstractClass { abstract public void abstractMethod(); public void implementedMethod() { System.out.print("implementedMethod()"); } final public void finalMethod() { System.out.print("finalMethod()"); } } 

Обратите внимание, что «abstractMethod ()» не имеет никакого тела метода. Из-за этого вы не можете сделать следующее:

 public class ImplementingClass extends AbstractClass { // ERROR! } 

Нет метода, который реализует abstractMethod() ! Таким образом, JVM не может понять, что он должен делать, когда он получает что-то вроде new ImplementingClass().abstractMethod() .

Вот правильный ImplementingClass .

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } } 

Обратите внимание, что вам не нужно определять implementedMethod() или finalMethod() . Они уже были определены AbstractClass .

Вот еще один правильный ImplementingClass .

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } } 

В этом случае вы переопределили implementedMethod() метод implementedMethod() .

Однако из-за final ключевого слова невозможно.

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } public void finalMethod() { System.out.print("ERROR!"); } } 

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

Теперь вы также можете реализовать абстрактный class дважды:

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } } // In a separate file. public class SecondImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("second abstractMethod()"); } } 

Теперь где-нибудь вы можете написать другой метод.

 public tryItOut() { ImplementingClass a = new ImplementingClass(); AbstractClass b = new ImplementingClass(); a.abstractMethod(); // prints "abstractMethod()" a.implementedMethod(); // prints "Overridden!" <-- same a.finalMethod(); // prints "finalMethod()" b.abstractMethod(); // prints "abstractMethod()" b.implementedMethod(); // prints "Overridden!" <-- same b.finalMethod(); // prints "finalMethod()" SecondImplementingClass c = new SecondImplementingClass(); AbstractClass d = new SecondImplementingClass(); c.abstractMethod(); // prints "second abstractMethod()" c.implementedMethod(); // prints "implementedMethod()" c.finalMethod(); // prints "finalMethod()" d.abstractMethod(); // prints "second abstractMethod()" d.implementedMethod(); // prints "implementedMethod()" d.finalMethod(); // prints "finalMethod()" } 

Обратите внимание, что, хотя мы объявили тип AbstractClass , он отображает "Overriden!" , Это связано с тем, что объект, который мы создали, был фактически реализованным ImplementingClass , чей implementedMethod() метод implementedMethod() конечно, переопределен. (Возможно, вы видели, что это называется polymorphismом.)

Если мы хотим получить доступ к определенному элементу для конкретного подclassа, мы должны сначала отбросить этот подclass:

 // Say ImplementingClass also contains uniqueMethod() // To access it, we use a cast to tell the runtime which type the object is AbstractClass b = new ImplementingClass(); ((ImplementingClass)b).uniqueMethod(); 

Наконец, вы не можете сделать следующее:

 public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass { ... // implementation } 

За один раз можно продлить только один class. Если вам нужно расширить несколько classов, они должны быть интерфейсами. Вы можете сделать это:

 public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB { ... // implementation } 

Вот пример интерфейса:

 interface InterfaceA { void interfaceMethod(); } 

Это в основном то же самое, что:

 abstract public class InterfaceA { abstract public void interfaceMethod(); } 

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

Недопустимо следующее:

 interface InterfaceB { void interfaceMethod() { System.out.print("ERROR!"); } } 

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

Класс Java становится абстрактным при следующих условиях:

1. По крайней мере один из методов отмечен как абстрактный:

 public abstract void myMethod() 

В этом случае компилятор заставляет вас отмечать весь class как абстрактный.

2. Класс отмечен как абстрактный:

 abstract class MyClass 

Как уже было сказано: если у вас есть абстрактный метод, компилятор заставляет вас отмечать весь class как абстрактный. Но даже если у вас нет абстрактного метода, вы все равно можете пометить class как абстрактный.

Общего пользования:

Обычное использование абстрактных classов – это создание схемы classа, аналогичного интерфейсу. Но в отличие от интерфейса он уже может обеспечить функциональность, то есть некоторые части classа реализованы, а некоторые части просто обозначены объявлением метода. (“Абстрактные”)

Абстрактный class не может быть создан, но вы можете создать конкретный class на основе абстрактного classа, который затем может быть создан. Для этого вам нужно наследовать от абстрактного classа и переопределить абстрактные методы, т. Е. Реализовать их.

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

Основные элементы абстрактного classа

  • Абстрактный class может содержать или не содержать абстрактные методы. Могут быть абстрактные методы.

    Абстрактный метод – это метод, объявленный без реализации (без фигурных скобок и с запятой), например:

    ex: abstract void moveTo(double deltaX, double deltaY);

  • Если class имеет хотя бы один абстрактный метод, то этот class должен быть абстрактным

  • Абстрактные classы не могут быть созданы (вам не разрешено создавать объект classа Abstract)

  • Чтобы использовать абстрактный class, вы должны наследовать его из другого classа. Обеспечьте реализацию всех абстрактных методов в нем.

  • Если вы наследуете абстрактный class, вы должны обеспечить реализацию всех абстрактных методов в нем.

Объявить абстрактный class Задание abstract ключевого слова перед classом во время объявления делает его абстрактным. Посмотрите на код ниже:

 abstract class AbstractDemo{ } 

Объявление абстрактного метода. Определение abstract ключевого слова перед методом во время объявления делает его абстрактным. Посмотрите на код ниже,

 abstract void moveTo();//no body 

Почему нам нужно отделять classы

В объектно-ориентированном приложении рисования вы можете рисовать круги, прямоугольники, линии, кривые Безье и многие другие графические объекты. Все эти объекты имеют определенные состояния (например: положение, ориентация, цвет линии, цвет заливки) и поведение (для ex -: moveTo, rotate, resize, draw). Некоторые из этих состояний и поведения одинаковы для всех графических объектов (например: цвет заливки, положение и moveTo). Другие требуют различной реализации (например: изменение размера или рисование). Все графические объекты должны иметь возможность рисовать или изменять размеры, они просто отличаются тем, как они это делают.

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

Во-первых, вы объявляете абстрактный class GraphicObject для предоставления переменных-членов и методов, которые полностью разделяются всеми подclassами, такими как текущая позиция и метод moveTo. GraphicObject также объявляет абстрактные методы, такие как рисование или изменение размера, которые должны быть реализованы всеми подclassами, но должны быть реализованы по-разному. Класс GraphicObject может выглядеть примерно так:

 abstract class GraphicObject { void moveTo(int x, int y) { // Inside this method we have to change the position of the graphic // object according to x,y // This is the same in every GraphicObject. Then we can implement here. } abstract void draw(); // But every GraphicObject drawing case is // unique, not common. Then we have to create that // case inside each class. Then create these // methods as abstract abstract void resize(); } 

Использование абстрактного метода в подclassах Каждый неабстрактный подclass объекта GraphicObject , такой как Circle и Rectangle , должен обеспечивать реализации методов draw и resize .

 class Circle extends GraphicObject { void draw() { //Add to some implementation here } void resize() { //Add to some implementation here } } class Rectangle extends GraphicObject { void draw() { //Add to some implementation here } void resize() { //Add to some implementation here } } 

Внутри main метода вы можете вызвать все такие методы:

 public static void main(String args[]){ GraphicObject c = new Circle(); c.draw(); c.resize(); c.moveTo(4,5); } 

Способы достижения абстракции в Java

Существует два способа достижения абстракции в java

  • Абстрактный class (от 0 до 100%)
  • Интерфейс (100%)

Абстрактный class с конструкторами, членами данных, методами и т. Д.

 abstract class GraphicObject { GraphicObject (){ System.out.println("GraphicObject is created"); } void moveTo(int y, int x) { System.out.println("Change position according to "+ x+ " and " + y); } abstract void draw(); } class Circle extends GraphicObject { void draw() { System.out.println("Draw the Circle"); } } class TestAbstract { public static void main(String args[]){ GraphicObject grObj = new Circle (); grObj.draw(); grObj.moveTo(4,6); } } 

Вывод:

 GraphicObject is created Draw the Circle Change position according to 6 and 4 

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

  • Если class имеет несколько абстрактных методов и несколько конкретных методов, объявите его abstract classом.

  • Если class имеет только абстрактные методы, объявите его как interface .

Рекомендации:

  • TutorialsPoint – Java Абстракция
  • BeginnersBook – метод абстрактного classа Java
  • Java Docs – Абстрактные методы и classы
  • JavaPoint – абстрактный class в Java

Это class, который не может быть создан, и заставляет внедрять classы, возможно, реализовать абстрактные методы, которые он описывает.

Из документации oracleа

Абстрактные методы и classы:

Абстрактный class – это class, объявленный абстрактом – он может включать или не включать абстрактные методы

Абстрактные classы не могут быть созданы, но они могут быть подclassами

Абстрактный метод – это метод, объявленный без реализации (без фигурных скобок и с запятой), например:

 abstract void moveTo(double deltaX, double deltaY); 

Если class включает абстрактные методы, то сам class должен быть объявлен абстрактным, как в:

 public abstract class GraphicObject { // declare fields // declare nonabstract methods abstract void draw(); } 

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

Поскольку abstract classes и interfaces связаны между собой, посмотрите ниже вопросы SE:

В чем разница между интерфейсом и абстрактным classом?

Как я должен объяснить разницу между интерфейсом и абстрактным classом?

Получите ваши ответы здесь:

Абстрактный class vs Интерфейс в Java

Может ли абстрактный class иметь окончательный метод?

Кстати – это вопрос, который вы задали недавно. Подумайте о новом вопросе, чтобы создать репутацию …

Редактировать:

Просто понял, что плакаты этого и связанных вопросов имеют одинаковое или, по крайней мере, похожее имя, но идентификатор пользователя всегда отличается. Так или есть, есть техническая проблема, что у keyur проблемы возникают снова и найти ответы на его вопросы, или это своего рода игра, чтобы развлечь SO-сообщество;)

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

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

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

 public abstract class MyAbstractClass{ public abstract void DoSomething(); } 

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

Пример:

 public abstract class MyAbstractClass{ public int CalculateCost(int amount){ //do some default calculations //this can be overriden by subclasses if needed } //this MUST be implemented by subclasses public abstract void DoSomething(); } 

Небольшое дополнение ко всем этим сообщениям.

Иногда вы можете захотеть объявить class и все же не знаете, как определить все методы, принадлежащие этому classу. Например, вы можете объявить class Writer и включить в него метод-член, называемый write () . Однако вы не знаете, как писать код write (), потому что он отличается для каждого типа устройств Writer. Конечно, вы планируете обрабатывать это путем получения подclassа Writer, такого как принтер, диск, сеть и консоль.

Абстрактный class не может быть непосредственно создан, но должен быть получен из пригодного для использования. Класс ДОЛЖЕН быть абстрактным, если он содержит абстрактные методы: либо напрямую

 abstract class Foo { abstract void someMethod(); } 

или косвенно

 interface IFoo { void someMethod(); } abstract class Foo2 implements IFoo { } 

Однако class может быть абстрактным без абстрактных методов. Его способ предотвратить прямое создание, например

 abstract class Foo3 { } class Bar extends Foo3 { } Foo3 myVar = new Foo3(); // illegal! class is abstract Foo3 myVar = new Bar(); // allowed! 

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

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

 abstract class Processor { protected abstract int[] filterInput(int[] unfiltered); public int process(int[] values) { int[] filtered = filterInput(values); // do something with filtered input } } class EvenValues extends Processor { protected int[] filterInput(int[] unfiltered) { // remove odd numbers } } class OddValues extends Processor { protected int[] filterInput(int[] unfiltered) { // remove even numbers } } 

Решение – базовый class (аннотация)

 public abstract class Place { String Name; String Postcode; String County; String Area; Place () { } public static Place make(String Incoming) { if (Incoming.length() < 61) return (null); String Name = (Incoming.substring(4,26)).trim(); String County = (Incoming.substring(27,48)).trim(); String Postcode = (Incoming.substring(48,61)).trim(); String Area = (Incoming.substring(61)).trim(); Place created; if (Name.equalsIgnoreCase(Area)) { created = new Area(Area,County,Postcode); } else { created = new District(Name,County,Postcode,Area); } return (created); } public String getName() { return (Name); } public String getPostcode() { return (Postcode); } public String getCounty() { return (County); } public abstract String getArea(); } 

Класс, который может иметь как бетонные, так и небедные методы, т. Е. С телом и без тела. 1-методы без реализации должны содержать «абстрактный» ключевой слово. 2-абстрактный class не может быть создан

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

Другими словами, class, объявленный с абстрактным ключевым словом, известен как абстрактный class в java. Он может иметь абстрактный (метод без тела) и не абстрактные методы (метод с телом).

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

 abstract class Bike{ abstract void run(); } class Honda4 extends Bike{ void run(){ System.out.println("running safely.."); } public static void main(String args[]){ Bike obj = new Honda4(); obj.run(); } } 

Участники classа

Абстрактный class может иметь статические поля и статические методы. Вы можете использовать эти статические члены с ссылкой на class (например, AbstractClass.staticMethod ()), как и с любым другим classом.

Не забывайте об этом.

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

  • Java получает ошибку для реализации интерфейса с более слабым доступом
  • Почему оба родительского и дочернего classов реализуют один и тот же интерфейс?
  • Что означает «программа для интерфейсов, а не реализации»?
  • Как создать интерфейс между fragmentом и адаптером?
  • Интерфейсы C # - В чем смысл?
  • Интерфейсы наследуются от classа Object в java
  • Не публичные пользователи для интерфейсов C #
  • BeanFactory vs ApplicationContext
  • Рекомендации по использованию интерфейса Java. Неужели получатели и сеттеры в интерфейсе плохо?
  • сделать JLabel обернуть его текстом, установив максимальную ширину
  • Внедрение интерфейса TypeScript с сигнатурой голосовой функции и другими полями
  • Interesting Posts

    TrueCrypt Macbook Pro Windows 7 больше не загружается с компакт-диска

    Как перенести некоторые данные в другой fragment?

    Android Studio: модуль не будет отображаться в «Редактирование конфигурации»

    Лучшая практика для структуры рабочего каталога проекта Django

    Проблемы с настройкой Dual Monitor между ноутбуком и внешним монитором

    Где хранить JWT в браузере? Как защитить от CSRF?

    Выделяемая функция с оценкой массива. gfortran против ifort

    SyntaxError: использование const в строгом режиме?

    Windows 7 не может автоматически подключаться к сетевому диску SAMBA с использованием общих учетных данных SAMBA

    C – попытка чтения одного символа из stdin (и сбоя) w / scanf / getchar

    Как добавить системное время в панель инструментов VLC?

    Почему мои наушники не требуют драйверов?

    Невозможно установить свойство только для чтения в папку temp

    почему я получаю «Должен переводить авторезистирующую маску в ограничения, чтобы иметь _setHostsLayoutEngine: YES» в xcode 6 beta

    Как передать параметры методу DbContext.Database.ExecuteSqlCommand?

    Давайте будем гением компьютера.