JAVA) JAVA의 설계도 추상클래스와 인터페이스

백준우·2022년 12월 28일
0

Java & Spring

목록 보기
4/6
post-thumbnail
post-custom-banner

1. 추상클래스

  1. 추상클래스란?
  2. 추상클래스의 예시

2. 인터페이스

  1. 인터페이스란?
  2. 인터페이스 예시코드

3. 추상클래스와 인터페이스


들어가면서

  • 자바는 OOP로 설계된다고 저번시간에 말을 했다. 그럼 다양한 클래스들을 용도별로 구분하고 쓰임새에맞게 가져다 쓰는게 맞지않을까싶다.
  • 이러한 개념과 생각을 가지고 깔끔한 클린코드를 작성하기 위해선 무분별한 클래스 생성과 적절한 상속사용으로 깔끔한 코드를 만드는게 필요하지 않을까 싶었다.
  • 그래서 이번엔 클래스에대해 공부를 하게 되었고 그중에서 추상클래스에대해 애매모한 개념이 있었고 이를 인터페이스와 함께 생각하며 개념을 잡기로 했다.
  • 많은 클래스를 유기적으로 가져다 쓰고 상속받고 엮이다보면 어쩌면 아래 거미줄같은 모습이 되지않을까 생각이 든다.

<출처 - https://velog.io/@new_wisdom/Java-%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4 >

Class에 대해 간략히 짚어보자

자바에서 클래스(class)란 객체를 정의하는 틀 또는 설계도와 같은 의미로 사용됩니다.
자바에서는 이러한 설계도인 클래스를 가지고, 여러 객체를 생성하여 사용하게 됩니다.
클래스는 객체의 상태를 나타내는 필드(field)와 객체의 행동을 나타내는 메소드(method)로 구성됩니다.
즉, 필드(field)란 클래스에 포함된 변수(variable)를 의미합니다.
또한, 메소드(method)란 어떠한 특정 작업을 수행하기 위한 명령문의 집합이라 할 수 있습니다.

1. 추상클래스

  1. 추상클래스란?
    1) 추상클래스라하면 일반클래스와 차이점과 이걸 왜 써야하는지 짚고 넘어갈 필요가 있다고 생각한다. 추상클래스는 미완성된 설계도라 할 수 있으며 하나 이상의 추상 메서드를 가지는 클래스를 말한다.
    2) 자동차를 예시로들면 부분마다 다르겠지만 바퀴는 4개이며 핸들이 있는등 공통된 분모가 있을것이다. 그 공통된 분모라도 4기통엔진과 8기통엔진에서 차이가 나듯 분리를 가능케하는것이 추상 클래스이다.
    3) 설계자가 특정 메서드를 각 클래스 별로 재 구현을 원하지만 부모 클래스에서 일반 메서드로 구현하면 자식 클래스에서 구현을 하지 않는 경우가 발생할 수 있다. 이런 메서드를 추상 메서드로 선언하면 자식 클래스는 재 구현을 강요받는다.
    • 추상 클래스 특징
      1) 추상 클래스는 키워드 abstract를 붙여 표현한다.
      2) 추상 메서드 미포함 해도 abstract를 붙여서 추상 클래스로 지정할 수도 있다.
      3) 클래스를 abstract로 지정하면 new를 통해 객체를 직접 생성할 수 없다.
      4) 메소드에 abstract를 사용할 경우 interface의 메소드와 같이 구현 부분은 없다.
      5) abstract로 선언한 메소드를 자식 클래스에서 반드시 구현해야 한다. (오버라이딩)
  • 추상클래스 장점
    1) 부모클래스에서 공통 부분을 구현과 설계가 완료되면 자식 클래스에서 상속받아 기능을 확장 시 이롭다.
    2) 자식 클래스에서 추상메서드를 반드시 구현하도록 강요한다. 이는 프로그램의 표준화 정도를 높인다.
    3) 공통 사항이 한곳에서 관리되어 개발 및 유지보수에 용이하다.
  1. 추상클래스의 예시
// 추상클래스 선언방법
abstract class 클래스이름 {
    ...
    public abstract void 메서드이름();
}

// 예시코드 
public abstract class Engine {
  // Field
  private int volume;

  // Constructor 
  public Engine(int volume) {
    this.volume = volume;
  }

  // Method
  abstract void showEngine() { }; //메소드가 선언은 되어있으나 내용이 없는 추상 메서드
}

public class Car extends AbstractTest {
  
  public Car(int volume){
  	super(volume); // 부모의 생성자에 할당을하여 사용한다.
  }
  
  // 추상메서드로 선언된 부분은 자식에서 선언을 해줘야한다.
  @Override
  void showEngine() {
  	System.out.println("이차량은 " + volume + "기통 엔진입니다.");
  }
  
  
}

2. 인터페이스

  1. 인터페이스란?
    1) 추상클래스가 미완성된 설계도라면 인터페이스는 완성된 설계도라고 할 수 있다.
    2) 'interface' 키워드를 사용하여 선언하는 인터페이스는 상수(static final)와 추상 메서드(abstract method)의 집합입니다.
    3) 클래스와 다르게 다중상속(구현)이 가능하다.
    4)
  • 인터페이스 규칙
    1) 추상 클래스처럼 불완전한 것이기 때문에 그 자체만으로 사용되기 보다,
    2) 다른 클래스를 작성하는데 도움을 줄 목적으로 작성된다.
    3) 일반 메서드 또는 멤버 변수를 구성원으로 가질 수 없다.
    4) 모든 멤버 변수는 public static final이어햐 하며, 이를 생략할 수 있다.
    5) 모든 메서드는 public abtract이어야 하며, 이를 생략할 수 있다.
    (단, JDK1.8부터 static 메서드와 default 메서드를 사용할 수 있다.)

TIP) interface이름 설정
인터페이스 명은 대부분 "~을 할 수 있는"의 의미인 able로 끝나는 것들이 많다고 한다.

  1. 인터페이스 예시코드
//인터페이스 선언방법
interface 인터페이스이름 {
	...
    public void 메서드이름(); //일반 메서드 선언
    
    public abstract void 메서드이름(); // 추상메서드 선언문

    public default void 메서드이름() {
    	//public default void를 사용하면 인터페이스에서 메서드가 정의된다.
    };
}

// 예시코드
public interface Movable {
    void move(int x, int y);
}

interface Attackable {
    void attack(int u);
}

// 인터페이스는 클래스와 다르게 다중 상속이 가능하다.
interface Fightable extends Movable, Attackable {
 	// TODO Auto-generated method stub
}
class Person implements Attackable, Movable {
 
	@Override
	public void move(int x, int y) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void attack() {
		// TODO Auto-generated method stub
	}
}

// 메서드이름이 똑같은 interface를 상속받을경우 하위클래스에서 Override해서 재선언 해주어야한다.

3. 추상클래스와 인터페이스

  1. 추상 클래스, 인터페이스 둘 다 객체로 만들 수 없다는 공통점이 있습니다. extends하거나 implements해야 합니다.
  2. 추상 클래스에는 public, protected, private 메소드를 가질 수 있습니다. 반면에 인터페이스는 public만 허용됩니다.
  3. 추상 클래스에는 멤버변수 선언이 가능하지만 인터페이스는 public static 변수만 선언이 가능합니다.
  4. 인터페이스는 implements 키워드로 여러 인터페이스를 구현할 수 있습니다. 반면에 추상클래스는 extends 키워드로 1개의 클래스만 상속받을 수 있습니다.
  • 추상 클래스는 이를 상속할 각 객체들의 공통점을 찾아 추상화시켜 놓은 것으로,
    상속 관계를 타고 올라갔을 때 같은 부모 클래스를 상속하며
    부모 클래스가 가진 기능들을 구현해야할 경우 사용한다.

  • 인터페이스는 상속 관계를 타고 올라갔을 때
    다른 조상 클래스를 상속하더라도, 같은 기능이 필요할 경우 사용한다.
    클래스와 별도로 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용한다.

<출처 - https://velog.io/@new_wisdom/Java-%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4 >

위의 그림을 예시로 들었을때 생물체라는 추상클래스에서 동물과 사람이 추가로 상속받는 추상클래스가 되고 이때 동물은 식물과 다르게 짖는다(Barkable)이라는 기능이 있으므로 이러한 기능을 분리하기 interface가 사용된다.
그리고 동물을 상속받은 모든 클래스와 식물을 상속받는 FlyHellPlanet은 다른 추상클래스를 상속받지만 Eatable이라는 먹는 기능은 동일하다. 이때도 다른 클래스지만 같은 기능을 가지고 있으므로 interface가 사용된다.

각각의 적절한 사용 케이스 정리

  • 추상 클래스
    1) 관련성이 높은 클래스 간에 코드를 공유하고 싶은 경우
    2) 추상 클래스를 상속 받을 클래스들이 공통으로 가지는 메소드와 필드가 많거나,
    3) public이외의 접근자(protected, private) 선언이 필요한 경우
    4) non-static, non-final 필드 선언이 필요한 경우 (각 인스턴스에서 상태 변경을 위한 메소드가 필요한 경우)

  • 인터페이스
    1) 서로 관련성이 없는 클래스들이 인터페이스를 구현하게 되는 경우.
    ex) Comparable, Cloneable 인터페이스는 여러 클래스들에서 구현되는데, 구현클래스들 간에 관련성이 없다.
    2) 특정 데이터 타입의 행동을 명시하고 싶은데, 어디서 그 행동이 구현되는지는 신경쓰지 않는 경우.
    3) 다중상속을 허용하고 싶은 경우

마치며 ...

  • 확실히 이번개념을 통해 객체지향설계를 좀더 효과적으로 할 수 있을것이라 생각된다.
  • 아직까지 많이 부족하지만 코드를 많이 짜보고 실습해보면서 효율적인 객체지향 설계를 구상할 수 있도록 해야겠다.
  • 개념을 머리로만 익히지말고 응용하면서 다양한 경우에 써보도록 해야겠다. (도전하자!!)

참고

profile
이게 되네?
post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 4월 2일

감사합니다.

답글 달기