JAVA 추상클래스
추상클래스
사전적인 의미로 추상(abstract)은 실체 간에 공통되는 특성을 추출한 것을 말한다..? 암튼 추상적이라고 하면 필자의 입장에서는 두리뭉실..? 완벽히 구현이 되지 않은 무언가..? 그렇게 생각이 든다.
하지만 찾아보니...공통되는 특성을 가지는 것을 추상적인 것이라고 볼 수 있습니다.
이렇게 클래스에도 추상클래스가 존재하는데, 객체를 직접 생성할 수 있는 클래스를 실체 클래스라고 정의하는데,
이러한 실체클래스들의 공통적인 특성을 추출하여서 선언한 클래스가 추상클래스입니다.
추상클래스는 실체클래스를 만들기 위해 부모클래스로만 사용이됩니다. 추상클래스는 추상적이고, 일반적인클래스처럼 완벽하게 만든 클래스가 아니기 때문에 객체를 생성할 수 없습니다.
이렇게 도대체 추상클래스를 이용하여서 상속을 받아서 실체클래스들을 설계하는 이유는 무엇일까?
1. 실체클래스들의 공통된 필드와 메소드의 이름을 통일할 목적이다.실체클래스를 설계시에 한사람만 클래스를 작성하는 것이면 상관없겠지만, 여러 개발자들이 설계할 경우에는 필드명이나 메소드명이 동일한 기능을 한다고 해도 이름이 달라서 통일이 안되고, 객체마다 사용방법이 달라지기 때문에 사용을 한다 예를들어서 어떤 A라는 개발자는 전원을 킨다를 turnOn()으로하고 B라는 개발자는 powerOn으로도 할 수 있기때문에 추상클래스에서 통일된 메소드를 선언하고 실체클래스들이 그 추상클래스를 상속을 받아서 사용하면 통일성을 가지면서 클래스를 설계할 수 있다.
2. 실체클래스를 작성할 때 시간을 절약을 할 수 있다.
실체클래스를 작성을 할 때 추상클래스를 상속받아서 작성을 하면, 추상클래스는 실체클래스들의 공통적인 특성의 기능들이 모여있는 부모클래스인데, 상속만 받아놓으면 굳이 실체클래스를 설계할 때 따로 설계할 필요가 없기때문에 시간절약 및 가독성있게 설계를 할 수 있습니다.
추상클래스의 선언
public abstract class Animal{
//필드
//생성자
//메소드
}
기본적인 추상클래스의 선언방법은 위에 코드와 같이 abstract를 붙여준다.
기본적인 클래스처럼 생성자 메소드 필드가 다 존재한다. 생성자는 상속 시에 자식(실체)클래스들이 객체를 생성할 때 부모클래스의 생성자를 호출되고 그다음에 자식클래스의 생성자가 호출이 되면서 만들어지기 때문에 생성자가 있어야한다.하지만 위에서도 말했다시피 직접 추상클래스를 호출하거나, 객체를 생성할 수 없다.
추상클래스를 한 번 만들어보자.공통적인 특성을 갖는 동물이라는 추상클래스를 만들어 보겠습니다.
public abstract class Animal{
String owner;//동물의 주인이름.
public Animal(String owner){
this.owner=owmer;
}
public void feed(){
System.out.println("먹이를 먹다");
}
public void sleep(){
System.out.println("잠을 자다");
}
}
public class Cat extends Animal{
public Cat(String owner){
super(owner); //추상클래스의 생성자를 불러옴.
}
public void cry(){
System.out.println("야옹")
}
}
public class AnimalEx{
public static void main(String[] args){
Cat cat = new Cat("윤원구");
cat.feed();//추상클래스의 메서드
cat.sleep();//추상클래스의 메서드
cat.cry();//실체클래스의 메서드
}
}
이렇게 위에 처럼 사용을 할 수 있습니다.
하지만 Animal 추상클래스에는 추상메소드도 사용할 수 있습니다.
어떠한 경우이면.. 위에 설명했다시피 통일이라는 개념으로 추상클래스를 사용해서 클래스를 설계를 하는데..동일한 메소드명이지만 실체클래스들 마다 메소드명은 같지만 내용은 서로 다르게 작성이 되야하는 경우가 있습니다.
예를 들어서, 동물은 모두가 먹이를 먹지만 서로 다른 종류의 먹이를 먹으며, 동물은 울거나 짖지만 서로 다른 소리로 짖거나 운다. 이럴경우에는 추상클래스에서 abstract를 해놓아서 메소드들을 작성하면 된다. 밑에 코드를 보자.
public abstract class Animal{
public abstract void sound(매개변수);
}
public Dog extends Animal{
@override
public void sound(매개변수){
System.out.println("왈왈");
}
}
이런식으로 저번에 배웠다시피 재정의를 통해서 다시 메소드를 정의할 수 있다.
근데 여기서는 재정의를 의무적으로 해야한다. 그리고 메소드가 텅텅 빈 메소드를 작성을 해줘야 한다.
개발자가 실체클래스를 개발하다가 기능구현을 해야 할 메소드를 빼먹지 않게 도와주는 역할도 한다.
interface의 구현도 같이 이렇게 의무적으로 강제로 재정의를 해서 구현을 해야한다.
추가로 추상메소드의 접근제한자는 private로 할 수가 없다 왜냐..? 딱봐도 상속을 받거나 재정의를 해야하는데 접근제한자가 private면 어떻게.. 접근을 하나.. 상속이란 개념은 같다.
이상..
Reference
https://www.hanbit.co.kr/store/education/edu_view.html?p_code=C5815590736
한빛출판네트워크
더 넓은 세상, 더 나은 미래를 위한 아시아 출판 네트워크 :: 한빛미디어, 한빛아카데미, 한빛비즈, 한빛라이프, 한빛에듀
www.hanbit.co.kr