본문 바로가기
Java/Java 기초문법

[JAVA 기초] 자바 객체지향언어 - 클래스,인스턴스와 객체

by dev수니 2021. 3. 9.
반응형

 

 1  객체지향언어의 특징

 

 

객체지향언어란 여러 가지 문제들을 해결하기 위해 실제 세계를 컴퓨터 속에 구현하고자 하는 노력에서 출발하였다.

객체지향언어는 다음과 같은 특징을 갖는다.

 

1. 코드의 재사용성 : 새로운 코드를 작성할 때 기존의 코드를 이용함으로 코드의 수를 크게 줄일 수 있으며 유지보수하기에도 편리한 특정을 지녔다.

2. 신뢰성 높은 프로그램 : 제어자의 메서드를 사용해서 데이터를 보호한다. 또 코드의 중복을 제거하여 오동작을 방지한다.

3. 코드 관리의 편리함 : 객체지향 프로그래밍은 한 부분만 변경하면 관련된 모든 부분이 변경된다. 따라서 코드의 관리가 편리하다.

 

 

 

 

 

 

 2  클래스(Class), 인스턴스(instance)와 객체(Object)

 

 

객체(Object)를 이해하려면 먼저 클래스(Class)와 인스턴스(instance)를 이해해야 한다.

 

자동차에 예를 들어보자. 자동차를 만들기 위해서는 설계도가 필요하다. 이 설계도에는 자동차의 기능과 속성들이 정의되어 있고 이는 클래스도 마찬가지이다. 클래스가 바로 설계도와 같은 역할을 하는 것이다.

 

또한 이 설계도를 이용하여 실질적으로 만들어낸 자동차가 바로 인스턴스에 해당된다. 설계도에 따라 만들어진 자동차들은 각각의 색상과 기능들을 선택할 수 있듯이 인스턴스 또한 클래스를 바탕으로 만들어진 것이므로 구조적은 틀은 클래스를 기반으로 모두 같은 구조로 형성되어 있지만 세부적인 요소 하나하나를 다르게 만들 수 있는 것이다.

 

이 모든 것이 객체(Object)를 위한 것이다.

 

 

 

 

 

 

 3  클래스의 사용

 

클래스 변수 : 모든 인스턴스가 공통된 값을 공유하는 변수이다. 즉 모든 인스턴스가 똑같은 저장공간을 공유한다. 클래스 변수는 클래스가 처음 메모리에 로딩될 때 생성된다. 따라서 인스턴스 변수와는 달리 인스턴스를 생성하지 않아도 사용한다. 사용방법은 다음과 같이 static을 붙여준다.

class Cars{
    static int wheel;    // class 변수 선언
}

 

인스턴스 변수 : 객체마다 가지는 고유한 변수이다. 인스턴스를 생성할 때 만들어지며 인스턴스마다 고유의 저장 공간을 가지므로 각각의 다른 값을 가질 수 있다. 다량의 인스턴스를 생성할 때 인스턴스마다 특별한 값을 가져야 할 경우 인스턴스 변수로 선언한다. 사용방법은 다음과 같다.

class Cars{
    int wheel;     // 인스턴스 변수 선언
}

 

 

 


 

EX 예제 1.

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
package java_practice;
class Cars{            // 클래스 생성
    public static String color;    // 색상
    public static int maxSpeed;    // 최대속력
    public static int minSpeed;    // 최소속력
    
    public static void avgSpeed(int maxSpeed, int minSpeed) {    // 평균속력출력 메서드
        System.out.println("평균속력 : " + (maxSpeed + minSpeed)/2);
    }
    public static void carColor (String color) {    // 색상출력 메서드
        System.out.println("색상 : " + color);
    }
}
 
public class Class_BasicCars {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        System.out.println("Car1");
        
        Cars.color = "Black";    // Cars의 색상 지정
        Cars.maxSpeed = 400;    // Cars의 최대속력 지정
        Cars.minSpeed = 10;        // Cars의 최소속력 지정
        Cars.carColor(Cars.color);        // Cars의 색상 출력메서드
        Cars.avgSpeed (Cars.maxSpeed, Cars.minSpeed);    // Cars의 평균속력 출력메서드
 
        
        System.out.println("Car2");
        
        Cars.color = "White";    // Cars의 색상 재지정
        Cars.maxSpeed = 500;    // Cars의 최대속력 재지정
        Cars.minSpeed = 20;        // Cars의 최소속력 재지정
        Cars.carColor(Cars.color);        // Cars의 색상 출력메서드
        Cars.avgSpeed (Cars.maxSpeed, Cars.minSpeed);    // Cars의 평균속력 출력메서드
    }
}
cs

static이란 '정적인', '고정의'라는 뜻으로 class소속이다. static은 다른 클래스에서 사용할 때에는 반드시 사용할 변수가 위치한 클래스명.변수명; 또는 사용할 메서드가 위치한 클래스명.메서드명();으로 사용해주어야 한다. 또한 이 값들을 한번 설정하게 될 경우 class내에서 고정적으로 값이 설정되기 때문에 다른 값으로 바꾸고 싶을 경우 값을 재설정 해주어야 하는 불편함이 있다.

 

또한 코드의 재사용이 많고 위의 구조에 코드를 계속해서 추가하고 로직이 커지다 보면 문제가 발생할 가능성 또한 커진다. 따라서 위 코드를 인스턴스화 시켜 사용해 주어야 한다.

 

인스턴스화 시킨 것으로는 다음과 같다.

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
package java_practice;
class Cars{            // 클래스 생성
    public String color;    // 색상
    public int maxSpeed;    // 최대속력
    public int minSpeed;    // 최소속력
    
    public void avgSpeed() {    // 평균속력출력 메서드
        System.out.println("평균속력 : " + (Cars.maxSpeed + Cars.minSpeed)/2);
    }
    public void carColor () {    // 색상출력 메서드
        System.out.println("색상 : " + Cars.color);
    }
}
 
public class Class_BasicCars {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        System.out.println("Car1");
        
        Cars car1 = new Cars();        // car1 인스턴스 생성
        car1.color = "Black";    // car1의 색상 지정
        car1.maxSpeed = 400;    // car1의 최대속력 지정
        car1.minSpeed = 10;        // car1의 최소속력 지정
        car1.carColor();        // car1의 색상 출력메서드
        car1.avgSpeed ();    // car1의 평균속력 출력메서드
 
        
        System.out.println("Car2");
        
        Cars car2 = new Cars();        // car2 인스턴스 생성
        car2.color = "White";    // car2의 색상 지정
        car2.maxSpeed = 500;    // car2의 최대속력 지정
        car2.minSpeed = 20;        // car2의 최소속력 지정
        car2.carColor();        // car2의 색상 출력메서드
        car2.avgSpeed ();    // car2의 평균속력 출력메서드
    }
}
cs

모든 static을 지워줌으로써 클래스소속에서 인스턴스 소속으로 바뀌었기 때문에 값을 설정해 주더라도 인스턴스 내에서만 값이 설정된다. (각 할당된 저장 공간 내에서만 값이 저장되기 때문)

이를 시각화하면 다음과 같다.

인스턴스내에서만 값을 지정해 주었고 두 인스턴스의 color값이 각각 다르다. 이를 상태가 다르다고 표현을 하는데 이에 따라서 메서드 color();와 avg();호출 시 각각 다른 값을 갖게 되는 것이다.

 

 

 

 

 

 

 

 

EX 예제 2.

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
package java_practice;
class Calculator{
    int left, right;         // 변수 선언
    public void setOprands (int left, int right) { // 파라미터(매개변수)
        this.left = left;        // this : left값이 위에 담겨서 객체의 전역에서 사용할 수 있게 됨.
        this.right = right;
    }
    public void sum() {
        System.out.println("합계 : "+ this.left + this.right); // int left,right 선언한 값을 가져와서 사용
    }
    public void avg() {
        System.out.println("평균 : "+ (this.left + this.right)/2);
    }
}
 
public class Class_Calculator {
    public static void main(String[] args) {
        
        Calculator c1 = new Calculator();
        c1.setOprands(8090);
        c1.sum();
        c1.avg();
        
        Calculator c2 = new Calculator();
        c2.setOprands(3050);
        c2.sum();
        c2.avg();
    }
}
cs

위의 내용을 설명하자면 다음과 같다.

Calculator클래스 생성 후 c1, c2인스턴스를 생성해 주었다. 인스턴스 생성 시 new Calculator로 객체를 새로 생성해 주었으며, 이를 변수 c1에 저장하였다. 이 변수의 데이터타입은 객체의 이름을 갖게된다.

 

또한 main에서 선언한 80, 90은 클래스내의 메서드 setOprands의 int left, int right에 담기고 이는 메서드 내의 left, right값으로 내려온다.

 

이 값이 this.left, this.right를 통해 변수 선언해준 int left, right에 각각 담기게 된다. 

또한 sum()와 avg()메서드 에서는 int left, right 선언한 값을 가져와 사용하게 된다.

 

 

 

 

 

 

EX 예제 3.

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
package java_practice;
class Cars{
    
    static int wheel = 4;    // 클래스 변수
    int speed;                // 인스턴스 변수
}
 
public class Class_InstanceCars {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("<인스턴스 생성 전>");
        System.out.println(Cars.wheel);    // 클래스변수 접근 가능 , 4
//        System.out.println(Cars.speed);    // 에러발생, 인스턴스 변수 접근 불가
        
        Cars car1 = new Cars();    // 인스턴스 생성 후에는 접근 가능
        
        System.out.println("<인스턴스 생성 후>");
        System.out.println(Cars.wheel);    // 4
        System.out.println(car1.speed);    // 인스턴스 생성 후에는 접근 가능, 0
        
        Cars car2 = new Cars();
        
        System.out.println("<변경 전>");
        System.out.println("car1.speed : " + car1.speed); // 0
        System.out.println("car2.speed : " + car2.speed); // 0
        System.out.println("car1.wheel : " + car1.wheel); // 4
        System.out.println("car2.wheel : " + car2.wheel); // 4
 
        car2.speed = 100;
        car2.wheel = 5;
 
        System.out.println("<변경 후>");
        System.out.println("car1.speed : " + car1.speed); // 0
        System.out.println("car2.speed : " + car2.speed); // 100
        System.out.println("car1.wheel : " + car1.wheel); // 5
        System.out.println("car2.wheel : " + car2.wheel); // 5
    }
}
cs

클래스 변수와 인스턴스 변수의 특징을 알아보는 코드이다.

 

줄4에서 바퀴의 수는 자동차마다 고정적이므로 클래스 변수로 선언하고 줄6에서 자동차의 속력은 고유한 값이므로 인스턴스 변수로 선언한다.

 

줄12에서 "클래스명.변수명"으로 wheel변수를 참조한 것을 참조하여 4를 출력한다.

 

줄13의 요류는 참조하고 있는 speed변수가 인스턴스 변수이므로 아직 인스턴스가 생성되지 않아서 메모리상에 존재하지 않기 때문이다. 줄18에서 인스턴스 생성 이후에는 참조가 가능한 것을 확인한다.

 

줄20에서는 인스턴스를 하나 더 생성한다. console창에서 변경 전과 변경 후를 확인해보면 인스턴스 변수인 speed는 car2의 값만 변했지만 wheel변수는 car1의 값도 바뀐것을 확인할 수 있다.

 

이를 통해 인스턴스 변수는 각각의 인스턴스마다 고유의 저장 공간을 가지고 있기 때문에 별개의 조정이 가능하지만 클래스 변수는 하나의 저장공간을 모든 인스턴스가 함께 공유한다는 것을 알 수 있다. 따라서 하나의 참조변수로 값을 변경하더라도 모든 인스턴스의 값이 변하게 된다.

 

 

 

반응형

댓글