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 |