프로그래밍 언어/JAVA

[JAVA] 자바의 추상 클래스 & 메서드

Rateye 2021. 1. 19. 14:47
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