※ 본 포스팅은 생활코딩 이고잉님의 강의를 공부한 후 개인적인 학습목적으로 작성하였습니다. 생활코딩에서 더 자세하고 정확한 정보를 얻으시려는 분들은 아래 참고자료를 확인해주세요. ※
자바 문서 보는 법 - API vs. UI
컴퓨터를 사용하려면 컴퓨터가 있어야 합니다. 그런데 컴퓨터 하드웨어를 직접 다루는 것은 어렵기 때문에 컴퓨터에다 운영체제를 설치합니다. 운영체제의 종류로는 윈도우, macOS, 리눅스 등이 있습니다. 이전 수업에서는 이러한 운영체제 위에 자바라고 하는 프로그램을 설치했습니다. 그리고 자바를 이용해 나의 프로그램을 만들 수 있었습니다. 그런데 프로그램은 무턱대고 만들 수 있는 것이 아니라 자바에서는 우리가 프로그램을 쉽게 만들 수 있도록 여러 가지 부품들을 제공합니다. 예를 들어, 화면에 뭔가를 출력하고 싶을 때는 System.out.print를, 날짜를 알고 싶을 때는 Date 클래스를, 수학적인 연산을 하기 위해서는 Math 클래스를 이용했습니다. 이처럼 자바에 기본적으로 내장된 System.out.print나 Date 클래스 같은 기능들을 기본 라이브러리라고 합니다. 즉, 라이브러리라고 하는 부품을 이용해 나의 프로그램을 만드는 것입니다. 나의 프로그램을 만들 때는 자바가 제공하는 기본적인 문법을 사용해서 시간 순서에 따라 자바가 제공하는 기본 라이브러리를 실행되게 해서 프로그램을 만드는 것입니다. 이 같은 맥락에서 자바가 기본적으로 제공하는 부품들을 조작하는 방법을 Application Programming Interface; API라고 합니다. 프로그램이라는 말은 ‘시간 순서에 따라서 실행된다’라는 시간이 강조된 표현이고, 애플리케이션이라는 것은 ‘자바가 제공하는 부품들을 응용해서 만든다’라는 응용 관점의 표현입니다. 즉, 자바를 응용해서 프로그래밍적으로 실행되는 프로그램을 만들기 위해 사용해야 하는 조작 장치 또는 조작 방법을 애플리케이션 프로그래밍 인터페이스(API)라고 부르는 것입니다. 그래서 프로그램을 잘 만들기 위해서는 어떤 API가 있고, API를 어떻게 조작하는가를 정확히 알아야 하고, API를 잘 활용하는 것이 좋은 프로그래머가 되는 초석이라고 할 수 있습니다.
그런데 우리가 만든 결과물이 사람에게 사용된다면 그 프로그램을 조작하기 위해 조작해야 하는 조작 장치들이 있을 것입니다. 예를 들어, 웹 프로그램이라면 링크가 있을 테고, 데스크톱 애플리케이션이라면 버튼이 있을 테고, 커맨드 라인 시스템이라면 아규먼트 같은 것이 있습니다. 이러한 것들을 가리켜 사용자가 프로그램을 조작하기 위해 사용하는 조작 장치라는 뜻에서 User Interface, 줄여서 UI라고 부릅니다. 또한 우리가 만든 프로그램은 사람이 사용하지 않을 수도 있습니다. 우리가 만든 프로그램을 부품으로 사용하는 또 다른 프로그램이 있을 수도 있습니다. 그런 경우에는 우리가 만든 프로그램이 우리의 프로그램을 사용하는 다른 프로그램에게 애플리케이션 프로그래밍 인터페이스를 제공해야 합니다. 그리고 그 프로그램이 다시 또 다른 프로그램에서 사용된다면 다른 프로그램에게도 API를 제공해야 합니다. 이번 수업부터는 자바가 제공하는 기본 라이브러리를 사용하는 방법, 즉 API의 사용법을 스스로 알아내는 방법을 살펴보겠습니다.
Self Question
1. Java에서 API란?
2. UI란?
자바 문서 보는 법 - 패키지, 클래스, 변수, 메서드
이번 수업에서는 자립의 핵심 기술이라고 할 수 있는 자바의 공식 사용 설명서를 보는 방법을 살펴보겠습니다. 구글과 같은 검색 엔진에서 ‘api documentation java’라는 검색어에 버전을 함께 적어서 검색하면 자바의 공식 사용 설명서 페이지를 찾을 수 있습니다.
자바 공식 문서 페이지로 들어가면 자바가 기본적으로 제공하는 부품들, 다시 말해 라이브러리에 대한 설명서를 볼 수 있습니다. 보다시피 화면이 두 개로 나눠져 있는데, 왼쪽 화면에 All Classes 아래에는 약 4,000개의 항목이 있습니다. 클래스라고 하는 것은 하나의 프로그램이라고 생각하면 됩니다. 만약 수학과 관련된 어떤 작업을 해야 하는데 그러한 기능을 직접 만들기 싫을 때 All Classes 밑에서 Math를 검색해 보면 됩니다. Math라고 검색했을 때 나오는 것이 Math 클래스이고, 이 클래스를 클릭하면 오른쪽 화면에서 math 클래스의 상세 정보를 확인할 수 있습니다.
Ctrl F로 Math 를 검색한 후 All classes에서 Math 클래스를 클릭하면 위와 같은 화면이 나옵니다. 이 클래스를 클릭하면 오른쪽 화면에서 Math 클래스의상세 정보를 확인할 수 있습니다. Class Math 위에 java.lang이라고 적혀 있는 것은 Math 클래스가 속한 패키지(package)를 나타냅니다. 아직 클래스에 대해서는 잘 모르지만 한번 상상해 봅시다. 만약 클래스가 엄청나게 많아지면 자바에서 기본적으로 제공되는 약 4,000개의 클래스가 정리정돈돼 있지 않고 흩어져 있으면 우리가 필요로 하는 것을 찾기가 어려울 것입니다. 또는 이미 Math라는 이름의 클래스가 있는데 여러분이 직접 math라는 클래스를 만들고 싶다면 똑같은 이름이 같은 공간에 있어서 충돌할 것입니다. 이 같은 문제를 해결하기 위한 것이 패키지입니다. 그래서 위 그림의 math는 java.lang에 속해 있는 것입니다.
화면의 왼쪽 상단에는 Packages가 위치합니다. Packages는 자바가 기본적으로 제공하는 여러가지 패키지의 목록을 나타냅니다. 예를 들어, Packages에서 java.lang을 검색하면 java.lang 패키지가 있는 것을 확인할 수 있습니다. 그리고 java.lang 패키지를 클릭하면 이 패키지에 속한 여러 클래스들의 목록이 나타나고, 그중 하나가 바로 Math이고 지금까지 사용해온 String 클래스도 이 패키지 안에 속한 것을 확인할 수 있습니다. 즉, 패키지는 서로 연관된 비슷한 성격의 클래스를 모아서 이름을 붙인 것이라고 생각하면 되고, 클래스는 서로 연관된 변수와 메서드를 모아서 이름을 붙인 것이라고 생각하면 됩니다.
위의 그림을 보면 math 클래스에 E, PI 등의 변수와 abs 등의 메서드가 있습니다. 이처럼 수학과 관련된 변수와 메서드를 그루핑한 것이 바로 Math 클래스입니다. 정리하면 관련 클래스들을 그루핑해서 이름을 붙인 것이 패키지이고, 변수와 메서드를 그루핑한 것이 클래스입니다. 다음 그림을 기억해 두시면 이후에 나오는 내용이 조금 더 쉽게 이해될 것입니다.
Self Question
1. 패키지란 무엇인가?
2. 클래스란 무엇인가?
자바 문서 보는 법 - 클래스
이번 수업에서는 클래스에 대한 실습을 한번 해봅시다. 먼저 클래스가 무엇인지 이해하기 위해 새로운 실습용 클래스를 만들겠습니다. 클래스의 이름은 ClassApp으로 지정하고, ‘public static void main(String[] args)’ 옵션을 체크합니다. 그리고 Finish 버튼을 클릭해 실습을 진행할 기본적인 코드를 생성합니다. 이번 실습을 통해 클래스를 사용하는 이유와 사용법을 소개하겠습니다. 실습에서 수학과 관련된 작업을 해야 한다고 가정해 보겠습니다. 그리고 지금 3.14… 라는 파이의 값이 구체적으로 기억나지 않는다고 가정해보겠습니다. 그럼 어떻게 하면 될까요? 자바는 수학과 관련된 작업을 할 때 도움을 주기 위해 수학과 관련된 클래스를 기본적으로 내장하고 있습니다. 수학과 관련된 클래스의 이름이 바로 Math입니다. 그리고 Math 클래스명을 적고 점(.)을 찍으면 해당 클래스에 속한 변수나 메서드의 목록이 표시됩니다. Math 클래스에 들어 있는 여러 변수와 메서드 중에서 이번 실습에서 필요한 것은 파이의 구체적인 값입니다. 따라서 파이 값을 입력하기 위해 Math.PI라고 입력합니다. 이는 3.14… 라는 파이의 구체적인 값이 적당한 정밀도로 저장돼 있는 변수가 PI인데, 이러한 PI 변수가 Math라는 클래스에 속해 있기 떄문입니다. 클래스를 이해하기 위해 파일과 디렉터리에 비유해 보겠습니다. 파일이 1억 개가 있는데, 디렉터리가 없다면 난장판일 것입니다. 이 같은 상황에서 유용한 도구가 디렉터리이고 클래스가 이 디렉터리와 비슷한 것이라고 생각하면 됩니다. 클래스는 서로 연관된 변수와 메서드를 그루핑한다는 점을 기억하시기 바랍니다. 그럼 다음과 같은 PI 변수의 값을 출력하는 코드를 실행해 봅시다.
다음과 같이 출력되는 것을 알 수 있습니다.
이번에는 어떤 정보가 필요한 것이 아니라 어떤 정보를 처리하고 싶다고 가정해 봅시다. 예를 들어, 1.6이라는 값을 구했을 때 소수점 아래를 버리고 싶다면 수학에서는 내림을 사용하면 됩니다. 영어로 내림은 바닥이라는 뜻에서 floor입니다. Math에 속한, 여러 가지 정보를 처리하는 방법들 중에 floor가 있습ㄴ다. 다음은 이러한 floor를 사용하는 예입니다.
보다시피 3.14를 통과시키면 3.0이 됩니다. 3.14…라는 숫자를 무조건 오렬서 4.0으로 만드는 방법도 사용해 봅시다. 이를 가리키는 수학적 개념은 올림이고 영어로는 천장이라는 뜻에서 ceil이라고 합니다.
보다시피 3.14… 라는 값이 ceil 메서드를 통과하면 소수점 이하가 올림되어 4.0이 됩니다. 다시 한번 강조하지만 클래스는 서로 연관된 변수와 메서드를 모아서 이름을 붙인 것입니다. 지금 당장 자신의 클래스를 만들 필요가 없어서 클래스를 만드는 법은 모르더라도 남이 만든 클래스를 사용하려면 사용법 정도는 알아야 합니다. 이번 수업에서는 클래스의 사용법을 알아봤습니다.
Self Question
1. 클래스를 사용하는 이유는?
자바 문서 보는 법 - 인스턴스
이전 수업에서는 클래스가 무엇인지 살펴봤습니다. 클래스는 서로 연관된 변수와 메서드를 모아서 이름을 붙인 것입니다. 이번 수업에서는 인스턴스(Instance)라는 것에 대해 살펴보겠습니다. 인스턴스는 대단히 중요하지만 너무나 어렵고 처음 듣고 이해하는 것이 이상할 정도니까 마음 편하게 구경하시면 되는 주제입니다. 먼저 실습을 위해 InstanceApp이라는 클래스를 만들겠습니다. 이번 실습에서 어떤 작업을 하려고 하는지 먼저 설명해 드리자면 result1.txt 파일에 “hello1”이라는 텍스트를 자바를 이용해 작성하려고 합니다. 여러분도 이 코드를 작성하기 위해 검색을 통해 어떤 클래스가 필요한지를 알아내고 클래스를 사용하는 예제를 찾아보시고, 그래도 이해가 안가는 내용이 있다면 API 문서를 분석해서 시간이 오래 걸리더라도 사용법을 알아내야 합니다. 이러한 과정을 진행했다고 가정하고 코딩을 진행해보겠습니다.
여기서는 FileWriter와 IOException 이라는 두 개의 클래스를 사용했는데, 자세히 한번 알아보도록 하겠습니다.
String filename = "result1.txt";
filename 이라는 변수에 “result1.txt”라는 문자를 할당했다.
FileWriter writer = null;
This line declares a FileWriter object named "writer" and initializes it to null.
writer라는 이름을 가진 FileWriter 오브젝트를 생성하고 null 값으로 초기화시킨다.
try {
This begins a try block where code that could throw an exception is contained.
writer = new FileWriter(filename);
This line creates a new FileWriter object with the file name specified earlier and assigns it to the "writer" variable.
앞서 생성한 writer라는 이름을 가진 FileWirter 객체에 filename(”result1.txt”)을 값으로 가진 FileWriter 객체를 새로 생성하여 할당한다.
} catch (IOException e) {
This catch block is executed if an IOException is thrown, meaning that there was an error writing to the file.
만약 IOException 이 돌아오면 catch block을 실행하는데, 다시 말해 에러가 발생하면 해당 블록의 코드를 실행한다는 것을 의미한다.
파일에 문자열을 작성하는 데는 여러 가지 방법이 있겠지만 여기서는 PrintWriter라는 클래스를 이용하겠습니다. 그런데 PrintWriter 클래스는 Math 클래스와는 사용법이 상당히 다릅니다.
Math 클래스는 Math라고 적으면 끝나는데 보다시피 PrintWriter 클래스는 뒤에다 괄호를 붙여서 텍스트를 저장할 파일의 이름을 적습니다. 또한 PrintWriter 앞에 new를 붙여서 PrintWriter의 복제본을 만들어서 PrintWriter 복제본을 p1이라는 변수에 담습니다. 그러면 p1 변수에는 PrintWriter 클래스의 인스턴스가 담기게 됩니다. 그리고 p1 변수에는 아무거나 들어가면 안 되기 때문에 p1에는 반드시 PrintWriter 클래스의 인스턴스만 들어간다는 뜻에서 데이터 타입으로 PrintWriter를 지정합니다. 그런데 이렇게 코드를 작성하고 나면 코드에 빨간색 밑줄 이생깁니다. PrintWriter 클래스를 불러오지 않아서 생기는 에러입니다. Math 클래스의 경우에는 특별한 조치를 하지 않아도 사용할 수 있지만 PrintWriter 클래스는 자바에 내장돼 있긴 하지만 패키지를 가져오는 작업을 해야만 사용할 수 있습니다. 클래스를 ‘가져온다’는 뜻에서 import를 사용해 실습에 필요한 PrintWriter 클래스를 가져오겠습니다. PrintWriter 클래스는 java의 io라는 패키지에 속해 있습니다. 따라서 이 파일 내에서 PrintWriter라는 이름의 클래스를 불러오겠다는 의미로 improt java.io.PrintWriter;라는 코드를 작성합니다.
그러고 나면 빨간색 밑줄이 생기는 범위가 바뀌게 됩니다. 이것은 파일을 읽을 때 파일이 없으면 문제가 될 수 있고 현재 파일이 없기 때문에 예외 상황이라고 자바에서 알려주는 것입니다.
이처럼 파일이 없는 상황에 대한 예외를 어떻게 처리할지에 대해서는 우리가 정해야 하는데, 지금 당장은 처리하기가 너무 어렵습니다. 그래서 예외를 배우거나 전문적인 소프트웨어를 만들기 전까지는 Add throws declaration이라는 항목을 클릭하면 됩니다. 그러고 나서 다음 단계에서 IOException을 선택합니다.
아무튼, p1 인스턴스 변수에서 write 메서드를 사용해 “Hello 1”을 텍스트 파일에 작성합니다. p1 인스턴스 변수에 대한 작업이 끝나면 close 메서드로 파일을 더 이상 붙잡고 있지 않게 해서 다른 사람도 파일을 수정할 수 있게 합니다. 그런 다음, 똑같은 코드를 복사해서 p2를 만들어 봅니다. 코드를 실행한 다음, 패키지 익스플로러 또는 내비게이터에서 마우스 우클릭 후 Refresh를 하면 result1.txt 파일과 result2.txt 파일이 생성되는 것을 확인할 수 있습니다.
그럼 원점으로 돌아와서 이번 수업의 중심 주제인 인스턴스에 대해 얘기해 보겠습니다. Math 클래스는 그냥 클래스명에다 점을 찍고 변수나 메서드를 곧바로 사용했습니다. 그런데 PrintWriter의 경우에는 new를 붙이고 PrintWriter를 복제한 결과를 p1 변수에 담았다는 차이점이 있습니다. 왜 굳이 이렇게 하는지를 한번 살펴보겠습니다.
인스턴스를 사용하지 않고 위와 같이 파일 명과 내용을 적어서 사용할 수 있다고 가정해봅시다. 실제로는 저런 코드가 작동하지 않습니다.
그러면, 여러 파일에 무언가를 적을 때마다 일일이 어떤 파일에 어떤 내용을 적을거야라는 것을 기입해 주어야 합니다. 비효율적이란 말이죠. (인스턴스를 사용하는 이유)
반면에 인스턴스를 사용하면, 훨씬 효율적으로 코드를 작성할 수 있습니다. 이런 차이가 발생하는 이유는 다음과 같습니다. 클래스에다가 직접 write 메서드를 사용하는 방식에서는 어떤 파일을 수정할지를 그때그때 알려줘야 합니다. 그 이유는 PrintWriter라는 하나의 클래스에서 write 메서드를 서로 돌려쓰고 있기 때문입니다. 하지만 new를 통해 PrintWriter 인스턴스를 만들었고, 이 인스턴스는 내부적으로 각자의 상태를 가지고 있습니다. 여기서 상태란 p1 변수는 result.txt 파일을, p2 변수는 result2.txt 파일을 가리킨다는 내부적인 정보를 의미하며, 이 때문에 p1 인스턴스 변수를 대상으로 writee 메서드를 사용하면 자동으로 result1.txt 파일에 기록하고, 마찬가지로 p2 인스턴스 변수를 대상으로 write 메서드를 사용하면 result2.txt 파일에 기록하게 되는 것입니다. Math 클래스는 일회성에 그치는 작업, 예를 들어 원주율이 필요하다거나 올림이나 내림과 같은 아주 짧은 맥락의 작업에 쓰입니다. 그런데 어떤 파일을 수정한다는 것은 파일 하나만 수정하는 것이 아니라 해당 파일에 대한 여러 가지 후속 작업이 이어지거나 동시에 여러 파일을 대상으로 작업이 이뤄질 수도 있습니다. 따라서 하나의 클래스를 사용하기보다는 클래스 앞에 new를 붙여서 복제한 후 각기 다른 상태를 가지고 있는 인스턴스를 만들어서 각 인스턴스를 사용하는 편이 더 효율적입니다. 그래서 클래스를 만드는 사람들은 만들고자 하는 클래스가 인스턴스를 만들 필요 없이 일회성으로 쓸 수 있다면 Math처럼 동작하는 클래스를 만들면 됩니다. 그런데 클래스가 수행하는 작업이 일회성이 아니라 긴 맥락의 작업들이 꼬리에 꼬리를 물면서 이어져야 한다면 사용자가 클래스를 복제한 인스턴스를 만들어서 해당 인스턴스를 사용할 수 있게 하는 편이 효율적입니다. 그럼 Math 클래스와 PrintWriter 클래스는 어떤 차이가 있는지 매뉴얼을 통해 확인해 보겠습니다.
API 문서를 보면 PrintWriter 클래스에는 Constructors라고 하는 항목이 있습니다. Constructor는 생성자라고 하는 것입니다. 반면에 Math는 Constructor가 없습니다. 일단은 생성자가 없는 클래스는 일회성으로 사용되는 클래스라고 생각하면 됩니다. PrintWriter 클래스의 경우 생성자가 있습니다. Constructors가 있다는 것은 constructor를 이용해서 인스턴스를 만드는 것이 허용된다고 생각하면 됩니다.
희가 사용한 생성자는 위의 것인데요. 자세히 알아보기 위해서는 클릭하면 됩니다.
크게 나뉘는 것들이 있는데요. 우선 설명을 해주는 부분이 제일 위에 있고요. 이 Constructor에 입력값으로 들어오는 값이 어떤 것이어야 하는지 설명하는 부분이 Parameter부분입니다. Throws부분은 오류에 대한 내용으로 FileNotFoundException은 파일을 찾을 수 없는 경우가 발생할 수 있다는 것을 우리에게 알려주고 있는 것입니다. 정리해 보겠습니다. 어떤 클래스를 사용할 때 그 클래스를 만든 사람이 클래스를 인스턴스로써 활용하기를 원한다면 클래스에 생성자가 있을 것이고, 이 경우 생성자 앞에 new를 붙이면 됩니다. 그럼 클래스가 복제되어 인스턴스가 되고, 인스턴스에 어떤 값이 올 수 있느냐를 규제하기 위해 앞에다가 PrintWriter라고 하는 클래스 이름을 적습니다.
인스턴스를 이해하는 것은 처음 자바에 입문하는 분들에게는 너무너무 어려운 일이고 저는 인스턴스를 이해하기까지 1년 걸렸습니다. 그러니까 너무 이해하려고 노력하지 말고 눈치껏 하시면 됩니다. 다른 사람들이 작성한 코드를 보면서 눈치껏 바꿔가면서 프로그래밍하다 보면 어느 순간 이해도 하기 전에 익숙해져서 사용할 수 있게 될 것입니다.
Self Question
1. 인스턴스를 만드는 방법은?
2. 인스턴스를 사용하는 이유는?
자바 문서 보는 법 - 상속
이번 수업에서는 자바에서 굉장히 중요한 것이라고 할수 있지만 너무 어렵기 때문에 이해하지 못해도 전혀 심란할 필요도 없는, 하지만 도전해볼 만한 주제인 ‘상속 inheritance’이라는 것에 대해 살펴보겠습니다.
우리가 이전 시간에 보았던 PrintWriter라는 클래스는 java.io.Writer라는 클래스를 부모로 가지고 있고 해당 클래스는 java.lang.Object라는 클래스를 부모로 갖고 있습니다. 이것이 무엇을 의미하는지 한번 알아보겠습니다. 우리가 어떤 기능을 만들 때 처음부터 끝까지 다 만드는 것은 어렵기 때문에 PrintWriter라는 클래스를 만든 사람이 처음부터 끝까지 다 만들지는 않습니다. 이미 있는 Writer라는 클래스가 갖고 있는 변수와 메서드를 그대로 물려받으면서 거기에다가 자기가 원하는 변수와 메서드를 추가한 것이 PrintWriter 클래스가 되는 것입니다. 마찬가지로 Writer 클래스를 만든 사람도 Object라는 클래스를 상속받아서 Writer 클래스에 원하는 변수와 메서드를 추가한 것입니다. 이클립스에서 PrintWriter 클래스가 어떤 상속 관계를 가지고 있는지 살펴보는 방법을 알려드리겠습니다.
해당 클래스에서 마우스 우클릭을 한 후 Open Type Hierachy를 클릭하면 다음과 같은 화면이 나오게 됩니다.
제가 선택한 클래스의 상속 관계를 확인할 수 있습니다.
Object에는 어떤 변수(필드)들과 메소드들이 있고 해당 클래스를 Writer가 상속을 했구나 라는 것을 아주 손쉽게 파악할 수 있습니다. java에서는 변수를 필드라고 합니다. Object 클래스가 가지고 있는 메서드 가운데 toString()이라는 굉장히 중요한 메서드가 있습니다. 이 메서드를 Writer 클래스에서는 구현한 적이 없습니다. 마찬가지로 PrintWriter 클래스에서도 구현한 적이 없습니다. 그럼에도 불구하고 PrintWriter 클래스는 Object 클래스를 상속받고 있기 때문에 toString()이라는 메서드를 사용할 수 있는 것입니다. 이 관계를 그림으로 나타내면 다음과 같습니다. 자바에서 가장 기본적인 클래스는 Object 클래스입니다. 자바의 모든 클래스는 Object 클래스를 반드시 상속받습니다.
만약 누군가가 Writer라고 하는 클래스를 만든다면 Object 클래스를 상속받게 됩니다. 그 때 사용하는 키워드가 바로 extends입니다. 즉, Object를 확장해서 Writer 클래스를 만들었다는 뜻입니다. 마찬가지로 누군가가 PrintWriter라는 클래스를 만드는데, 처음부터 끝까지 만드는 것이 아니라 Writer 클래스를 확장해서(상속받아서) 만든다면 위의 그림과 같은 관계가 형성됩니다.
이 상태에서 PrintWriter 인스턴스를 만들고 인스턴스에 toString을 실행 하게 되면, Java는 다음과 같이 작동하게 됩니다. 우선 실행된 클래스인 PrintWriter에 toString 메서드가 있는지 확인하고 없다면 extends에 해당하는 Writer에 가서 해당 메서드가 있는지 확인합니다. 마찬가지로 또 없다면 Writer의 extends인 Object에 가서 해당 메서드를 찾고 찾게 된다면 그 메서드를 실행시키게 됩니다.
이번에는 조금 다른 측면을 살펴보겠습니다. Writer 클래스에는 Write 메서드들이 있고 입력값으로 문자열을 받는 메서드가 있습니다. 그런데 PrintWriter 클래스에서도 Write 메서드 중에 입력값이 문자열인 메서드가 있습니다. 즉, Writer와 Writer를 상속받는 PrintWriter에 동일한 형식의 write 메서드가 있는 상태입니다. 다시 말해, write라는 메서드를 덮어쓰기 한 것입니다. 그런 상황에서 p2.write(”hello 2”);를 실행하게 된다면 여기서 write 메서드는 PrintWriter 클래스의 write 메서드를 사용하는 것입니다.
이 관계를 그림으로 나타내보면 위와 같습니다. Writer 클래스에는 write라는 메서드가 있었습니다. 그런데, Wirter 클래스를 상속 받는 PrintWriter 클래스를 만든 사람이 기존의 write 메서드가 맘에 안드는 점이 있는 겁니다. 이럴 경우 그것을 덮어 쓰는 메서드를 똑같이 PrintWriter 클래스의 write 메서드로 만들게 됩니다. 이때 p1 인스턴스의 변수는 자신이 속한 클래스의 wirte 메서드를 사용하게 됩니다. PrintWriter 클래스의 write 메서드가 Writer 클래스의 write 메서드를 덮어쓰는 것을 오버라이드(override)라고 합니다.
이처럼 다른 사람이 만든 클래스, 메서드, 변수가 상속 관계에 있을 때 그것의 관계를 메뉴얼 상에서 어떻게 해석하는지를 파악하는 것이 중요합니다. 자바의 공식 사용 설명서를 보면 상단에 트리(Tree)라는 메뉴가 있습니다. 트리는 상속 관계를 나무 모양으로 보여주는 역할을 합니다. 위의 그림처럼 나오는데요. 이 자바가 기본적으로 제공하는 표준 라이브러리의 클래스들이 서로 관의 어떤 상속 관계를 맺고 있는지 보여줍니다. 그리고 이 상속 관계의 제일 위에 Object가 있습니다. Object에 있는 메소드들은 java의 모든 클래스에서 사용 가능한 메소드이기 때문에 여러분들이 나중에 시간이 있을 때 Object에 있는 메소드들의 쓰임은 알아보시는 것이 좋습니다.
이제 PrintWriter 클래스로 돌아가면 이제 많은 것들이 이해가 될 겁니다. Writer 클래스로 가볼까요? Writer 클래스의 문서에서 Direct Known Subclasses 항목의 의미는 Writer 클래스를 직접 상속받는 자식들 가운데 알려진 것들로는 이런 것들이 있다는 뜻입니다. 왜 ‘알려져 있는 것’이라는 표현을 썼을까요? 정확한 답변은 아닐 수 있지만 여러분도 Writer 클래스를 상속받아서 여러분만의 클래스를 만들 수 있기 때문입니다. 그런 것들은 Writer 클래스의 공식 설명서에는 나타나지 않기 때문에 Known이라는 표현을 쓰는 것이 아닐까라고 추측해 봅니다.
다시 PrintWriter로 돌아가봅시다. Field Summary 항목이 있는 것을 볼 수 있습니다. 여기서는 lock이라는 변수, 다른 말로 필드(field)가 Writer 클래스에 정의되어 있고 그것을 상속받아서 PrintWriter에서도 lock이라는 필드를 사용할 수 있음을 알 수 있습니다. 지금까지 자바 API 문서를 보는 법과 API 문서를 보기 위해 필수적으로 알고 있어야 할, 자바의 구조를 담당하는 패키지, 클래스, 인스턴스, 상속에 대해 살펴봤습니다. 우리가 이러한 것들을 만들지는 못해도 사용할 줄은 알아야 합니다. 스마트폰을 만들지는 못해도 일단 사용할 줄 알면 되는 것처럼요. 이번 수업은 여기까지 하겠습니다.
👏 상속 inheritance란?
상속 Inheritance
우리가 어떤 기능을 만들 때 처음부터 끝까지 다 만드는 것은 매우 어렵습니다. 우리가 이전 시간에서 배웠던 API를 떠올려보아도 그렇다는 것을 단번에 이해할 수 있는데요. 프로그램을 만든다는 것은 자바의 문법을 따라 시간의 순서대로 자바가 기본적으로 제공하는 라이브러리를 작동하게 만드는 것입니다. 그런 관점에서 API Application Programming Interface는 자바가 기본적으로 제공하는 도구들을 사용하는 방법을 의미합니다. 이처럼 프로그램을 만든다는 것 자체가 누군가가 만든 라이브러리를 이용하는 것이고, 상속은 새로운 클래스를 만들 때 모든 메서드를 직접 만들 필요는 없기 때문에 다른 클래스가 갖고 있는 변수와 메서드를 그대로 물려 받으면서 자신이 필요한 변수와 메서드를 추가하는 것이라고 할 수 있습니다.
참고자료 및 원본 : 오픈튜토리얼스 생활코딩 (이고잉 님)
- 생활코딩 JAVA 입문 수업 : https://opentutorials.org/course/3930
'[생활코딩] Server > JAVA1(기초)' 카테고리의 다른 글
생활코딩 JAVA 1_지식이란, 지식의 지도 (0) | 2023.05.01 |
---|---|
생활코딩 JAVA 1_직접 컴파일하고 실행하기 {실행 환경 살펴보기, 컴파일과 실행하기, 라이브러리 이용, 입력과 출력} (0) | 2023.04.29 |
생활코딩 JAVA 1_입력과 출력 (arguments & parameter) (0) | 2023.04.28 |
생활코딩 JAVA 1_디버거 (1) | 2023.04.28 |
생활코딩 JAVA 1_IoT 프로그램 만들기 (0) | 2023.04.28 |