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

Что такое "абстрактный класс" в Java?

Ответ 1

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

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

Вот пример:

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().

Однако из-за ключевого слова 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(): никакие другие реализации не будут разрешены.

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

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()"
}

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

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

// 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
}

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

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

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

interface InterfaceA
{
    void interfaceMethod();
}

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

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

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

Неправильно следующее:

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

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

Ответ 2

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

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

public abstract void myMethod()

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

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

abstract class MyClass

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

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

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

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

Ответ 3

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

Основные вещи абстрактного класса

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

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

    например: abstract void moveTo(double deltaX, double deltaY);

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

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

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

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

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

abstract class AbstractDemo{ }

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

abstract void moveTo();//no body

Почему нам нужно абстрагировать классы

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

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

Сначала вы объявляете абстрактный класс GraphicObject для предоставления переменных-членов и методов, которые полностью используются всеми подклассами, такими как текущая позиция и метод moveTo. GraphicObject также объявляет абстрактные методы, такие как рисование или изменение размера, которые должны быть реализованы всеми подклассами, но должны быть реализованы различными способами. Класс 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();
}

Использование абстрактного метода в подклассах Каждый неабстрактный подкласс 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

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

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

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

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

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

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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

Пример:

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();
}

Ответ 6

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

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

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

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

Edit:

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

Ответ 7

От oracle документация

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

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

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

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

abstract void moveTo(double deltaX, double deltaY);

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

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

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

Так как abstract classes и interfaces связаны, см. ниже вопросы SE:

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

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

Ответ 9

Решение - базовый класс (аннотация)

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();

}

Ответ 10

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

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

Ответ 11

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

abstract class Foo {
    abstract void someMethod();
}

или косвенно

interface IFoo {
    void someMethod();
}

abstract class Foo2 implements IFoo {
}

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

abstract class Foo3 {
}

class Bar extends Foo3 {

}

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

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

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

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
    }
}

Ответ 12

Класс, который может иметь как конкретные, так и не конкретные методы, т.е. с телом и без него.

  1. Методы без реализации должны содержать ключевое слово abstract.
  2. Абстрактный класс не может быть создан.

Ответ 13

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

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

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

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();  
    }  
} 

Ответ 14

Члены класса

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

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

Ответ 15

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

Ответ 16

Он ничего не делает, просто предоставляет общий шаблон, который будет предоставлен для его подкласса.