Вы находитесь на странице: 1из 12

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

Абстрактный класс - это класс, который не может быть


создан. Абстрактный класс используется для создания
наследующего подкласса, который может быть создан.
Абстрактный класс делает несколько вещей для
наследуемого подкласса:
1. Определить методы, которые могут
использоваться наследующим подклассом.
2. Определить абстрактные методы, которые должен
реализовать наследующий подкласс.
3. Предоставляет общий интерфейс, который
позволяет переклассифицировать подкласс со
всеми другими подклассами.
Класс, который объявлен с
использованием абстрактного ключевого слова,
называется abstract class. Абстракция - это процесс
скрытия деталей реализации данных и отображения
только функциональных возможностей для
пользователя. Абстракция позволяет вам
сосредоточиться на том, что делает объект, а не на
том, как он это делает.
Основные вещи абстрактного класса
1. Абстрактный класс может содержать или не
содержать абстрактные методы. Это могут быть не
абстрактные методы.
Абстрактный метод - это метод, который объявлен
без реализации (без фигурных скобок и
сопровождается точкой с запятой), например:
например: abstract void moveTo(double deltaX,
double deltaY);
2. Если у класса есть хотя бы один абстрактный
метод, тогда этот класс должен быть абстрактным
3. Абстрактные классы не могут быть созданы (Вы не
можете создавать объекты класса Abstract)
4. Чтобы использовать абстрактный класс, вы
должны наследовать его от другого класса.
Предоставить реализации для всех абстрактных
методов в нем.
5. Если вы наследуете абстрактный класс, вы
должны предоставить реализации для всех
абстрактных методов в нем.
Объявление абстрактного
класса Указание abstract ключевого слова перед
классом во время объявления делает его
абстрактным. Посмотрите на код ниже:
abstract class AbstractDemo{ }
Объявление абстрактного
метода Указание abstract ключевого слова перед
методом во время объявления делает его
абстрактным. Посмотрите на код ниже,
abstract void moveTo();//нет тела

Вот пример:
public abstract class AbstractClass
{
public abstract void abstractMethod();
public void implementedMethod()
{ System.out.print("implementedMethod()"); }
public final 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();
Почему нам нужно абстрагировать классы
В объектно-ориентированном приложении для
рисования вы можете рисовать круги, прямоугольники,
линии, кривые Безье и многие другие графические
объекты. Все эти объекты имеют определенные
состояния (например, положение, ориентация, цвет
линии, цвет заливки) и общее поведение (например,
перемещение, поворот, изменение размера,
рисование). Некоторые из этих состояний и поведения
одинаковы для всех графических объектов (например,
цвет заливки, положение и перемещение). Другие
требуют другой реализации (например, изменить
размер или нарисовать). Все графические объекты
должны уметь рисовать или изменять размеры сами,
они просто отличаются тем, как они это делают.
Это идеальная ситуация для абстрактного
суперкласса. Вы можете воспользоваться сходствами
и объявить все графические объекты наследуемыми
от того же абстрактного родительского объекта
(например, GraphicObject), как показано на
следующем рисунке.

Сначала вы объявляете абстрактный


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

void moveTo(int x, int y) {


// Внутри этого метода мы должны изменить
положение графика
// объект в соответствии с х, у
// Это то же самое в каждом GraphicObject.
Тогда мы можем реализовать здесь.
}

abstract void draw(); // Но каждый случай


рисования GraphicObject уникальный, не
распространенный. Тогда мы должны создать это
дело внутри каждого класса. Затем создайте эти
методы как абстрактные
abstract void resize();
}
Использование абстрактного метода в
подклассах Каждый неабстрактный
подкласс GraphicObject, такой
как Circle и Rectangle, должен предоставлять
реализации для методов draw и resize.
class Circle extends GraphicObject {
void draw() {
// Добавить к некоторой реализации здесь }
void resize() {
// Добавить к некоторой реализации здесь
}
}
class Rectangle extends GraphicObject {
void draw() {
// Добавить к некоторой реализации здесь
}
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
1. Абстрактный класс (от 0 до 100%)
2. Интерфейс (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
Помните два правила:
1. Если в классе мало абстрактных методов и мало
конкретных методов, объявите его
как abstract класс.
2. Если класс имеет только абстрактные методы,
объявите его как interface.
 

Вам также может понравиться