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

View more Tutorials:

1- Введение

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

2- Абстрактный класс (Abstract Class)

Абстрактный класс (Abstract class). Посмотрим пример:
// Это абстрактный класс.
// Он заставляет объявить как abstract
// так как в нем имеется абстрактный метод
public abstract class ClassA  {

	// Это абстрактный метод.
	// Он не имеет тела (body).
	// Access modifier данного метода является public.
	public abstract void doSomething();

	// Access modifier данного метода является protected.
	protected abstract String doNothing();
	// Данный метод не объявляет access modifier.
	// Его аccess modifier является по умолчанию.
	abstract void todo() ;
}

// Это абстрактный класс.
// Он объявляется как abstract,
// несмотря на то, что он не имеет никакого абстрактного метода.
public abstract class ClassB   {

}
Характеристика абстрактного класса:
  1. Объявлен abstract.
  2. Может объявлять 0, 1 или более абстрактных методо внутри.
  3. Не может инициализировать 1 объект напрямую из абстрактного класса.

3- Абстрактный класс, примеры

Смотрите иллюстрацию:
AbstractJob.java
package org.o7planning.tutorial.abs;

// Абстракный класс (Симулирующий работу)
// Он объявляет 2 абстрактных метода.
public abstract class AbstractJob {

	public AbstractJob() {

	}

	// Это абстрактный метод.
	// Этот метод возвращает название работы.
	public abstract String getJobName();

	// Это абстрактный метод.
	public abstract void doJob();

}
JavaCoding.java
package org.o7planning.tutorial.abs;

// Данный класс выполняет все абстракные методы родительского класса.
public class JavaCoding extends AbstractJob {

	public JavaCoding() {
	}

	// Выполнить абстракный метод объявленный в родительском классе.
	@Override
	public void doJob() {
		System.out.println("Coding Java...");
	}

	// Выполнить абстракный метод объявленный в родительском классе.
	// Этот метод будет иметь тело (body).
	// И возвращает название работы.
	@Override
	public String getJobName() {
		return "Coding Java";
	}

}
ManualJob.java
package org.o7planning.tutorial.abs;

// ManualJob - (Симулирует универсальную работу)
// Родительский класс (AbstractJob) имеет 2 абстрактных метода.
// Этот класс выполняет только 1 абстрактный метод родительского класса.
// Поэтому он должен быть объявлен как abstract.
public abstract class ManualJob extends AbstractJob {

	public ManualJob() {

	}

	// Выполняет абстрактные методы родительского класса.
	@Override
	public String getJobName() {
		return "Manual Job";
	}

}
BuildHouse.java
package org.o7planning.tutorial.abs;

// Этот класс унаследован от абстрактного класса ManualJob
// BuildHouse не может быть объявлен как абстрактный.
// Поэтому он должен выполнить все остальные абстрактные методы.
public class BuildHouse extends ManualJob {

	public BuildHouse() {

	}

	// Выполняет абстрактные методы родительского класса.
	@Override
	public void doJob() {
		System.out.println("Build a House");
	}

}
Пример демо
JobDemo.java
package org.o7planning.tutorial.abs;

public class JobDemo {

	public static void main(String[] args) {

		// Создать объект AbstractJob
		// из Constructor класса JavaCoding.
		AbstractJob job1 = new JavaCoding();

		// Вызвать метод doJob()
		job1.doJob();

		// Метод getJobName является абстрактным в классе AbstractJob.
		// Но он выполнен в определенном подклассе.
		// Поэтому вы можете его вызвать.
		String jobName = job1.getJobName();

		System.out.println("Job Name 1= " + jobName);

		// Создать объект AbstractJob
		// из Constructor класса BuildHouse.
		AbstractJob job2 = new BuildHouse();

		job2.doJob();

		String jobName2 = job2.getJobName();

		System.out.println("Job Name 2= " + jobName2);

	}
}
Результаты запуска примера:

4- Overview of the interface

Мы знаем что класс, может быть расширен из родительского класса.
// Класс B является подклассм A, или можно сказать B расширен из A
// Java позволяет расширить только один класс из другого.
public class B extends A  {
   // ....
}

// В случае не определяется из какого класса расширен класс B.
// По умолчанию, понимается, что В расширен из класса Object.
public class B  {

}

// Данный способ объявления и способ выше являются индентичными.
public class B extends Object  {

}
Но класс может быть расширен из нескольких Interface ( Интерфейсов).
// Класс может быть расширен только из родительского класса.
// Но может выполнить (расширение) из многих Interface.
public class Cat extends Animal implements CanEat, CanDrink {

  // ....
}

Характеристика Interface (интерфейса):

  1. Интерфейс всегда имеет modifier это: public interface, несмотря на то, объявляете ли вы точно или нет.
  2. Если имеются поля (field), то они: public static final, несмотря на то, объявляете ли вы точно или нет.
  3. Его методы являются абстрактными, то есть без основы функцимм, и все имеют modifier: public abstract, несмотря на то, объявляете ли вы или нет.
  4. Интерфейс не имеет конструктора (Constructor).

5- Структура Interface

NoAccessModifierInterface.java
package org.o7planning.tutorial.itf;

// Это интерфейс не определяющий 'access modifier'.
// Его аccess modifier является по умолчанию.
// Только классы одного пакета могут выполнить данный интерфейс.
interface NoAccessModifierInterface {

}
CanMove.java
package org.o7planning.tutorial.itf;

// Данный интерфейс (Interface) определяет стандарт
// про вещи, которые могут двигаться.
public interface CanMove {

	// Методы в Interface все являются абстрактынми и public.
	public abstract void run();

	// Даже если вы не пишете 'public abstract' то java все равно понимает так.
	void back();

	// Скорость.
	public int getVelocity();

}
CanDrink.java
package org.o7planning.tutorial.itf;

// Данный интерфейс (Interface) определяет стандарт
// про вещи которые могут пить.
public interface CanDrink {

	// Поля (field) в Interface все являются 'public static final'.
	// Даже если вы объявляете или нет, java будет понимать так.
	public static final String PEPSI = "PEPSI";
	final String NUMBER_ONE = "NUMBER ONE";
	String SEVENUP = "SEVEN UP";

	public void drink();

}
CanEat.java
package org.o7planning.tutorial.itf;

// Данный интерфейс (Interface) определяет стандарт
// про вещи которые могут кушать.
public interface CanEat {

	public void eat();
}

6- Класс применяющий интерфейс

Animal.java
package org.o7planning.tutorial.cls;

import org.o7planning.tutorial.itf.CanMove;

// Animal (Животное).
// Данный класс раширен от класса Object (Несмотря на то, что не написано).
// И объявлен выполнить (или еще называется унаследовать) interface CanMove.
// Interface CanMove имеет 3 абстрактных метода.
// Этот класс выполняет только 1 метод.
// Поэтому он должен быть объявлен как abstract.
// Остальные абстрактные методы будут выполнены подклассами.
public abstract class Animal implements CanMove {

	// Выполнить метод run() в interface CanMove.
	@Override
	public void run() {
		System.out.println("Animal run...");
	}

}
Cat.java
package org.o7planning.tutorial.cls;

import org.o7planning.tutorial.itf.CanDrink;
import org.o7planning.tutorial.itf.CanEat;

// Класс Cat расширен от класса Animal и выполняет 2 interface CanEat, CanDrink.
// Cat это обычный класс (Он не объявлен абстрактным).
// Поэтому ему надо выполнить все абстрактные методы Interface.
public class Cat extends Animal implements CanEat, CanDrink {

	private String name;

	public Cat(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}

	// Выполняет метод интерфейса (interface) CanMove.
	@Override
	public void back() {
		System.out.println(name + " cat back ...");
	}

	// Выполняет метод интерфейса (interface) CanMove.
	@Override
	public int getVelocity() {
		return 110;
	}

	// Выполняет метод интерфейса (interface) CanEat.
	@Override
	public void eat() {
		System.out.println(name + " cat eat ...");
	}

	// Выполняет метод интерфейса (interface) CanDrink.
	@Override
	public void drink() {
		System.out.println(name + " cat drink ...");
	}

}
Mouse.java
package org.o7planning.tutorial.cls;

import org.o7planning.tutorial.itf.CanDrink;
import org.o7planning.tutorial.itf.CanEat;

public class Mouse extends Animal  implements CanEat, CanDrink {

  @Override
  public void back() {
      System.out.println("Mouse back ...");
  }

  @Override
  public int getVelocity() {
      return 85;
  }

  @Override
  public void drink() {
      System.out.println("Mouse drink ...");
  }

  @Override
  public void eat() {
      System.out.println("Mouse eat ...");
  }

}
AnimalDemo.java
package org.o7planning.tutorial.cls;

import org.o7planning.tutorial.itf.CanEat;

public class AnimalDemo {

	public static void main(String[] args) {

		// Наследует статическое поле от interface CanDrink.
		System.out.println("Drink " + Cat.SEVENUP);

		// Создает объект CanEat.
		// Объект объявлен как CanEat.
		// Но на самом деле является Cat.
		CanEat canEat1 = new Cat("Tom");

		// Объект объявлен как CanEat.
		// Но на самом деле является Mouse.
		CanEat canEat2 = new Mouse();

		// Полиморфизм (Polymorphism) ясно показывается здесь.
		// Java всегда знает вид объекта
		// ==> Tom cat eat ...
		canEat1.eat();
		// ==> Mouse eat ...
		canEat2.eat();

		boolean isCat = canEat1 instanceof Cat;

		System.out.println("catEat1 is Cat? " + isCat);

		// Cast.
		if (canEat2 instanceof Mouse) {
			Mouse mouse = (Mouse) canEat2;

			// Выхывается метод drink (Унаследованный от CanDrink).
			mouse.drink();
		}

	}
}
Результаты запуска примера:

View more Tutorials: