728x90
반응형
추상메서드
- 메서드 구현부(바디, {}) 가 없는 메서드
실행할 코드가 없는 메서드 - 구현부가 없기 때문에 외부에서 호출해도 실행할 코드가 없음
따라서, 추상메서드를 포함하는 클래스는 반드시 추상클래스로 선언해야한다 - 추상메서드 정의 시 리턴타입 앞에 abstract 키워드를 붙임
추상메서드 정의 기본 문법
[접근제한자] abstract 리턴타입 메서드명([매개변수..]);
추상클래스
- 인스턴스 생성이 불가능한 클래스 인스턴스 생성이 가능할 경우 추상메서드 호출이 가능하므로 인스턴스 생성을 못하도록 막아놓은 클래스
- 상속을 통해 서브클래스에서 추상메서드를 구현하도록 강제하는 용도의 클래스로 주로 사용
- 추상클래스가 가질 수 있는 멤버 생성자, 일반 멤버변수, 상수, 일반 메서드, "추상 메서드"
- 추상클래스 정의 시 class 키워드 앞에 abstract 키워드를 붙임
- 인스턴스 생성은 불가능하지만, 참조변수 타입으로는 사용 가능
추상클래스 정의 기본 문법
abstract class 클래스명 {}
추상클래스와 추상메서드를 사용하여 강제성을 부여하는 방법
// 1. 추상메서드 draw() 를 갖는 추상클래스 Shape 정의
abstract class Shape {
// public abstract void draw() {} // 추상메서드는 바디를 가질 수 없다!
public abstract void draw();
}
// 2. 추상클래스 Shape 을 상속받는 서브클래스 Circle 정의
// => 추상메서드가 존재하는 경우 서브클래스에서 반드시
// 추상메서드를 구현(implements)해야한다!
// 구현(implements) 과 오버라이딩(Overriding) 은 동일한 기능이지만
// 메서드 바디{} 를 구현하는데 목적이 있기 때문에 다른 용어로 표현함
class Circle extends Shape {
// draw() 메서드를 상속받아 구현해야함 => Overriding(Implements) 필수!
@Override
public void draw() {
System.out.println("추상클래스로부터 상속받은 추상메서드 오버라이딩");
System.out.println("원 그리기!");
}
}
// Shape 클래스를 상속받는 Rectangle 클래스 정의
class Rectangle extends Shape {
// 추상메서드 오버라이딩에 대한 강제성으로 부여되므로
// 개발자가 실수로 빠뜨릴 위험이 없어짐!
@Override
public void draw() {
System.out.println("추상클래스로부터 상속받은 추상메서드 오버라이딩");
System.out.println("사각형 그리기!");
}
}
강제성을 부여하지 않고 클래스를 정의하게 될 경우 발생하는 문제점
// 도형 클래스 정의
//class Shape {
//
// public void draw() {
// System.out.println("도형 그리기!");
// }
//
//}
//
//// 원(Circle) 클래스 정의 - Shape 상속
//class Circle extends Shape {
// /*
// * Shape 클래스를 상속받는 Circle 클래스는 draw() 메서드를 갖게 되지만
// * draw() 메서드를 오버라이딩 하지 않고 다른 메서드를 정의하여
// * 원을 그려도 부모(Shape) 입장에서는 강제할 방법이 없다!
// */
// public void circleDraw() {
// System.out.println("원그리기!");
// }
//}
//
//// 사각형(Rectangle) 클래스 정의 - Shape 상속
//class Rectangle extends Shape {
// /*
// * Shape 클래스를 상속받는 Rectangle 클래스도 draw() 메서드를 갖게 되지만
// * 실수로 인해 draw() 메서드 오버라이딩을 하지 않았더라도
// * 부모(Shape) 입장에서는 강제할 방법이 없다!
// */
//}
//Shape s = new Shape(); // 오류 발생!
// Cannot instantiate the type Shape
// => 인스턴스화가 불가능한 타입이므로 인스턴스 생성 시 오류 발생!
// 참조변수의 데이터타입으로 사용은 가능
Shape s = new Circle();
s.draw();
s = new Rectangle();
s.draw();
public class Ex {
public static void main(String[] args) {
SubClass sc = new SubClass();
sc.normalMethod(); // 상속받은 일반메서드
sc.abstractMethod1(); // MiddleClass 에서 구현한 추상메서드
sc.abstractMethod2(); // SubClass 에서 구현한 추상메서드
// 추상클래스로 인스턴스 생성 불가
// AbstractClass ac = new AbstractClass();
// MiddleClass mc = new MiddleClass();
// 변수 타입으로 사용되어 업캐스팅 활용은 가능
MiddleClass mc = sc;
mc.normalMethod(); // 상속받은 일반메서드
mc.abstractMethod1(); // MiddleClass 에서 구현한 추상메서드
mc.abstractMethod2(); // SubClass 에서 구현한 추상메서드
AbstractClass ac = sc;
ac.normalMethod(); // 상속받은 일반메서드
ac.abstractMethod1(); // MiddleClass 에서 구현한 추상메서드
ac.abstractMethod2(); // SubClass 에서 구현한 추상메서드
}
}
// 추상클래스
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(
"MiddleClass 에서 구현한 추상메서드 abstractMethod1()");
}
}
// MiddleClass 를 상속받는 SubClass 정의
// => MiddleClass 에서 구현되지 않은 abstractMethod2() 메서드에 대한
// 구현 책임이 발생함! => 반드시 오버라이딩
class SubClass extends MiddleClass {
@Override
public void abstractMethod2() {
System.out.println(
"SubClass 에서 구현한 추상메서드 abstractMethod2()");
}
}
728x90
반응형
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
[JAVA] 자바의 상수 Constant (0) | 2021.01.19 |
---|---|
[JAVA] 자바의 Static (0) | 2021.01.19 |
[JAVA] 자바의 참조형변환 (레퍼런스 형변환) (0) | 2021.01.19 |
[JAVA] 자바의 final (0) | 2021.01.19 |
[JAVA] 자바의 this & super (0) | 2021.01.19 |