[Java] abstract

SeongEon Kim·2022년 5월 2일
0

JAVA

목록 보기
27/52

abstract는 상속을 강제하는 일종의 규제이다. 즉, abstract 클래스나 메소드를 사용하기 위해서는 반드시 상속해서 사용하도록 강제하는 것이다.

  1. 문법적인 측면
    package org.opentutorials.javatutorials.abstractclass.example1;
    abstract class A{
    	//class A가 추상 클래스라는 의미
       public abstract int b();
       //본체가 있는 메소드는 abstract 키워드를 가질 수 없다.
       //public abstract int c(){System.out.println("Hello")}
       //추상 클래스 내에는 추상 메소드가 아닌 메소드가 존재 할 수 있다. 
       public void d(){
           System.out.println("world");
       }
    }
    public class AbstractDemo {
       public static void main(String[] args) {
           //A obj = new A();
           //여기서 에러가 발생한다.
       }
    }

 위의 코드를 살펴보면
 메소드 b의 선언 부분에는 abstract라는 키워드가 등장하고 있다. 이 키워드는  메소드 b는 메소드의 시그니처만 정의되어 있고 이 메소드의 구체적인 구현은 하위 클래스에서 오버라이딩 해야 한다는 의미다. 이렇게 내용이 비어있는 메소드를 추상 메소드라고 부른다. 추상 메소드를 하나라도 포함하고 있는 클래스는 추상 클래스가 되고, 자연스럽게 클래스의 이름 앞에 abstract가 붙는다.
 
 위의 코드에서 오류가 발생하는 것은 추상 클래스 A를 인스턴스화 시키면서 발생하는 것이다. 추상 클래스는 구체적인 메소드의 내용이 존재하지 않기 때문에 인스턴스화시켜서 사용할 수 없기 때문이다. 
 
 아래 코드를 살펴보자.
 

package org.opentutorials.javatutorials.abstractclass.example2;
abstract class A{
public abstract int b();
public void d(){
System.out.println("world");
}
}
class B extends A{
public int b(){return 1;}
}
public class AbstractDemo {
public static void main(String[] args) {
B obj = new B();
System.out.println(obj.b());
}
}


 클래스 B는 클래스 A를 상속했다. 그리고 클래스 A의 추상 메소드인 메소드 b를 오버라이딩하고 있다. 그 결과 클래스 A가 사용 가능하게 된다.
 
2. 추상 클래스의 기능

 추상 클래스는 상속을 강제하기 위한 것이다. 즉 부모 클래스에는 메소드의 시그니처만 정의해놓고 그 메소드의 실제 동작 방법은 이 메소드를 상속 받은 하위 클래스의 책임으로 위임하고 있다. 
 
 아래 코드를 통해 자세히 알아보자.
 

package org.opentutorials.javatutorials.abstractclass.example3;
abstract class Calculator{
int left, right;
public void setOprands(int left, int right){
this.left = left;
this.right = right;
}
public abstract void sum();
public abstract void avg();
public void run(){
//여기서 run은 아래 메소드들을 순서대로 실행시키는 로직이다.
sum();
avg();
}
}
class CalculatorDecoPlus extends Calculator {
public void sum(){
System.out.println("+ sum :"+(this.left+this.right));
}
public void avg(){
System.out.println("+ avg :"+(this.left+this.right)/2);
}
}
class CalculatorDecoMinus extends Calculator {
public void sum(){
System.out.println("- sum :"+(this.left+this.right));
}
public void avg(){
System.out.println("- avg :"+(this.left+this.right)/2);
}
}
public class CalculatorDemo {
public static void main(String[] args) {
CalculatorDecoPlus c1 = new CalculatorDecoPlus();
c1.setOprands(10, 20);
c1.run();

    CalculatorDecoMinus c2 = new CalculatorDecoMinus();
    c2.setOprands(10, 20);
    c2.run();
}

}


 코드를 보면 합계(sum)를 실행하고 평균(avg)를 실행하는 절차를 메소드 run을 통해서 한 번에 실행되도록 하고 있다. 하지만 경우에 따라 합계와 평균을 화면에 출력하는 모습을 달리해야 하는 경우가 생길 수 있다. 이때 상황에 따라 동작 방법이 달라지는 메소드(sum, avg)는 추상 메소드로 만들어서 하위 클래스에서 구현하도록 하고 모든 클래스의 공통분모(setOprands, run)의 경우에는 상위 클래스에 두어서 코드의 중복, 유지보수의 편의성 등을 꾀할 수 있다.
 
profile
꿈을 이루는 사람

0개의 댓글