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

 

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

 

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

 

abstract class worker

{

protected int Age;

public String Name;

abstract public void setSalary(int newSalary);

...

}

class boss extends worker

{

//Пишем реализацию абстрактного метода родительского класса

public void setSalary(int newSalary)

{

if(newSalary>=0)

Salary=newSalary;

else

Salary=3000;

}

...

}

class еngineer extends worker

{

//Пишем реализацию абстрактного метода родительского класса

public void setSalary(int newSalary)

{

if(newAge>=0)

Salary=newSalary;

else

Salary=2500;

}

...

}

 

Тут мы объявили класс worker, написали в нем абстрактный метод setSalary, и объявили два класса-потомка класса worker - классы boss и еngineer. В каждым из их мы пишем свою реализацию для метода setSalary.

 

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

abstract class worker

...

 

Экземпляры абстрактного классы мы создавать не сможем - только экземпляры его потомков.

 

Для чего вообще возиться с абстрактными методами? Не проще ли его в классе предке вообще не объявлять? Дело в том, что вы можете в переменную типа родительского класса записать экземпляр класса потомка:

worker bigBoss=new boss();

 

Это значит, что вы можете в вашем программе объявить массив worker'ов, и записать в него всех работников - и инженеров, и директоров и простых работников. И тогда, если вам надо начислить зарплату для всех, то вы просто перебираете элементы этого массива.