추상클래스가 무엇이고 왜 사용하는지 알아보자.
추상클래스란?
추상클래스가 뭘까?
A 클래스, B 클래스, C클래스가 있다고 했을 때, 각 클래스 안에는 각자의 필드와 메소드가 있을 것이다.
추상클래스는 A 클래스, B 클래스, C 클래스 간에 비슷한 필드와 메소드를 공통적으로 뽑아내 만들어진 클래스다.
예를 들어 "키보드"라는 클래스가 있다.
이 "키보드"를 만드는 제조사는 여러개이다. A 제조자, B 제조사, C 제조사는 각 제조사만의 스타일대로 키보드를 제작하고 제품을 출시한다.
이때 A 제조사는 키보드를 누를 때마다 불빛이 들어오고, B 제조사는 키보드를 누를 때마다 딸각거리는 소리가 나고, C 제조사는 키보드를 살짝만 눌러도 잘 눌리는 특징을 가진다.
이 키보드들 간에 공통점이 있을까?
바로 "키보드를 누른다."라는 행동 즉, 메소드가 공통적이라고 볼 수 있다.
그럼 키보드를 누르는 메소드를 추출해서 추상클래스 내부에 두면 되는 것이다.
실체클래스는 실체가 드러나는 클래스고, 추상클래스는 실체 클래스의 공통적인 부분을 추출해 어느정도 규격을 잡아놓은 추상적인 클래스이다.
실체클래스는 실제 객체를 생성할 수 있을 정도의 구체성을 가지는 반면, 추상클래스는 아직 메소드의 내용이 추상적이기 때문에 실제 객체를 생성할 수 는 없는 것이다.
이때 추상클래스와 실체클래스는 상속적인 관계를 가지고 있다.
정리하자면 다음과 같다.
- 추상클래스는 실체클래스의 공통적인 부분(변수, 메소드)를 추출해서 선언한 클래스이다.
- 추상클래스는 객체를 생성할 수 없다. 아직은 실체성이 없고 구체적이지 않은 클래스이기 때문이다.
- 추상클래스와 실체클래스는 상속관계를 갖는다.
추상클래스 왜 사용할까?
추상클래스의 개념은 알겠고, 이걸 왜 사용할까? 추상클래스를 사용하는 이유는 크게 3가지가 있다.
공통된 필드와 메소드를 통일하기 위한 목적
5명의 개발자에게 자동차를 상속받아 각자만의 실체클래스를 구현하라고 한다면,
5명의 개발자는 제각각 다른 변수명과 메소드명으로 구현할 것이다. 이렇게 제각각 구현이 된다면 문제가 있다.
만약 A 자동자의 계약이 만료되고, B 자동차로 새로 교체를 해야한다면 하면 어떻게 될까?
만약 A 자동차와 B 자동차의 변수와 메소드명이 동일하다면 객체 인스턴스만 변경해주면 되는데,
개발자마다 제각각 다른 이름으로 구현되어 있다면 변수와 메소드를 하나하나 전부 다 확인하고 변경해줘야 할 것이다.
이건 뭐... 유지보수가 아니라 새로 개발하는 느낌일 것이다.
따라서 추상클래스를 사용하는 것이다.
추상클래스에 미리 정의해놓은 필드와 메소드가 있다면, 실체클래스는 추상클래스의 변수명과 메소드명을 변경할 수 없어 무조건 정의되어 있는 이름으로 구현해야한다.
이렇게 추상클래스를 사용하면 변수와 메소드 이름을 통일하여 유지보수성을 높이고 통일성을 유지할 수 있게 된다.
실체클래스 구현시, 시간절약
자동차라는 실체클래스를 구현해야 한다고 생각해보자.
자동차는 바퀴가 있어야 하고 굴러가야하고... 백미러도 있어야 하고........트렁크도 있어야 하고....어...
여기서 추상클래스의 효과를 발휘할 수 있다.
자동차 추상클래스를 상속받으면 자연스럽게 자동차에 공통적으로 들어가야하는 변수와 메소드가 짠!하고 오버라이딩 된다.
즉, 강제로 주어지는 변수와 메소드를 가지고 개발자는 나만의 스타일대로 구현만 하면 되는 것이다.
따라서 설계시간이 절약되고 개발자는 구현하는데만 집중할 수 있게 된다.
규격에 맞는 실체클래스 구현
위에서 개발자는 실체클래스를 구현하는데 있어 추상클래스를 상속받아 나만의 스타일대로 구현만 하면된다고 했는데,
이때 실체클래스를 나만의 스타일대로 구현한다고 해도, 혼자서 개발하는 것이 아니기 때문에 모두가 약속한 변수와 메소드 그리고 설계 규칙에 맞게 구현해야될 필요가 있다.
그래야 코드 수정시, 영향도를 적게 가져가면서 유지보수성을 높일 수 있다.
이런경우에도 추상클래스의 강력한 기능이 나온다.
추상클래스를 상속받은 실체클래스들은 반드시 추상메소드를 재정의(오버라이딩)해서 코드를 작성해야 한다.
만약 그렇지 않을 경우, 컴파일 에러를 발생시키기 때문에 강제적으로 *추상메소드를 구현해야만 한다.
추상메소드?
추상클래스 안에 abstract 키워드를 가지고 있는 메소드를 추상메소드라 하며, 상속 시 반드시 재정의해야 하는 메소드이다.
정리
추상클래스는 코드 수정 시 다른 코드의 영향도를 적게 가져가면서 변화에는 유연하게 만들기 위해 사용한다.
추상클래스는 규격에 맞게 코드가 정의되어 있기 때문에 해당 규격에 대한 구현부만 수정하면 손쉽게 수정이 가능하기 때문이다.
추상클래스 어떻게 쓰나요?
클래스 앞에 abstract 키워드 붙이면 추상클래스이다
public abstract class 클래스명{
// 필드
// 생성자
// 메서드
// 추상메서드
}
예제를 통해 알아보자.
public abstract class Animal {
public String kind;
public void breath(){
System.out.println("숨 쉰다.");
}
// 추상 메소드
public abstract void sound(); // 구체적인 구현부가 없음!
}
Animal 클래스 앞에 abstract 키워드가 있으므로 해당 클래스는 추상클래스임을 알 수 있다.
추상클래스의 내부를 보면,
- kind 변수와
- breath라는 일반메소드와
- abstract 키워드가 붙은 sound 추상메소드가 있다.
따라서 해당 Animal 클래스를 상속받는 실체클래스들은 반드시 sound 라는 추상메소드를 재정의(오버라이딩)해야만 한다.
public class Cat extends Animal {
public Cat() {
this.kind = "포유류";
}
@Override
public void sound() {
System.out.println("야옹!");
}
}
Dog 클래스는 extends 키워드를 통해 Animal 추상클래스를 상속 받은 실체클래스이다.
추상클래스 변수를 그대로 사용했고, sound 추상 메소드를 오버라이딩해서 구현했음을 알 수 있다.
public class Dog extends Animal {
public Dog() {
this.kind = "포유류";
}
@Override
public void sound() {
System.out.println("왈왈!");
}
}
Dog 실체클래스도 위의 Cat 실체클래스와 똑같다.
다만, sound 추상메소드는 Cat 실체클래스에 맞게끔 자기 스타일대로 구현되어 있음을 확인할 수 있다.
여기서 오버라이딩을 하면, *다형성이 발생된다는 사실을 알 수 있다.
또한 실체클래스들의 코드를 보면 그 모양이 비슷비슷하기 때문에 규격이 맞춰져 있다는 것을 알 수 있다.
다형성?
같은 이름의 기능(메소드)인데, 다른 결과를 도출할 수 있는 객체지향의 특성이다.
Reference
'☕ Java > 이론' 카테고리의 다른 글
정적 팩토리 메서드(static factory method) (0) | 2023.06.12 |
---|---|
[Java] 체크 예외와 언체크 예외 (0) | 2023.03.07 |
[Junit5] @ParameterizedTest 사용하기 (0) | 2022.10.11 |
[Java] 스트림 (Stream) (0) | 2022.02.08 |
[Java] Optional 클래스 (0) | 2022.02.07 |
[Java] 메소드 참조 (Method References) (0) | 2022.02.04 |
[Java] 함수형 인터페이스 (0) | 2022.02.03 |
[Java] 람다 (0) | 2022.01.28 |