[JAVA]추상클래스와 추상메서드(Abstract)
@욕심쟁이
·2020. 9. 11. 17:46
추상(Abstract)이란?
- 실체간에 공통되는 특성을 추출한것.
1. 추상클래스
- 공통적인 특성을 추출해서 선언한 클래스
- 용도 : 실체 클래스의 공통적인 특성(필드, 메소드)을 뽑아냄
1) 공통된 필드와 메소드 이름을 통일할 목적
2) 서브클래스를 작성할 때 시간 절약
- 인스턴스 생성이 불가능한 클래스
→ 인스턴스 생성이 가능할 경우 추상메서드 호출이 가능하므로 인스턴스 생성을 못하도록 막아놓은 클래스
- 상속을 통해 서브클래스에서 추상메서드를 구현하도록 강제하는 용도의 클래스로 주로 사용
- 추상클래스가 가질수 있는 멤버
→ 생성자, 일반멤버변수, 상수, 일반메서드, "추상메서드"
- 클래스 정의시 class키워드 앞에 "abstract"키워드를 붙임
- 인스턴스 생성은 불가능하지만 참조변수 타입은 사용가능→다형성 적용가능
<추상클래스정의 기본문법>
abstarct class 클래스명 {
//필드
//생성자
//메소드(일반메서드, 추상메서드)
}
2. 추상메서드
- 메서드 구현부(바디,{})가 없는 메서드(= 실행할 코드가 없는 메서드)
**메서드란? 호출받으면 코드를 실행하는 것
- 구현부가 없기 때문에 외부로부터 호출되어도 실행할코드가 없음
→ 따라서, 추상메서드를 포함하는 클래스는 반드시 추상클래스로 선언해야한다!
- 추상클래스에 추상메서드가 없어도된다
- 추상메서드 정의시 리턴타입 앞에 "abstract"키워드를 붙임
<추상메서드 정의 기본 문법>
[접근제한자]abstract 리턴타입 메서드 명([매개변수,....);
3. 추상메서드 재정의
- 코드의 통일성
- 메소드의 선언만 통일하고, 실행 내용은 다름
→ (슈퍼클래스의 추상메서드바디는 없어야하고, 서브클래스의 추상메서드바디는 있고 내용은 달라도 상관없음)
- 추상클래스는 추상메소드를 선언 해도되고 안해도됨
- 추상메서드는 추상클래스에서만 선언가능
- 슈퍼클래스의 메서드를 하위클래스가 강제로 적용시키고싶을때 추상메서드 지정
→ 상속받은 클래스에 추상메소드가 있으면 그 메서드는 재정의(구현 : Implement) 해야됨
- 추상메서드를 재정의하지않으면 자식클래스는 추상클래스가 되어야함
→ 자식클래스에서 부모의 추상 메서드를 오버라이딩하지 않으면 자식도 추상클래스가됨
→ 추상메서드를 오버라이딩 할때까지 추상클래스 상속
예제1
public class Ex {
public static void main(String[] args) {
SubClass sc = new SubClass();//SubClass의 인스턴스 생성
sc.normalMethod();
sc.abstractMethod1();
sc.abstractMethod2();
//추상클래스로 인스턴스 생성불가
//AbstractClass ac = new AbstractClass();
//MiddleClass mc = new MiddleClass();
//업캐스팅은 가능
AbstractClass ac = sc;
ac.normalMethod();
ac.abstractMethod1();
ac.abstractMethod2();
MiddleClass mc = sc;
mc.normalMethod();
mc.abstractMethod1();
mc.abstractMethod2();
}
}
//추상클래스
abstract class AbstractClass{
String var; // 일반멤버변수
public AbstractClass() {}// 생성자
public void normalMethod() {
System.out.println("추상클래스의 메서드!");
}
//추상메서드 abstractMethod()정의
//=> 현재클래스는 반드시 추상클래스로 선언해야함(추상메서드가 있기때문)
public abstract void abstractMethod1();
public abstract void abstractMethod2();
}
//추상클래스 AbstractClass를 상속받는 MiddleClass 정의
//=>2개의 추상메서드중 하나의 메서드만 오버라이딩
abstract class MiddleClass extends AbstractClass{
//모든 추상메서드를 오버라이딩 하지않고, 일부만 구현할 겨우
//여전히 추상메서드를 포함하게 되므로 일반클래스로 정의 할 수 없다!
//=> 추상메서드를 모두 오버라이딩 하거나, 현재클래스를 추상클래스로 선언
@Override
public void abstractMethod1() {
System.out.println("MiddelCalss 에서 구현한 추상메서드 abstractMethod1");
}
}
//MiddleClass를 상속받는 SubClass 정의
//=> MiddleClasee에서 구현되지 않은 abstractMethod2()메서드에 대한
//구현책임이 발생함 => 반드시 구현
class SubClass extends MiddleClass{
@Override
public void abstractMethod2() {
System.out.println("SubVLass에서 구현한 추상메서드 abstractMethod2()");
}
}
예제2
public class Ex {
public static void main(String[] args) {
//Shap s = new Shap(); //=> 인스턴스화 불가(new하지말라)
// Cannot instantiate the type Shap
//=> 인스턴스화 불가능한 타입이르모 인스턴스 생성시 오류발생!
//참조변수의 데이터 타입으로 사용은 가능
Shap s = new Circle();
s.draw();
s = new Rectangle();
s.draw();
}
}
abstract class Shap{
//public abstract void draw(); //추상메서드는 body{}를 가질수 없다.
public abstract void draw(); //추상메서드는 추상클래스에만 정의되어야만 한다. => 추상메서드는 호출되어선 안되기 때문에
}
//2. 추상클래스 Shap을 상속받는 서브 클래스 Circle정의
//=>추상메서드가 존재하는 경우 서브클래스에서 수상메서드를 구현(implement)해야한다!
// 구현()과 오버라이딩은 동일한 기능이지만
// 메서드 바디{}를 구현하는데 목적이 있기때문에 다른용어로 표현함
class Circle extends Shap{
//draw()메서드를 상속받아 구현(implement)해야함 => Overriding(Implements) 필수!
@Override
public void draw() { //must implement (바디를)구현해야한다!
System.out.println("추상클래스로부터 상속받은 추상메서드를 오버라이딩");
System.out.println("원그리기!");
} //구현하기싫으면 추상클래스가 되어야하고 결국 자식의자식의 자식까지 구현(implement)할때까지 간다//빼면 상속 못받음
}
class Rectangle extends Shap{
//추상메서드 오버라이딩에대한 강제성으로 부여되므로 개발자가 실수로 빠뜨릴 위험이 없어짐!
@Override
public void draw() {
System.out.println("추상클래스로부터 상속받은 추상메서드를 오버라이딩");
System.out.println("사각형 그리기!");
}
}
/*
//==================================================================
강제성을 부여하지 않고 클래스를 정의하게 될 경우 발생하는 문제점
//==================================================================
class Shap{
public void draw() {
System.out.println("도형그리기");
}
}
class Circel extends Shap{
/*Shap클래스를 상속받는 Circle클래스는 draw()메서드를 갖게 되지만
* draw()메서드를 오버라이딩 하지않고 다른메서드를 정의하여
* 원을 그려도 부모(Shap) 입장에서는 강제할 방법이 없다!
public void CircleDrew() {
System.out.println("원그리기");
}
}
class Rectangle extends Shap{
/* Shap클래스를 상속받는 Rectangle클래스는 draw()메서드를 갖게 되지만
* 실수로 인해 draw()메서드를 오버라이딩 하지않더라도
* 부모(Shap) 입장에서는 강제할 방법이 없다!
}
*/
'IT > JAVA' 카테고리의 다른 글
[JAVA] 프로그램 실행 과정 (0) | 2020.09.14 |
---|---|
[JAVA] 디자인 패턴(Design patterns)::싱글톤(Singleton):: (0) | 2020.09.14 |
[JAVA] INSTANCEOF 연산자 (0) | 2020.09.08 |
[JAVA] 형변환(기본형변환/참조형변환[upcasting/downcasting]) (0) | 2020.09.07 |
[JAVA] FINAL 키워드 (0) | 2020.09.02 |