안드로이드 <Kotlin>

[android/java] 메소드 오버라이딩 시 super 메소드 호출의 필요성

TaeGyeong Lee 2024. 1. 13. 20:29

개요

안드로이드 프로그래밍할때, 우리는 굉장히 많은 메소드를 오버라이딩합니다. 그런데 오버라이딩 시 super 문법을 통해 부모 클래스의 메소드를 호출하는 것 super.onSaveInstanceState(outState); 을 매우 자주 보았을 겁니다. 왜 사용할까요?

메소드 오버라이딩은 일반적으로 부모 클래스 메소드를 사용하지 않고 재정의한 메소드를 사용하기 위함인데, 굳이 부모 클래스의 메소드를 호출하면 오버라이딩한 의미가 별로 없지 않나요?

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);

        ...

    }

 

super

먼저 이 상황을 이해하기 위해선 super 문법을 알고 있어야 합니다. super 문법을 통해 부모 클래스의 메소드를 호출할 수 있습니다. super에 대한 자세한 내용은 이 글을 참고하세요.

 

작성할 필요가 없는 경우

앞서 언급한 onSaveInstanceState 메소드를 오버라이딩할 경우 super.onSaveInstanceState(outState); 를 작성할 필요가 없습니다.

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {

        ...
}

오버라이딩되는 대상,  부모 클래스의 메소드가 아래와 같이 빈 블록으로 정의되어 있기 때문입니다. 

@MainThread
    public void onSaveInstanceState(@NonNull Bundle outState) {
    }

 

빈 블록이 아니더라도, 작성할 필요가 없는 메소드도 있습니다. 아래는 onCreateView 메소드의 정의입니다. null을 반환할 수 있거나, 단순히 멤버 선언일 경우 등등.. 경우에 따라 다양한 이유로 작성할 필요가 없습니다.

    @MainThread
    @Nullable
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        if (mContentLayoutId != 0) {
            return inflater.inflate(mContentLayoutId, container, false);
        }
        return null;
    }

 

반드시 작성해야 하는 경우

단, 그렇다고 해서 모든 메소드 오버라이딩 시 부모 클래스 메소드를 호출하지 않아도 되는 것은 아닙니다. 아래와 같이 부모 클래스의 메소드, onCreate 메소드는 오버라이딩 시 반드시 부모 클래스의 메소드를 호출해야 합니다.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // 반드시 작성해야 합니다. 미작성 시 에러
        
        ...
    }

아래는 부모 클래스의 onCreate 메소드 정의입니다. 부모 클래스의 메소드는 또 다시 조부모 클래스의 메소드를 상속받고 조부모 메소드 호출 후 fragment 생명주기를 통제하고 있습니다. onCreate 메소드의 경우 생명주기 통제가 반드시 필요합니다.

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        mFragments.dispatchCreate();
    }

따라서 onCreate 메소드는 반드시 오버라이딩 시 부모 메소드를 호출해 주어야 합니다. 

 

작성하면 되는 경우

onPressedBack 메소드의 경우 상황에 따라 super.onPressedBack(); 을 작성하면 안됩니다. 아래 코드를 보세요.

@Override
    public void onBackPressed() {
        if(System.currentTimeMillis() - backPressedTime >= 2000) {
            Toast.makeText(getBaseContext(), "Press back again to exit", Toast.LENGTH_SHORT).show();
        } else {
            super.onBackPressed();
        }
        backPressedTime = System.currentTimeMillis();
    }

 

만약 super.onBackPressed(); 를 블록 제일 앞에 작성한 경우 뒤로가기 버튼은 누르는 경우 무조건 바로 해당 액티비티는 종료됩니다. 즉, 구현하고자 하는 바에 따라 작성하면 안될 수도 있습니다.

@Override
    public void onBackPressed() {
    	super.onBackPressed(); // 부모 클래스의 메소드는 해당 액티비티를 종료시키므로 아래 코드는 의미가 없어집니다.
        if(System.currentTimeMillis() - backPressedTime >= 2000) {
            Toast.makeText(getBaseContext(), "Press back again to exit", Toast.LENGTH_SHORT).show();
        } else {
            super.onBackPressed();
        }
        backPressedTime = System.currentTimeMillis();
    }

 

DRY (Don't repeat yourself)

소프트웨어 공학 이론 중 하나인 DRY는 코드의 중복을 최소화하고 재사용성을 높이기 위한 원칙입니다. 가령, 안드로이드 개발 환경에서 onSaveInstanceState 메소드에 몇 가지 새로운 기능이 추가되었다고 가정해봅시다. 이런 경우, 이미 작성된 코드에 영향을 최소화하면서 새로운 변화에 대응할 수 있어야 합니다.

여기서 super.onSaveInstanceState(outState); 코드가 주목받습니다. onSaveInstanceState 메소드의 변경에 상관없이, 이 코드를 사용하면 앱 개발자는 추가 코드 수정 없이도 새로운 버전에 유연하게 대응할 수 있습니다.

간단히 말하면, super.onSaveInstanceState(outState); 코드는 DRY한 코드를 유지하도록 도와줍니다. 이미 존재하는 코드에 영향을 최소화하면서 새로운 변화에 대응함으로써 개발자는 코드 간 상호 영향을 최소화하고 더욱 유연하게 개발할 수 있습니다.

 

개인적인 생각

사용하지 말아야 하는 경우를 제외하고, 기본적으로 이 코드를 작성하는 것이 좋다고 생각합니다. 앞서 언급한 DRY 원칙을 지키는 것이 좋기 때문입니다.

 

참고 자료

 

What is the purpose of calling super class's method while overriding a method?

While overriding methods like onPostExecute from AsyncTask we can avoid or remove super.onPostExecute(result); from it. Can you tell me why and when do we need to use this call? as I here implemented

stackoverflow.com

 

Don't repeat yourself - Wikipedia

From Wikipedia, the free encyclopedia Principle of software development "Don't repeat yourself" (DRY) is a principle of software development aimed at reducing repetition of information which is likely to change, replacing it with abstractions that are less

en.wikipedia.org

https://www.geeksforgeeks.org/how-to-implement-press-back-again-to-exit-in-android/

 

How to Implement Press Back Again to Exit in Android? - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org