본문 바로가기

국비필기노트/Java

자바(java)_클래스,객체,메서드,전역변수,지역변수

▶객체란?

 

-. 프로그래밍에서의 객체는 프로그램에서 표현하고자 하는 기능을 묶기 위한 단위이다. 

 

▶객체를 구성하는 단위

 

-. 객체를 이루는 것은 데이터와 기능이다.

        어떠한 전산처리를 한다는 것은 데이터를 어떻게 조작할지에 대한 컨트롤이다. 좀 더 직관적으로 표현하자면 연말정산시, 홈택스에 들어가서 고유의 아이디(데이터)로 접속을 하고 2021년에 대한 연말전산을 하게되는데, 이런 정확한 데이터를 홈페이지에 입력하고 내용을 처리(기능)하는 일련의 과정들이 하나의 데이터와 기능이다.

-. 데이터는 변수로 표현된다.

-. 기능은 함수(=메서드)로 표현된다.

-. 객제안에 포함된 변수를 '멤버변수' 혹은 '프로퍼티'라고 한다.

 

▶클래스,객체,메서드의 관계

 

-. 객체는 기본적인 설계하에 만들어진 구성단위로서 객체를 생성하기 위해서 객체의 설계도가 필요한데 설계도 역할을 하는 프로그램 소스가 Class이다. 

-. 자동차를 예시로 들고오면, 자동차는 반드시 바퀴, 문, 창문, 거울이 있다. 즉, 자동차라는 설계도(Class)로 바퀴,문,창문,거울을 구현시키고 최종적으로 버스, 트럭, 승용차를 만든다. 여기서 나오는 승용차,버스,트럭이 프로그래밍에서는 객체로 표현된다. 게다가 각각의 자동차에는 1종 2종처럼 기능이 모두 다르게 구현되는데 이 때 기능을 각기별로 다르게 구현 시키는 역할을 하는게 메서드이다.

 

클래스 객체 메서드
-. 객체를 정의해 놓은 것 
-. 속성(멤버변수)와 기능(메서드)이 정의됨
-. 클래스에 정의된 내용대로 메모리에 생성된 것
-. 여러개 생성 가능
-. 멤버변수
-. 객체의 기능을 구현시킴
ex. 자동차 설계도 ex. 바퀴,문,창문,거울 ex. 전진,후진

 

-. 공장에서 하나의 설계도를 사용하여 여러개의 제품을 생산할 수 있는 것처럼 하나의 클래스를 통해 동일한 구조를 갖는 객체를 여러개 생성할 수 있다.

-. 자동차 바퀴, 문, 창문 등은 멤버변수로 존재할 수 있다.

-. 전진, 후진 등의 기능은 메서드 형태로 표현된다.

-. 동일한 설계로 만들어진 자동차라 하더라도 각각의 자동차를 구성하는 부품들은 그 형태만 같을 뿐, 실제로는 각각 다른 존재(객체,메서드등이 다르기 때문에)이게 된다.

-. 클래스를 작성하면서 그 안에 생성되는 멤버변수들은 여러 개의 객체간에 서로 동일한 이름으로 존재하지만 실제로는 전혀 다른 값이라는 의미이다. 

 

 

▶클래스의 기본 작성 방법

 

-. Class 클래스 이름{

             멤버변수;

             멤버변수;      // 바퀴,문,창문

                ...

  

              void 메서드이름(){     //엔진 기능

 

                }

     }       // 자동차 설계도 

 

-. Class라는 예약어와 클래스의 이름을 명시한 후 {}안의 구현부 블록을 구성한다.

-. 멤버변수는 여러개 존재할 수 있다. 이 때, 값을 선언과 동시에 할당할 수도 있고, 객체를 통해 간접적으로 할당할 수 도 있다.

-. 메서드도 여러개 존재할 수 있다.

-. 클래스 안에 포함된 멤버변수와 메서드를 특성에 따라 그룹화 하기 위한 기법이 클래스를 작성하는 것이라고 이해할 수 있다. 

 

▶객체 기본 작성 방법

 

-. 객체의 선언

    클래스 이름 객체이름; 

-. 객체의 할당

    객체이름 = new 클래스이름();

-. 선언과 할당의 통합

    클래스이름 객체이름 = new 클래스이름();

 

▶객체의 사용

 

-. 객체 안에 포함된 변수나 메서드는 점(.)으로 연결하여 접근한다.

         ▷ 객체 안에 포함된 변수의 값을 다른 변수에 복사하는 경우

                      변수 = 객체이름.멤버변수;

         ▷ 객체 안에 포함된 변수의 값에 다른 값을 대입하는 경우

                      객체이름.멤버변수 = 값;

         ▷ 객체 안에 포함된 메서드를 호출하는 경우

                      객체이름.메서드이름();

         ▷ 객체 안에 포함된 메서드에 파라미터를 전달하는 경우

                      객체이름.메서드이름(값1,값2, ..., 값n);

 

▶클래스를 정의하면서 멤버변수에 값을 직접 대입하는 경우

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Student{
    // 이름, 나이
    String name = "자바학생";
    int age = 10;
 
}
 
 
public class Main01{
 
    public static void main(String[] args) {
        //객체의 선언과 할당의 분리
        Student std;
        std = new Student();
 
        //객체의 생성(일괄지정)
        Student std2 = new Student();
 
        System.out.println("std 이름: " + std.name);
        System.out.println("std 나이: " + std.age);
 
        System.out.println("std2 이름: " + std2.name);
        System.out.println("std2 나이: " + std2.age);
 
        
    a)    std2.name = "JYP학생";
        
        System.out.println("std2 이름: " + std2.name);
        System.out.println("std2 나이: " + std2.age);
 
    }
    }
 
 
cs

 

예를들어 설계도에서 처음부터 학생과 나이에 "자바학생"과 10이라는 값을 저장을 한 것이다. 나이와 이름이 있다 뿐만 아니라 이름과 나이의 값을 강제적으로 정해놓은 것이다. 즉,객체를 생성함과 동시에 객체 안에 name변수와 age변수가 할당된 값을 포함하게 된다.

 

"자바학생"과 10은 기본값이라고 볼 수 있다.

 

그렇기에 같은 클래스로 객체를 여러개 생성할 경우, 기본적으로 Student에는 이름과 나이로는 모든 객체가 동일한 값을 갖게된다. 그런데 클래스를 만들다보면 이 값을 변경할 상황이 분명히 생길 것이다. 

 

이때 main에서 객체 안에 포함된 변수의 값에 다른 값을 대입하는 경우 객체이름.멤버변수 = 값; 을 사용하여 값을 넣어준다. 그러면 클래스를 통하여 생성된 객체라 할지라도 서로 다른 값을 대입하면 서로 독립적인 형태로 존재하게된다는 것을 우린 알 수 있다.

 

 

또 자세히 살펴보면 std2의 이름을 변경했을 때 std1의 이름은 변경되지않았다. 이는 각각의 학생들을 관리하기 위한 개별적인 객체를 만든거지 std1과는 아무런 상관이 없다는 것이다.  

 

쉽게 풀어보자면 이는 Student라는 Class 만들어 두고 name과 age값을 기본값으로 설정을 했는데 학생들의 이름이 모두 동일하니 헷갈려 이름을 바꾸고싶다. 객체에 다른 값을 개별로 주고싶다. 할 때 사용되는 방법이 이 방법이다.

 

단, 이 방법은 간단하게 기본값을 설정할 때 주로 쓰이는 방법이고 잘 권고되지는 않는다.  

바로 밑에서 그 이유와 다른 방법으로 값을 대입하는 법을 좀 더 살펴보자.

 

 

▶값이 대입되지 않은 멤버변수를 갖는 클래스

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Main02 {
 
    class Character{
 
        //일반적으로 멤버변수는 선언만 한다.
        String name;
        int age;
 
    }
    public static void main(String[] args) {
        
        //하나의 클래스가 정의되면, 그 클래스의 구조를 기반으로 하는 객체를 여러개 생성할 수 있다.
 
        Character d = new Character();
        d.name = "둘리";
        d.age = 20;
 
        Character h = new Character();
        h.name = "희동";
        h.age = 3;
 
        System.out.println("이름: " + d.name + ", 나이: " + d.age);
        System.out.println("이름: " + h.name + ", 나이: " + h.age);
 
    }
}
 
 
cs

 

클래스란 객체를 위한 틀을 제공하는 것이기 때문에 클래스 작성과정에서 멤버변수에 대입된 값은, 객체를 통하여 멤버변수의 값을 지정하기 전까지 사용될 "기본값"으로서의 의미이다. 

 

객체를 통하여 새로운 값이 대입되면 클래스 작성시에 멤버변수에 대입한 값은 의미를 잃어버리게 된다. 

 

그래서 일반적으로 클래스 작성시에는 멤버변수에 값을 지정하지 않는다. 즉, 클래스에는 멤버변수를 선언만 하고 값은 main함수에서 객체를 생성하고 main함수에서 값을 넣어 해당 클래스로 보내주는 방법을(객체이름.변수명 = 값)주로 사용한다.

 

▶메서드를 포함하고 있는 클래스와 전역변수

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Main03 {
    class HelloWorld{
        // 전역변수(멤버변수)는 모든 메서드가 공유한다.
        
        String message; 
 
        void sayHello(){
           System.out.println(message);
        }
 
        void setEng(){
            message = "hello Java";
        }
 
        void setKor(){
 
            message = "안녕하세요. 자바";
        }
        }    

    public static void main(String[] args) {
        HelloWorld hello = new HelloWorld();
        
        //메서드 호출
        hello.sayHello(); // 아무런 값이 없으니 null
        hello.setEng(); // Hell.Java 가 된다. 
        hello.sayHello();
        hello.setKor(); // 한글 문자 재할당
       hello.sayHello();
}
    }
 
 
cs

 

메서드란 프로그램에서 하나의 동작 단위(기능)를 의미한다. 

 

main에서 객체안에 포함된 메서드를 호출하고 있기에 객체이름.메서드이름(); 방법을 사용하여 메서드를 main으로 뽑아냈다.

 

▶메서드 만을 포함하는 클래스

 

객체 안에 멤버변수(=데이터)가 포함되지 않고 객체 안에 포함된 메서드를 호출하여 결과를 만들기 위한 목적으로 만들어지는 메서드도 있다. 

그러므로 굳이 여러 개의 객체를 생성할 필요가 없다. 

 

 

-. 계산기능을 갖는 클래스의 예

 

              class Calc{

                                int(int x, int y ){

                                     return x + y;

                                     }

                             }

 

위 예시는 어떤 값을 저장하는 변수가 없고 기능만 있는 메서드이다. 

 

            Calc c1 = new Calc () ;

            int a = c1.sum (100,200);

            syso(a);        //300

          

            Calc c2 = new Calc () ;

            int b =  c2.sum (100,200);

            syso(b);         //500

 

main 함수에서 Calc이라는 클래스에 값을 보내는 예시이며, 값을 구해야하는 상황이 2번이 생겨 객체를 2개 생성하여 하나의 Calc이라는 클래스를 필요한 횟수만큼 재사용 하는 경우이다. 

 

근데 현재 어떠한 데이터를 저장하지 않는데(멤버변수가 없는데) class를 두개 생성하여 사용하는 것은 비효율적이다. 밑에는 객체를 재사용한 올바른 방법의 예시이다. 

 

  Calc c1 = new Calc () ;

            int a = c1.sum (100,200);

            syso(a);       

            int b = c1.sum( 200,300); 

 

우리는 자체적으로 데이터를 갖는 형태가 아니라 외부적인 요인인 파라미터에 의해서 결과가 생성되므로, 객체 역시 하나의 객체를 재사용하는 것이 바람직함을 기억한다.

 

 

 

▶지역변수와 전역변수

 

두 개 이상의 메서드가 서로 동일한 대상을 위해서 존재할 경우, 이 메서드들을 클래스에 포함시켜 그룹화 할 수 있는데 클래스에 멤버변수와 메서드가 공존할 경우, 멤버변수는 모든 메서드가 공유하는 전역변수로 존재하게 된다.

 

*변수의 종류

멤버변수(전역변수) 지역변수
클래스 안에서 선언된 변수로서, 클래스 블록 범위 안에서만 유효하다.  메서드 안에서 선언된 변수로서, 메서드의 블록을 빠져나가지 못한다. 그러므로, 다른 메서드는 해당 변수를 인식하지 못한다.
이 규칙은 조건, 반복문과 같은 블록 { } 을 형성하는 모든 경우에 
해당된다.

 

예시를 봐보자 

 

 

 

-. num은 전역변수고 num2는 지역변수이다. 

-. num1은  클래스 전역적으로 사용이 되고 num2는 메서드안에서만 사용이 가능하다.

-. 전역변수(멤버변수)는 Heap영역에 저장이 되고 지역변수는 Stack영역에 저장이 된다.

    ▷Heap : 프로그래머가 원하는 방식으로 쓸 수 있는 공간, 긴 생명주기를 가진 데이터들만 저장이 된다. 

    ▷Stack: 아주 잠깐 사용하고 삭제할 데이터의 저장공간. 그래서 지역변수는 자동으로 초기화가

                되지 않는다. 

 

 

▶클래스 예시

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Calc{
        // plus, param int x, int y 
        int plus (int x, int y){
            return x  + y;
        }
 
        // minus, param int x, int y, return
        int minus(int x, int y){
            return x  - y;
        }
 
        // times, param int x, int y, return
        int times(int x, int y){
            return x  * y;
        }
        // divide, param int x, int y, return
        int divide(int x, int y){
            int result = 0;
 
            if(y != 0){
            result = x  / y;
            }
            return result;
        }
    }
 
 
    
    public static void main(String[] args) {
        //객체생성
        Calc c = new Calc();
 
   a)  int p = c.plus(100,50);
    System.out.println("100 + 50 = " + p);  
    b) System.out.println("100 - 50 = " + c.minus(100,50));
        System.out.println("100 * 50 = " + c.times(100,50));
        System.out.println("100 / 50 = " + c.divide(100,50));
    }
 
 
cs

 

클래스안에서 계산기능만을 수행하는 메서드를 각 기능에 따라 입력하였다.

main 메소드 안에서 값을 넣어 출력한다.

 

a) 처럼 p를 변수에 넣어 출력해도 되고 b)처럼 객체명 (.) 메서드명 의 형식으로 메서드에 접근하여 바로 출력도 가능하다.