자바(Java) - 추상 클래스, 인터페이스

Jan 01, 2024
자바(Java) - 추상 클래스, 인터페이스

추상 클래스

💡
추상 클래스(abstract class)는 완전하게 구현되어 있지 않은 메소드를 가지고 있는 클래스를 의미한다.
 
메소드가 미완성되어 있으므로 추상 클래스로는 객체를 생성할 수 없다.
 
추상 클래스는 주로 상속 계층에서 추상적인 개념을 나타내기 위한 용도로 사용된다.
 
자바에서 추상 클래스를 만들기 위해서는 클래스 선언 시에 앞에 abstract를 붙인다.
 
public abstract class Animal { public abstract void move(); // 추상 메소드 정의, 세미 콜론(;)으로 종료됨을 유의 ... }
 
💡
추상 클래스는 하나 이상의 추상 메소드를 가지고 있어야 한다.
 
추상 메소드는 항상 세미 콜론(;)으로 종료되어야 한다.
 
추상 클래스를 상속받는 자식 클래스에서는 반드시 추상 메소드를 재정의하여야 한다.
 
만약 재정의하지 않으면 오류가 발생한다.
 
public class Lion extends Animal { // 추상 클래스를 상속받으면 추상 메소드를 구현하여야 한다. public void move() { System.out.println("사자의 move() 메소드입니다."); } }
 
 

추상 클래스의 용도

부모 클래스에서 draw()를 void draw() {} 와 같이 내용이 없는 일반 메소드로 정의한 후에 자식 클래스에서 재정의하는 것추상 메소드를 사용하는 방법과는 어떤 차이가 있을까?
 
💡
결과는 같다.
 
하지만 추상 메소드로 정의하면 서브 클래스에서는 반드시 구현하여야 하므로 구현을 강요하는 면에서 장점이 있다.
 
추상 메소드가 아니면 자식 클래스에서 재정의하지 않고 넘어갈 수도 있기 때문이다.

인터페이스

💡
각자의 클래스를 다른 사람의 클래스와 연결하려면 클래스 간의 상호작용을 기술하는 일종의 규격이 있어야 한다. 이러한 규격을 인터페이스(interface)로 정의할 수 있다.
 
 

인터페이스 정의

💡
인터페이스를 정의하는 것은 클래스를 정의하는 것과 유사하다. 하지만 키워드 class를 사용하지 않고 키워드 interface를 사용한다.
 
public interface 인터페이스이름 { 반환형 추상메소드1(...); 반환형 추상메소드2(...); } /* 인터페이스는 추상 메소드들과 디폴트 메소드들로 이루어진다. 인터페이스 안에서 필드(변수)는 선언될 수 없다. 상수는 정의할 수 있다. */
 
💡
메소드들은 모두 이름과 매개 변수만 존재하고, 몸체가 없으며 세미콜론으로 종료되는 점에 유의
 
인터페이스 안에서 선언되는 메소드들은 모두 묵시적으로 public abstract이다.
 
따라서 public이나 abstract 수식어는 없어도 된다.
 
 

인터페이스 구현

💡
인터페이스는 다른 클래스에 의하여 구현(implement)될 수 있다.
 
인터페이스를 구현한다는 말은 인터페이스에 정의된 추상 메소드의 몸체를 정의한다는 의미이다.
 
클래스가 인터페이스를 구현하기 위해서는 inplements 키워드를 사용한다.
 
class Television implements RemoteControl { ... }
 
 

인터페이스 vs 추상 클래스

💡
추상클래스는 바텀 업 : 구체적인 것 만들고 위로
인터페이스는 탑 다운 : 규격 만들고 아래로
 
추상 클래스는 인터페이스와 유사하다.
이들은 객체화될 수 없고 주로 구현이 안 된 메소드들로 이루어진다.
 
  • 추상 클래스
    • 일반적인 필드도 선언할 수 있으며, 일반적인 메소드도 정의할 수 있다.
    • 만약 관련된 클래스들 사이에서 코드를 공유하고 싶다면 추상 클래스를 사용하는 것이 좋다.
    • 공통적인 필드나 메소드의 수가 많은 경우, 또는 public 이외의 접근 지정자를 사용해야 하는 경우에 추상 클래스를 사용한다.
    • 정적이 아닌 필드나 상수가 아닌 필드를 선언하기를 원할 때 사용한다.
    •  
  • 인터페이스
    • 모든 메소드는 public, abstract가 된다.
    • 관련 없는 클래스들이 동일한 동작을 구현하기를 원할 때 사용한다.
    • 특정한 자료형의 동작을 지정하고 싶지만 누가 구현하든지 신경쓸 필요가 없을 때 사용한다.
    • 다중 상속이 필요할 때 사용한다.

인터페이스를 이용한 다중 상속

인터페이스끼리도 상속이 가능하다

💡
인터페이스끼리도 상속이 가능하다.
 
클래스도 extends를 이용하여 상속을 받을 수 있고
인터페이스도 extends를 이용하여 다른 인터페이스를 상속받을 수 있다.
클래스가 인터페이스를 구현할 때는 implements 키워드를 사용한다.
 
 

인터페이스를 이용한 다중 상속

💡
다중 상속(Multiple inheritance)은 하나의 클래스가 여러 개의 부모 클래스를 가지는 것이다.
 
다중 상속은 애매모호한 상황을 만들 수 있기 때문에 자바에서는 금지되어 있다.
 
하지만 때에 따라서는 다중 상속이 필요하다.
 
자바에서는 인터페이스를 이용하여서 다중 상속과 비슷한 효과를 낼 수 있다.
 
첫 번째 방법은 여러 개의 인터페이스를 동시에 구현하는 것이다.
interface Drivable { void drive(); } interface Flyable { void fly(); } public class FlyingCar1 implements Drivable, Flyable { public void drive() { System.out.println("I'm driving"); } public void fly() { System.out.println("I'm flying"); } public static void main(String[] args) { FlyingCar1 obj = new FlyingCar1(); obj.drive(); obj.fly(); } }
 
두 번째 방법은 하나의 클래스를 상속받고 또 하나의 인터페이스를 구현하는 것이다.
interface Flyable { void fly(); } class Car { int speed; void setSpeed(int speed) { this.speed = speed; } } public class FlyingCar2 extends Car implements Flyable { public void fly() { System.out.println("I'm flying!"); } public static void main(String[] args) { FlyingCar2 obj = new FlyingCar2(); obj.setSpeed(300); obj.fly(); } }
 
 

상수 정의

💡
인터페이스에는 상수를 정의할 수 있다.
 
인터페이스에서 정의된 변수는 자동적으로 public static final이 되어서 상수가 된다.
Share article

stwin755