추상

doldol_kim·2020년 2월 28일
0

Java-OOP

목록 보기
4/6

추상(Abstract)이란 ?

클래스를 상속하여 사용하도록 강제하는 것.

부모 클래스에는 메소드의 서명(껍데기)만 정의해놓고 해당 메소드의 실제 동작은 부모 클래스를 상속한

자식 클래스에서 구현하도록 책임을 위임하는것

  • 키워드 : abstract

추상의 특징

  • 추상 클래스를 사용하기 위해서는 반드시 추상 클래스를 상속받는 클래스를 정의하여 사용해야 한다.
    • 추상 클래스에 추상 메소드가 정의되어 있다면, 상속 받는 클래스에서는 그 메소드를 오버라이딩 하여 구체적인 내용을 구현해야한다.
  • 본체가 있는 메소드는 abstract 키워드를 쓸 수 없다.
  • 추상 클래스에서 일반 메소드는 사용 가능하다.
package pr01;
abstract class A{
    public abstract int b();
    /*public abstract int c(){ // 본체가 있는 메소드는 abstract 키워드를 쓸 수 없다
        System.out.println("Hi");
    }*/
    public void d(){ // 추상 메소드가 아닌, 일반 메소드도 추상 클래스에서 쓸 수 있다.
        System.out.println("Hello");
    }
}
//class B extends A{} //Error:(11, 1) java: pr01.B is not abstract and does not override abstract method b() in pr01.A --> 추상 클래스에 있는 메소드를 오버라이딩 해야함
class B extends A{ //
    @Override
    public int b() {
        return 0;
    }
}
public class test {
    public static void main(String[] args) {
        //A abs1 = new A(); //Error: pr01.A is abstract; cannot be instantiated
        // 추상 클래스는 상속을 강제하므로, 상속을 받아서 사용해야 한다.
        B abs2 = new B();
        abs2.b();
        abs2.d();
    }
}

추상을 왜 사용할까

추상은 소규모 프로그램에서는 크게 사용할 필요가 없어 보인다. 하지만 규모가 큰 프로그램의 경우 다양한 상황에서 사용되는 하나의 기능이 있을 때, 그 기능의 공통적인 부분을 추상 클래스로 만들어서 추상 클래스에는 공통적인 로직만 구현하고, 하위 클래스에서는 용도에 따라 달라지는 기능을 구현할 수 있다.

아래의 코드를 보며 추상을 사용한 것과 사용하지 않은 코드의 차이를 확인해보자

  • 추상 클래스 사용

    package pr01;
    
    abstract class Calculator{
        int left, right;
        public Calculator(int left, int right){
            this.left=left;
            this.right=right;
        }
        public abstract void sum();
        public abstract void avg();
        public void run(){
            sum();avg();
        }
    }
    class CalculatorPlus extends Calculator{
        public CalculatorPlus(int left, int right) {
            super(left, right);
        }
        @Override
        public void sum() {
            System.out.println("+ sum "+(this.left+this.right));
        }
        @Override
        public void avg() {
            System.out.println("+ avg "+(this.left+this.right)/2);
        }
    }
    class CalculatorMinus extends Calculator{
        public CalculatorMinus(int left, int right) {
            super(left, right);
        }
        @Override
        public void sum() {
            System.out.println("- sum "+(this.left+this.right));
        }
        @Override
        public void avg() {
            System.out.println("- avg "+(this.left+this.right)/2);
        }
    }
    public class test {
        public static void main(String[] args) {
            CalculatorPlus c1 = new CalculatorPlus(10,20);
            c1.run();
    
            CalculatorMinus c2 = new CalculatorMinus(10,20);
            c2.run();
        }
    }
    /*
    + sum 30
    + avg 15
    - sum 30
    - avg 15
    */

    추상 클래스인 Calculator2개의 추상 메소드1개의 일반 메소드가 있다.

    Calculator를 상속한 CalculatorPlusCalculatorMinus무조건 sum()avg()를 구현해야한다.

    이 둘은 추상 메소드이기 때문이다. 만약, 이 중 하나라도 구현하지 않는다면 오류가 나며 실행이 되지 않는다.

  • 추상 클래스를 사용하지 않음

    package pr01;
    
    class Calculator{
        int left, right;
        public Calculator(int left, int right){
            this.left=left;
            this.right=right;
        }
        public void sum(){System.out.println("부모입니다");}
        public void avg(){}
        public void run(){
            sum();avg();
        }
    }
    class CalculatorPlus extends Calculator{
        public CalculatorPlus(int left, int right) {
            super(left, right);
        }
        // sum() 메소드를 구현하지 않았다.
        @Override
        public void avg() {
            System.out.println("+ avg "+(this.left+this.right)/2);
        }
    }
    class CalculatorMinus extends Calculator{
        public CalculatorMinus(int left, int right) {
            super(left, right);
        }
        @Override
        public void sum() {
            System.out.println("- sum "+(this.left+this.right));
        }
        @Override
        public void avg() {
            System.out.println("- avg "+(this.left+this.right)/2);
        }
    }
    public class test {
        public static void main(String[] args) {
            CalculatorPlus c1 = new CalculatorPlus(10,20);
            c1.run();
    
            CalculatorMinus c2 = new CalculatorMinus(10,20);
            c2.run();
        }
    }
    /*
    부모입니다
    + avg 15
    - sum 30
    - avg 15
    */

public classCalculator3개의 일반 메소드가 있다.

Calculator를 상속한 CalculatorPlusCalculatorMinussum()avg()구현하지 않아도 된다.

CalculatorPlus를 보면 sum() 메소드를 구현하지 않았다. 하지만, 이래도 실행은 되고 실행결과는 부모 클래스에 있던 "부모입니다" 가 출력되었다.

CalculatorPlus를 만들때 실수로 sum()메소드를 정의 못 할 수 있다. 이럴 경우 부모 클래스에서 구현된 sum()이 호출되어 원하지 않는 모습으로 동작할 수 있다.

추상을 사용한다면, 추상 메소드를 강제로 구현해야 하므로 이러한 실수를 사전에 방지할 수 있다.

profile
김돌돌입니다

0개의 댓글