Java abstract 와 interface 의 차이

이동명·2023년 5월 24일
0
post-thumbnail
post-custom-banner

Interface vs Abstract Class

추상클래스와 인터페이스(abstracts, interface)는 상속받는 클래스 혹은 구현하는 인터페이스 안에 있는 추상 메소드를 구현하도록 강제하는 것이다. 결국 둘 다 비슷한 일을 하는 것이라고 느껴진다. 하지만 서로 사용 목적이 다르기 때문에 아래글을 읽어보며 특징을 알아보자.

추상 클래스와 인터페이스의 공통점

  • 둘 다 자기 자신이 new를 통해 객체를 생성할 수 없고, 오로지 자식만이 객체를 생성할 수 있습니다.

  • 둘 다 추상 메서드(abstract method)를 갖습니다.

  • 둘 다 하위 클래스에서 추상 클래스를 모두 구현해야 합니다.

추상 클래스와 인터페이스의 차이점

추상클래스(Abstract Class)

  • 상속하여 공통된 기능을 만들고, 확장하기 위함
  • 다중상속 불가능
  • 생성자와 일반변수 모두 가질 수 있다.
  • 메서드를 부분적으로 구현할 수 있다.
  • extends 키워드를 사용한다.

인터페이스(Interface)

  • 구현하는 객체들이 같은 동작을 보장하기 위함
  • 다중상속 가능
  • 생성자와 일반변수를 가질 수 없다.
  • 메서드 선언만 가능하다.
  • implements 키워드를 사용한다.
  • 부모의 메소드를 반드시 모두 오버라이딩해야 한다.

아래와 같은 예시를 들어 이해하고 왜 사용해야 하는지 이해 해 봅시다.

추상클래스 는 공통점을 뽑아놓은 클래스라고 생각하시면 되겠습니다. 여러 자식들이 가지고 있는 공통된 속성들을 뽑아서 하나의 클래스를 만들어 놓은 것을 뜻합니다. 그래서 하위 클래스에서도 extends(상속)이라는 키워드를 사용하여 이 추상 클래스를 상속받아 객체를 구체화시켜갑니다. 이때 상속의 의미는 is a kind of (~의 한 종류)라는 의미를 가지게 됩니다. 예를 들자면 사자 is a kind of 동물이라는 의미를 말이죠. 추상 클래스는 클래스라는 이름에서 알 수 있듯 엄연한 객체입니다. 비록 단독으로 생성하지는 못하지만 객체이기에 생성자도 사용할 수 있죠. 인터페이스와는 완전히 다른 개념 입니다.

public class ExamAbstract {
	/**
	 * 추상클래스 & 추상메서드 abstract 사용하기 추상클래스는
	 * 말그대로 약간 추상적인 의미를 가진 클래스여야 하며 
	 * 비추상적인 클래스에서 이를 상속받아 사용합니다.
	 */
	public static void main(String [] ar){
		Tiger tiger = new Tiger("Hodol");
		tiger.cry();
		tiger.behavior();
		System.out.println("사자의 이름은 :" + tiger.animal_name);
		
		Dog dog = new Dog("Mikey");
		dog.cry();
		dog.behavior();
		System.out.println("개의 이름은 :" + dog.animal_name);
	}
	
}

// 추상 클래스
abstract class Animal {
	String animal_name;
	
	Animal(String name) {
		animal_name = name;
	}
	public abstract void cry();

	public abstract void behavior();

}

class Tiger extends Animal {
	
	public Tiger(String name) {
		super(name);
	}

	@Override
	public void cry() {
		// TODO Auto-generated method stub
		System.out.println("어흥");
	}

	@Override
	public void behavior() {
		// TODO Auto-generated method stub
		System.out.println("우측으로 빠르게 움직인다.");
	}

}

class Dog extends Animal {
	
	public Dog(String name) {
		super(name);
	}
	@Override
	public void cry() {
		// TODO Auto-generated method stub
		System.out.println("멍멍");
	}

	@Override
	public void behavior() {
		// TODO Auto-generated method stub
		System.out.println("왼쪽으로 느리게 달린다");
	}

}

인터페이스 는 객체가 아니라 추상 자료형입니다. 객체가 아니기에 생성자도 사용할 수 없습니다. 오로지 상수와 추상 메서드만 가질 수 있고 이것을 다른 객체가 구현합니다. 그래서 implement(구현하다)라는 키워드를 사용하는 것입니다. 이때 구현의 의미는 be able to(~할 수 있는)이라는 의미를 가집니다.

그런데, 추상클래스 하나를 두고, 각각 껍데기(추상 메소드)들만 두고 상속받는 객체에서 구현(오버라이드)하면 되는데 왜 인터페이스라는 개념을 사용할까?

답은 자바가 다중 상속을 지원하지 않기 때문이다.

다중 상속이라는 것은 super class(부모 클래스)를 2개 이상 두는 것이다. 예를 들어서

//다중 상속
class Futurecar extends Car, Plane {
 
 @Override
 public void move() {
  super.drive();
 }
  
}

위의코드에서 car, plane 클래스 모두 move()라는 메소드를 가지고 있다면, 어떤 메소드가 사용될 지 모호하다. 이 다중 상속의 모호성 때문에 자바에서는 다중 상속을 금지한다.

하지만, 인터페이스는 아래와 같이 여러개의 인터페이스를 구현할 수 있다.

public class ExamInterface {
	/**
	 * 인터페이스는 추상클래스의 일종이지만 보다 더 극단적인경우입니다.
	 * 추상메서드로만 구성되며 abstract와다르게 메서드만 정의가 가능합니다.
	 * 공동 작업을 할때 메서드의 표준화를 시키기 위하여 많이 사용되며,
	 * 서로 다른 클래스를 연결할 때도 사용됩니다.
	 */
	public static void main(String[] ar) {
		Door door = new Door();
		door.open();
		door.close();
		door.Red();
		door.Blue();

		Bottle bottle = new Bottle();
		bottle.open();
		bottle.close();
	}
}

interface OpenCloseIf {
	public void open();

	public void close();
}
interface PaintIf {
	public void Red();

	public void Blue();
}

/**
 * Interface 는 implements 로 상속받으며
 * extends 상속과는 다르게 다중 상속이 가능합니다.
 */
class Door implements OpenCloseIf , PaintIf {

	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println("Door Open");
	}
	
	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println("Door Close");
	}
	
	@Override
	public void Red() {
		// TODO Auto-generated method stub
		System.out.println("Paint the door red");
	}

	@Override
	public void Blue() {
		// TODO Auto-generated method stub
		System.out.println("Paint the door blue");
	}

	

}

class Bottle implements OpenCloseIf {
	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println("Bottle Open");
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println("Bottle Close");
	}
}

참고


[JAVA] 추상클래스와 인터페이스(abstract class & interface)
[JAVA] 추상클래스와 인터페이스의 공통점과 차이점
[JAVA] abstract와 interface의 차이점
[JAVA] Interface vs Abstract Class
[초급 JAVA]자바 interface 와 abstract 예제로 이해하기

profile
Web Developer
post-custom-banner

0개의 댓글