java에서도 c++이 .cpp과 .h를 나눠서 코딩하는 것처럼 할 수 있나요?

조회수 1577회

c++ 과제로 코딩할 때 .h 파일에

class 선언하고 private 변수 선언하고 public 함수 ( parameters ) ; 이렇게 하고 cpp에서 함수 구현을 해줬었는데

자바도 이런 방식으로 코딩이 가능할까요? .h 가 설계도 같은 느낌이어서 편했거든요

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 이야기가 길어질 소재네요.

    일단 세 줄 요약

    • C / C++ 이 헤더를 별도로 나누는 건 어쩔 수 없어서입니다
    • Java에는 그런 기능 없습니다
    • 비슷한 건 있는데 용도가 다릅니다...

    C / C++의 컴파일 과정

    C / C++은 컴파일을 파일 단위로 합니다. .cpp 파일을 돌면서 하나하나 컴파일하는데, .h.hpp는 컴파일하지 않습니다.

    그럼 헤더는 대관절 언제 어디서 컴파일하는가 하면, 컴파일하기 이전에 전처리기로 .cpp 파일에 쑤셔넣습니다. 그게 #include 구문입니다.

    왜 이런 짓을 하냐면, C / C++은 남이 개발한 코드를 불러오는 걸 언어 차원에서 지원하질 않거든요. (C++20에 모듈 생긴다던데...)

    대신 컴파일할 때 남의 코드는 공백으로 비워두고, 링크 단계에서 남의 코드를 연결합니다.

    근데 공백으로 비워두려고 해도 일단 함수가 어떻게 생겼는지는 알아야지 컴파일을 하겠죠? 그래서 컴파일하기 이전에 #include.cpp 파일에 남의 함수나 클래스가 어떻게 생겼는지 집어넣습니다.

    Java

    Java는 C++ 이후에 나온 언어입니다. 문제점은 고치고 싶겠죠. 그래서 언어 차원에서 남이 개발한 코드를 불러오는 기능이 있습니다. 그게 import 구문입니다. 코드 최상단에서 많이 보셨죠?

    또, C / C++의 "헤더가 분리된다"는 많은 경우 골칫거리였습니다. 조금만 큰 프로젝트를 하시다보면 여기저기서 같은 헤더를 포함해서 컴파일이 안 되는 사례를 많이 겪어보시게 될 겁니다 (으악). 그래서 아예 나눠쓰지 않게 만들었죠.

    여담이지만 Java는 "패키지" 단위로 컴파일합니다.

    분리해서 쓰기?

    서술하신 설계도 같은 느낌 에 대해서는 할 말이 많습니다.

    1. 긴 코드는 분리 / 리팩터링의 신호

    일단 설계도가 따로 필요한 수준이 되었다는 건 코드가 슬슬 이해하기 힘들어졌다는 뜻입니다. 길어진 코드를 보고 관리하는 건 멘탈이 나갑니다... 이런 시점이 오면 적절한 수준에서 코드를 분리하려고 노력해야 합니다. 그냥 소스째로 보고 이해할 수 있으면 베스트거든요.

    아 물론 필요하다면요. 근데 이 필요성은 어떻게 판단하느냐 하면 ... 이거 프로그래머의 평생에 걸친 과제 중 하나입니다. 소프트웨어 공학, 디자인 패턴, YAGNI 같은 걸 나중에 검색해보셔요.

    2. 완전히 똑같진 않은데... 인터페이스?

    근데 코드 내에서도 이런 "설계도" 가 필요한 시점이 옵니다. 설계도라기보단 약속에 가까운데요, 그래서 인터페이스 라는 게 있습니다.

    인터페이스는 클래스에 이런 함수가 있어야 한다! 라는 약속입니다. 함수 정의만 있어요. 아니 오히려 함수 본문을 못 쓰게 막아놨습니다. 인터페이스를 상속하는 클래스는 인터페이스가 "이런 함수 있어야 해!" 라고 한 함수들을 모두 구현해야 합니다.

    다만 인터페이스는 헤더 파일과 같은 의미가 아닙니다. 왜냐면 인터페이스는 여러 클래스가 지켜야 할 약속이거든요...

    인터페이스에 대해도 공부해보셔요. 비슷한 걸로 추상 클래스(abstract class) 도 있습니다.

    이게 또 웃긴 게 C++에는 인터페이스가 없어서 클래스로 대신합니다...

    3. C#의 partial

    이렇게 클래스에 통으로 정의까지 바로 하는 게 좀 불편한 때도 있습니다. 그래서 Java 옆 나라 언어인 C#에는 partial class 라는 게 있습니다. 물론 언급하신 헤더파일과는 다르지만요...

    partial class로 선언된 클래스는 정의를 따로 나눌 순 없지만 같은 클래스를 쪼개서 다른 파일에 적을 수 있습니다. 이 클래스들은 컴파일 할 때 하나로 합쳐줍니다.

    오리1.cs

    partial class 오리 {
        public void 꽥꽥();
    }
    

    오리2.cs

    partial class 오리 {
        public void 뒤뚱뒤뚱();
    }
    

    컴파일 결과

    class 오리 {
        public void 꽥꽥();
        public void 뒤뚱뒤뚱();
    }
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)