추상 클래스, 추상 메소드, 재정의
abstract
실체 간의 공통 특성을 추출한 것.. 추상 클래스라는 건 뭔지 학습하자
ㅇ실체 클래스 = 객체를 직접 생성할 수 있는 클래스
ㅇ추상 클래스 = 클래스들의 공통적인 특성을 추출해서 선언한 클래스
ㄴ실체 클래스와 추상 클래스 -> 상속의 관계가 있다.
ㄴ추상클래스가 부모, 실체 클래스가자식.
ㄴ그러므로 실체클래스는 추상클래스의 모든 특성을 물려받고, 추가적인 특성을 가질 수 있다.
이 때 특성은 필드, 메소드 같은 것을 말한다.
그럼 추상 클래스는 어떤 용도로 사용할까?
추상클래스의 용도
ㅡ> 통일할 수 있는 기능을 객체마다 따로 부여하게 되면 같은 기능인데도 사용 방법을 달리 해야 해서 혼잡해진다.
그래서 추상 클래스에 통합할 수 있는 기능들을 넣고, 실체 클래스가 상속하게 만들면 간단하고 좋다.
ㅡ> 이렇게 공통적인 필드, 메소드는 추상 클래스에 작성하고, 서로 다른 점만 각 객체에 작성을 하면 시간 절약이 된다.
+보통 개발 프로젝트에서 설계자와 코더가 따로 있다고 한다.
설계자는 코더에게 클래스를 어떤 구조로 작성해야 하는지 알려준다고 한다.
+예시 : 자동차에서 타이어 규격을 준수하는 모든 타이어를 사용할 수 있다.
이 때 타이어 규격이 추상 클래스고, 규격을 준수하는 각 타이어들은 실체 클래스라고 볼 수 있다.
추상클래스 선언하기
abstract 키워드 이용!
이 키워드를 붙이면 new연산자를 이용해 객체를 만들지 못한다.
상속을 통해 자식 클래스만 만들 수 있다.
new연산자로 직접 생성자를 호출할 수는 없지만
추상클래스 내에 생성자는 있어야 한다.
자식 객체가 생성될 때 super(...)를 호출해서 추상클래스 객체를 결국 생성하기 때문이다.
<추상 클래스>
public abstract class 클래스 {
//필드
//생성자
//메소드
}
<<익히기>>
Phone을 추상 클래스로 두고, 이 클래스를 상속받는 SmartPhone 실체 클래스를 만들어보자
추상 클래스라는거 자체가
실체클래스의 공통되는 필드, 메소드를 추출해 만든 것이다.
그렇기 때문에 객체를 직접 생성해서 사용할 수 없는 것이다.
(추상클래스 객체는 직접 구현하지 않는다)
추상클래스는 오로지 부모 클래스로만 사용된다. 즉 extends 뒤에만 올 수 있는 클래스이다.
공통되는.. 공유할만한 클래스 멤버를 추출한다는게 약간.. static이랑 비슷한 느낌인데..... 뭐가 다르지??
-->static은 클래스가 딱히 객체화되지 않아도 그 static으로 선언된 메소드, 필드를 이용 가능한 것이었다.
-->정적 클래스를 잘 사용하면! 인스턴스화가 적합하지 않은 일회성, 유틸리티, 라이브러리 클래스를 용도에 맞게 정의할 수 있다. 좋은 예는 PI,E 등의 상수가 들어 있는 Math 클래스이다. 단순히 수학적 계산을 제공한다.
-->모든 클래스는 생성자를 통해서 메모리에 로딩되지만, static 클래스의 경우에는 클래스 자체가 JVM이 기동하면서 바로 로딩을 시키게 된다.
-->정적 메소드는 특정 인스턴스에 속하지 않고, 클래스에 속하는 것이다. (정적 메소드는 재정의할 수 없다)
목적이랑 사용 용도의 초점이 다르다는 느낌 알겠다.
알아보다가 이런 것도 발견했다.
추상클래스에 static멤버를 선언하는 것은 문제가 없다.
(정적 멤버는 객체랑 따로 놀기 때문에, 클래스의 인스턴스가 없어도 해당 정적 메소드를 직접 호출 가능하다.
예를 들면
abstract class Foo { static void bar() { } } ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ Foo.bar(); |
하지만
static멤버를 abstract로 선언하는 것은 불가능하다고 한다.
!!
'정적 메소드는 직접 호출할 수 있으나'
'추상 메소드는 직접 호출할 수 없다.'
아직 잘 느낌이 안오고 모르겠는데.. 나중에 다시 돌아오자.
추상 클래스에는 final 필드나 static 필드를 선언할 수 없는 이유........
??근데 왜 꼭 abstract으로 클래스를 만들어야 하지?
그냥 상속하면 안돼? 왜 직접 객체생성하면 안되는거지??
음..근데 결국 super()를 통해서 간접적으로 추상 클래스의 객체도 새로 생성되는게 아닌가?
혼공자 360페이지에 보면 'new연산자로 직접 생성자를 호출할 수는 없지만 자식 객체가 생성될 때 super(...)를 호출해서 추상 클래스 객체를 생성하므로 추상클래스도 생성자가 필요하다'라고 명시되어있는데..... 그럼 추상 클래스 객체도 결국 생성되긴 한다는건데.. 그럼 결국 객체를 생성하는건 추상 클래스나 일반 클래스나 똑같은 거 아닌가..?
라고 생각을 했었는데
이해가 잘 되는 글을 하나 찾았다.
추상 메소드와 재정의
추상 메소드는 추상 클래스에서만 선언 가능하다.
메소드의 선언부만 있는 메소드이다.
자식 클래스에서 재정의되어 실행 내용을 결정해야 한다.
-->각 동물들이 내는 소리가 서로 다르다고 해서, 추상클래스에 sound()라는 메소드를 작성하지 않는다면 자식 클래스 동물들이 소리를 낸다는 사실에 위배된다.
-->이런 경우에 추상 클래스에 추상메소드를 정의하고, 재정의를 통해 각 객체에 알맞게 이용한다.
-->추상 메소드를 재정의하지 않으면 자식 클래스도 추상 클래스가 되어야 한다.
추상클래스 설계할 때 하위클래스가 반드시 실행 내용을 채워 사용하도록 강제하고 싶은 메소드가 있을 경우에 해당 메소드를 추상 메소드로 선언하는 것이다.
각 동물이 어떤 소리를 내는지는 각 동물 객체가 알아서 정하고, 그냥 소리를 낸다는 공통적 특징을 규정하기 위한 추상 메소드를 선언해보면
public abstract class Animal {
public abstract void sound();
}
이 정도로 작성할 수 있고, 그냥 '소리를 낸다'는 공통적이고 광범위한 메소드다.
추상 메소드에 중괄호는 붙이지 않는다.
개는 멍멍 고양이는 야옹 같은 소리를 낸다는 것을 구체적으로 작성하기 위해서는, 실체 클래스에서 이 추상 메소드를 재정의하면 된다.
확인 문제
03.
public class LoginServlet extends HttpServlet {
@Override
public void service() {
System.out.println("로그인합니다.");
}
}
public class FileDownloadServlet extends HttpServlet {
@Override
public void service() {
System.out.println("파일 다운로드합니다.");
}
}
'JAVA' 카테고리의 다른 글
[혼자 공부하는 자바] 7/12 8-2 [타입 변환과 다형성] [인터페이스 상속] (0) | 2020.07.12 |
---|---|
[혼자 공부하는 자바] 7/11 8-1 [인터페이스] [추상 메소드] [실체 메소드] (0) | 2020.07.11 |
[혼자 공부하는 자바] 7/10 07-2 [타입 변환과 다형성] [자동 타입 변환] [강제 타입 변환] (0) | 2020.07.11 |
[혼자 공부하는 자바] 7/09 07-1 [상속] [자식클래스] [부모클래스] [오버라이딩] [메소드 재정의] (0) | 2020.07.10 |
[혼자 공부하는 자바] 7/08 06-6 [패키지와 접근 제한자] (0) | 2020.07.08 |