클래스와 배열
클래스와 객체(Object)를 구별하고 객체지향 프로그래밍의 특징을 익힌다.
String 또는 StringBuffer와 같은 기본 클래스들을 알아본다
자바에서 애기하는 배열이란? 그리고 필요성과 활용을 익힌다.
jdk 5.0에서 제공하는 배열을 이용한 Enhanced for Loop(개선된 루프)를 익힌다.
jdk 5.0에서 제공하는 Autoboxing/Unboxing의 유익함을 알아본다.
jdk 5.0에서 제공하는 Varargs(Variable arguments) 기능과 구현을 익힌다.
[클래스와 객체의 개념1]
글래스란?
한 마디로 건물을 지울 때 제일 먼저 필요로 하는 설계도면과 같다. 현관위 위치와 복도의 크기 등의 속성들을 정확하게 Design된 설계도면을 가지고 건물을 짓게 된다. 완성된 건물을 자바에서는 곧 객체(Object)라 한다. 이렇게 건물이 지어지면 그 건물의 위치를 가리키는 주소(reference)가 있게 마련이고 그 주소를 통해 건물로 세금통지서 또는 각종 배달 서비스 즉, 연락(요청)을 위할 수 있다.
[클래스와 객체의 개념2]
클래스의 구조와 정의
자바 프로그램은 클래스들이 모여서 이루어진다고 생각해도 무리는 아니다. 그래서 자바를 두고 "완전한 객체 지향적 언어"라는 호평이 생긴 것이다. 이런 클래스들을 많이 이해하고 생성하여 얻어지는 객체(Object)를 사용하는 것이 자바이므로 객체(Object)를 생성하기 위해서는 먼저 클래스의 구조를 알고 작성 할 수 있어야 한다.

[클래스와 객체의 개념2]
클래스 헤더
클래스 헤더는 클래스를 선언하는 부분을 의미한다. 여기에는 class라는 예약어를 중심으로 오른쪽은 클래스 명이며 왼쪽은 접근 제한(Access Control/Access Modifier)과 크래스의 형태 및 클래스 종류를 나타내기도 한다.
[접근제한] [클래스 종류] class 클래스명
● 접근제한: 뒤에서 자세히 공부하게 되지만 그래도 의미 정도는 알아보자. 접근제한은 말 그대로 현재 클래스를 접근하여 생성하고 사용하는데 있어 제한을 두겠다는 의미에서 정의하는 것이다. 클래스에서 쓰이는 접근제한은 public을 정의하는 방법과 아예 정의하지 않는 방법 두가지가 있다.
● 클래스의 종류: 이는 최종(final)클래스 또는 추상(abstract)클래스와 같은 클래스종류를 의미하며 현재 클래스가 어떤 클래스인지를 알리는 수기어의 일정이다. 이 부분이 생략되게 되면 일반 클래스임을 의미 하게 된다.
● 클래스명: 클래스의 이름을 의미하며 여기에는 몇 가지 약속이 있다 했다. 이는 제3장 자바 기본문법의 식별자에서 이미 공부한 바가 있으니 기억이 나지 않으면 지금 바로 참조하기 바란다.
01 class Ex1{
02
03 }
[클래스와 객체의 개념3]
멤버 필드
● 변수와 상수(속성) 즉, 테이터라고도 하는데 이것은 객체가 만들어질 때에 그 객체의 특징적인 속성을 담아두는 것이다. 여기서 필드이 형태가 static이냐 instance냐?에 따라 필드개념이 달라진다. 이는 멤버변수 부분과 현재 절의 static부분에서 다루도록 하겠다.
● [상수] 상수라는 것은 고정된 값을 의미하며 프로그램이 종료 될 때까지 절대로 변하지 않는 값(속성)인 것이다. 제5장의 final부분에서 자세히 다로고 있다.
● [변수] - 멤버변수(전역변수) : 변수는 상수와는 반대로 프로그램이 종료 될 동안 값이 변경될 수 있는 값(속성)을 의미한다.
01 class Ex1{
02 int data;
03 }
● 멤버 메서드(메서드는 함수다)
메서드는 특정한 일을 수행하는 행위, 다시 말해 동작을 의미하는 것이다.
멤버필드 들의 값을 가지고 작업을 수행할 수도 있으며 메서드도 static메서드(클래스 메서드)와 instance메서드 라는 2종류가 있다. 간단히 설명하자면 static메서드(클래스 메서드)는 메서드를 가지는 객체를 생성하지 않아도 사용할 수 있지만 instance메서드는 객체를 생성해야만 사용이 가능한 것이다. 현재 절의 마지막 부분인 static을 공부할 때 자세히 알아보도록 하고 여기서는 클래스의 구조를 알아보는 것이 목적이므로 클래스의 구조에 중심을 맞춰 공부하도록 하자
01 class Ex1{
02 int data;
03 public void setData(int n){
04 data = n;
05 }
06 }
void 는 리턴값이 없다. Return 값이 없고 System.out.print로 출력
[클래스와 객체의 개념4]
● 클래스 정의
우리가 애기하는 클래스란? 초등학생들이 어떤 사물을 인식하고 그것을 그림으로 표현하는 것처럼 프로그램머들은 그 사물을 자바라는 프로그램언어에 도입하여 추상적으로 사물의 속성과 움직임을 표현한 것이다. 그럼 다음 [조건]을 보고 우리가 일상 생활에 있는 사물 중 MP3 Player를 클래스로 간단히 정의해 보도록 하자!
[조건] 우선 클래스명은 MP3p 정하고 속성부분은 색상을 기억하는 COLOR와 메모리용량을 기억하는 memory로 정하자! 동작부분에서는 memory용량을 upgrade해 주는 memoryUp이라는 동작과 color를 설정하는 setColor라는 동작을 정의해 보자!

01 class MP3p{
02 String color;
03 int memory;
04 public void memoryUp(int n){
05 memory += n;
06 }
07 public void setColor(String c){
08 color = c;
09 }
10 }
※ 저장 시에는 반드시 클래스 명과 동일!
MP3p.java
[클래스와 객체의 개념5]
● 간단히 알아보는 메모리 구조
앞서 제1장을 참조해보면 메모리 영역은 여러 가지로 나눌 수 있다. static영역은 뒤에서 공부하므로 여기서는 stack과 heap에 관해서만 애기하도록 하자.
● stack은 offset 값만으로 바로 참조할 수 있는 변수와 같이 가벼운 저장하고 곳이며 heap은 사실 내부에 참조영역(registry)을 따로 가지므로 객체와 같은 무거운 것들을 저장하는 공간이라 할 수 있다.

[클래스와 객체의 개념6]
● 객제 생성과 멤버 접근법
정수형 또는 실수형 그리고 문자형등과 같은 자료형을 '기본 자료형'이라 하며 자바 내부에서 제공되는 클래스 또는 MP3p 클래스처럼 프로그램머에 의해 만들어진 사용자 정의 클래스등을 자료형으로 하는 '차조(객체) 자료형' 이 있다는 것을 제3장에서 이미 공부한 적이 있다. 이런 참조 자료형을 가지는 변수(reference) 다시 말햇서 객체를 생성하고 사용하는 법을 알아 보도록 하자.
1)객체 생성: m3 = new MP3p();

● new라는 연산자를 통해 무조건 메모리상에 공간을 할당 받고 MP3p클래스의 생성자로 인하여 객체를 생성한 후 생성된 객체를 참조할 수 있는 reference를 m3에 담아 준다.(이것이 객체를 구분할 수 있는 주소개념이다) 결국 m3를 통해 MP3p객체에게 서비스 요청을 하게 되는 것이다.
● 생성자에 관해서는 뒤에서 따로 공부하는 부분이 있으니 여기서는 객체를 생성할 때는 생성자라는 것에 의해 만들어진는 것이다. 라는 것만 알고 가자!
● 접근 제한자
멤버들은 객체 자신들만의 속성이자 특징이므로 대외적으로 공개되는 것이 결코 좋은 것은 아리다. 그런 이유로 프로그래머가 객체의 멤버들에게 접근 제한을 걸 수가 있는데 자바에서는 이를 접근 제한자라 한다.

같은 패키지라는 말의 뜻을 간단히 설명 하자면, 같은 폴더에 있는 객체를 의미한다고 생각하면 된다.

● 멤버접근법
▶멤버 전근법에 대해서는 앞서 확인해본 것과 같은 m3와 같은 객체의 참조(reference)를 통해(.)를 사용하여 해당 객체의 메서드나 변수 즉 멤버들을 접근할 수 있다. (.)는 dot연산자라고도 하며 사용법은 [객체참조.멤버명] 형식으로 사용된다.
m3.memoryUp(768);
▶여기서 쓰인 m3가 바로 MP3p클래스가 생성되어 그 객체의 참조(reference)를 가지는 변수이다. 즉 생성된 MP3p객체를 m3가 참조하게 되는 것이고 이것을 통해 인자(Arguments)값으로 768을 전달하며 memoryUp()함수를 호출하여 하나의 멤버변수에 누적 시키는 동작을 하게 되는 것이다.
[클래스와 객체의 개념7]
● 캡슐화
객체에 대한 수정 작업으로 인해 객체 활용도에 문제가 발생한다면 제품 하나에 대한 upgrade가 상당히 부담스러울 것이다. 자바에서는 각 기능을 하나의 모듈(부품)처럼 활용하여 객체간의 이식성이 높고 독립적인 면을 유지하는 장점이 있다.
전기 압력밥솥이 어떤 원리와 어떤 과정으로 밥을 지어내는지는 알 필요 없이 그냥 사용법만 익혀서 사용한다. 고장이 나서 A/S를 받을 때마다 사용법이 바뀐다면 좋은 회사 또는 좋은 제품(객체)이라 할 수 없다.사용법이 바뀌지 않는 이유는 모든 기능이 모듈화 되어 있기 때문이다.
캡슐화란? 관련이 있는 데이터 그리고 동작들을 하나로 묶어 요약하고 사용자에게는 내부적인 접근을 허용하지 않는 대신에 사용의 편의성을 제공해 주는 것이다.
● 멤버변수
▶instance변수 (개인이 소유하고 있는 물컵)
객체가 생성될 때 각 객체들마다 따로 따로 생성되어 고유의 값을 받아 각 객체의 속성으로 자리 잡는 변수가 바로 instance변수 이다
1 class MP3p{
2 String color;
3 int memory;
▶static변수(약수터에 있는 물 바가지)
여러 개의 객체가 생성될 때 단 하나만 생성되며 모든 객체들이 공유하는 개념으로 사용되는 변수가 static변수이다.
1 class MP3p{
2 String color;
3 int memory;
4 static String maker;
● 메서드
메서드(멤버함수)란? 객체가 할 수 있는 동작을 정의하는 것이며 메서드 또한 instance메서드와 static메서드로 나눠어 진다. 의미는 앞의 내용과 같다.
메서드의 구성
[접근제한] [변환형] [메서드명] (자료형 인자1, 자료형 인자2,...){
수행문1;
수행문2;
}
▶접근제한: 자바에서 객체나 멤버들에 대한 접근을 제한하는 방법을 의미한다. 여기에는 public, protected, default, private의 종류로 나눌 수 있다.
▶변환형: 메서드(멤버함수)에서 해야 할 일들을 모두 끝내고 마지막으로 메서드(멤버함수) 자신을 불러준 곳으로 반환하는 값의 자료형을 의미한는 것이다. 만약 반환 값이 없다면 void라는 예약어로 대처해야 한다. 즉 생략은 불가능하다는 뜻이다.
▶메서드명: 사용자 정의 이름(User defined name)이며 제3장의 식별자에 대한 규칙을 참조하기 바란다.
▶인자: Arguments라고도 하며 이것은 메서드(멤버함수)를 호출할 때 필요에 따라 특정 값을 제공해주기 위해 미리 선언하는 것이며 메서드(멤버함수)를 호출할 시에 반드시 인자의 자료형과 수가 일치해야 한다.
▶수행문: 식 수행 및 제어문 또는 실행문 등을 의미한다.
01 class MethodEx {
02
03 int var1,var2; // 멤버 변수들
04
05 public int sum(int a, int b){ // 메서드(멤버 함수)
06 return a+b;
07 }
08 public static void main(String[] args){
09 MethodEx me = new MethodEx();
10 int res = me.sum(1000, -10);
11 System.out.println("res="+res);
12 }
13 }
예제: MethodEx.java
실행결과
-----------java run-------------
res = 990
Normal Termination
출력완료(0초 경과)

01 class MethodEx2{
02
03 int var;
04
05 public void setInt(int var){
06 var = var;
07 }
08
09 public int getInt(){
10 return var;
11 }
12
13 public static void main(String[] args){
14 MethodEx2 me2 = new MethodEx2();
15 me2.setInt(1000);
16 System.out.println("var : "+ me2.getInt());
17 }
18 }
예제: MethodEx2.java
실행결과
var : 0
[클래스와 객체의 개념8]
1000이 출력되지 않는 이유가 무엇일까? 문제는 setlnt(int var)라는 메서드(멤버함수)에 있으며 자바에서는 특정 영역의 우선권은 멤버변수가 아닌 지역변수가 가지게 되어 있다.

● 인자 전달 방식
▶값 호출(Call by value): 이는 앞선 예제 MothodEc2.java와 같이 메서드를 호출 시기본자료형의 값을 인자로 전달하는 방식을 의미한다.
▶참조호출(Call by reference): 메서드 호출 시 전달하려는 인자를 참조(객체) 자료형을 사용 할 경우를 의미한다. 여기에는 기본 자료형이 아닌 일반 객체 또는 배열들이 여기에 속한다.
▶Varargs(Variable Arguments) : jdk5.0에서 새롭게 추가된 기능이며 이는 메서드 정의 시 통일된 인자의 자료형에 '...'하고 명시하므로 이를 통해 메서드를 수행하는데 필요한 인자의 수를 유연하게 구현 할 수 있다.
(내부적으로 배열화 작업을 자동적으로 해 주기 때문!)
01 class ValueParameter{
02
03 public int increase(int n){
04 ++n;
05 return n;
06 }
07 public static void main(String[] args){
08 int var1 = 100;
09 ValueParameter vp = new ValueParameter();
10 int var2 = vp.increase(var1);
11 System.out.println("var1 : "+ var1 + ", var2 : " + var2);
12 }
13 }
값 호출 (Call by value)에 대한 예제: ValueParamenter.java
실행결과:
var1 : 100, var2 : 101
결과 내용을 보게 되면 인자로 전달된 int var1(실인자)의 값은 변함이 없음을 알 수 있다. 그러므로 int var1(실인자)의 값이 다음 그림과 같이 복사본이라고 할 수 있는 int n(형식인자)에 대입되고 그것을 증가 시키면 int var1(실인자)는 영향을 전혀 받지 않게 된다. 즉 int n(형식인자)만 증가하게 되는 것이다.
01 class ReferenceParameter{
02
03 public void increase(int[] n){
04 for(int i = 0 ; i < n.length ; i++)
05 n[i]++;
06 }
07 public static void main(String[] args){
08 int[] ref1 = {100,800,1000};
09 ReferenceParameter rp = new ReferenceParameter();
10 rp.increase(ref1);
11
12 for(int i = 0 ; i < ref1.length ; i++)
13 System.out.println("ref1["+i+"] : "+ ref1[i]);
14 }
15 }
참조 호출 (Call by reference)에 대한 예제: ReferenceParameter.java
실행결과:
ref[0] : 101
ref[1] : 801
ref[2] : 1001
Varargs를 제외하고 자바에서 얘기하는 인자 전달방식에 있어서는 모두가 전달하는 인자가 복사되어 전달된다. (Call by value)에서는 값을 복사하여 전달하였으므로 호출 시의 실인자는 별도의 값으로 인식되어 영향을 받지 않으며 (Call by reference)에서는 reference(주소)가 복사되어 전달 되었으므로 하나의 객체를 참조하는 변수가 2개가 되어 어느 한 곳에서 수정을 하게 되면 같은 객체를 참조하는 다른 쪽에서도 영향을 받게 된다.
01 class VarTest{
02
03 public void argTest(String ... n){
04 for(int i = 0 ; i < n.length ; i++)
05 System.out.println("n["+i+"]:"+n[i]);
06 System.out.println("--------------------------");
07 }
08 public static void main(String[] args){
09 VarTest vt = new VarTest();
10 vt.argTest("Varargs", "Test");
11
12 vt.argTest("100", "600", "900", "1000");
13 }
14 }
Varargs (Variable Arguments)에 대한 예제: VarTest.java
실행결과:
n[0]; Varargs
n[1]: Test
-------------------------
n[0]: 100
n[1]: 600
n[2]: 900
n[3]: 1000
-------------------------
Varargs의 장점은 앞으로 배우게 되는 '메서드 오버로딩' 과 연관이 있겠지만 이에 대한 설명은 간단히 해보자!
JDK5.0 이전의 버전에서는 특정 메서드를 정의할 때 인자(argument)의 타입과 수를 정해 두고 호출 시 전달되는 인자(argument)의 수가 일치하지 않을 경우에는 메서드를 호출할 수가 없었다. 이런 문제로 인해 많은 개발자들이 메서드의 이름은 같지만 인자의 수가 다른 여러 개의 메서드를 정의하는 메서드 Overloading법 또는 메서드 정의 시에 배열객체를 인자로 지정하므로 이 문제를 해결 하였지만 매번 호출 시의 배열화 작업이 매우 불편하다.
이런 부분의 앞의 예저 [VarTest.java]의 Varargs기능응로 해소되었다. 앞으로 Generics, 개선된 루프등과 같이 jdk5.0에서 새롭게 변화된 점들을 배워가면서 지금의 Variable Arguments부분을 같이 병행하게 되면 보다 심플한 내용을 보게 될 것이다.
자바프로래밍 언어: 클래스와 배열 [2]에서 계속
'처음배우는 IT' 카테고리의 다른 글
자바프로그래밍 언어: 클래스와 배열 [3] (0) | 2020.12.28 |
---|---|
자바프로그래밍 언어: 클래스와 배열 [2] (0) | 2020.12.27 |
자바프로그래밍 언어: 주석문과 제어문 (0) | 2020.12.23 |
자바 프로그래밍 기초: 자바 기본 문법 (0) | 2020.12.21 |
자바프로그래밍 언어: 자바의 탄생 (1) | 2020.12.20 |