ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] Class와 객체
    Language/Java 2019. 10. 5. 16:24

     

     

    자바에서 가장 핵심적인 개념을 꼽자면 단연 객체(Object)라고 할 수 있습니다.

    그렇다면 객체란 무엇일까요?

     

    논리적 개념으로는 실제 세계의 모든 유, 무형의 모든 것들을 의미합니다. 모든 객체들은 각각 고유의 속성과 기능을 가질 수 있습니다.

     

    자동차를 예로 들면, 자동차는 크기, 색깔 등의 속성을 가지고, 주행, 멈춤 등의 기능을 가지고 있죠. 이러한 속성과 기능을 포함한 자동차라는 객체가 생성될 수 있습니다.

     

    자바를 처음 시작할 때 Class와 객체의 개념을 혼동하는 분들이 많은데 Class와 객체는 아주 비슷하지만 다른 개념입니다. 이 차이를 설명할 때 흔히들 붕어빵을 예로 들어 Class는 붕어빵 틀이고, 객체는 붕어빵이라고 설명하곤 합니다.

     

    더 구체적으로, 위에서 언급한 자동차를 이용해 Class와 객체를 구현해보도록 하겠습니다.

     

    Car Class

    class Car{
    
      int price;
      String color;
    
      public void drive(int speed){
          System.out.println(speed+"km/h 로 주행합니다.");
      }
    
      public void stop(){
          System.out.println("주행을 멈춥니다.");
      }
    
    }

     

    Car라는 이름을 가진 Class를 하나 정의했습니다. price, color, size라는 속성과, drive, stop 메소드를 가지고 있습니다.

    이 Class를 이용해서 객체를 생성해보겠습니다.

     

    Car Class의 객체 생성

    class Test{
    
      public static void main(String [] args){
        
        Car benz = new Car();
        benz.price = 300;
        benz.color = "blue";
        benz.drive(80);
        System.out.println(benz.color);
    
        Car porsche = new Car();
        porsche.price = 400;
        porsche.color = "yellow";
        porsche.drive(90);
        System.out.println(porsche.color);
        
        Car audi = new Car();
        audi.price = 500;
        audi.color = "red";
        audi.drive(100);
        audi.stop();
        System.out.println(audi.color);
        
      }
    }

     

    Car라는 클래스를 각각 benz, porsche, audi라는 변수에 담아 세 개의 객체를 생성했습니다.

    이 세 객체는 모두 price, size라는 속성과 drive, stop이라는 메소드를 가지고 있지만, 각각 다른 값을 가지고 있는 별개의 객체입니다.

    하나의 붕어빵 틀로 팥, 슈크림 등 각기 다른 종류의 붕어빵을 만들 수 있듯이 Car라는 Class로 가격과 색상이 각기 다른 객체를 생성 할 수 있는 것입니다. 

     

    Getter / Setter

    위 코드에서는 각 객체의 속성값에 접근할 때 benz.price=300; 처럼 객체.속성(변수명)의 형태를 사용했습니다. 이렇게 접근하는 것도 가능하지만 데이터의 무결성을 보장할 수 없다는 문제가 있습니다. 외부에서 해당 Class의 데이터에 위와 같이 직접 접근하는 경우 개발자의 의도에서 벗어나는 데이터 조작이 이루어질 수 있기 때문입니다.

     

    예를 들어, 위의 Car Class에서 price 변수에는 500미만의 양수 값만 들어갈 수 있고, color 변수는 값을 불러오는 경우 뒤에 'color'라는 단어를 붙여야한다고 가정해봅시다. 

    audi의 price에는 500이라는 값이 할당될 것이고, 이는 개발자가 의도한 값이 아니지만 어떤 에러도 발생하지 않을 것입니다. 또한, 각 객체의 color값을 출력할 때, 'color'라는 단어를 붙여줄 수도 없습니다.

     

    이를 해결하기 위해, 해당 Class의 데이터의 접근제한자를 private로 설정하고 getter/setter 메소드를 사용합니다.

    (접근제한자에 대한 설명은 다음 포스팅에서 다룰 예정, private는 해당 Class외부에서의 접근을 차단하는 접근제한자)

     

    public class Car {
    
    	private int price;		// private: 외부에서 접근 불가
    	private String color;
    
    	public void drive(int speed) {
    		System.out.println(speed + "km/h 로 주행합니다.");
    	}
    
    	public void stop() {
    		System.out.println("주행을 멈춥니다.");
    	}
    
    	public int getPrice() {		// price변수 값 불러오기
    		return price;
    	}
    
    	public void setPrice(int price) {		// price변수에 값 할당하기
    		if (price >= 0 && price < 500) {
    			this.price = price;
    		}
    	}
    
    	public String getColor() {		//color변수 값 불러오기
    		return color + "color";
    	}
    
    	public void setColor(String color) {		//color변수에 값 할당하기
    		this.color = color;
    	}
    
    }
    

     

    위에서 작성했던 Car Class를 다음과 같이 수정할 수 있습니다. 외부에서 데이터를 할당할 때는 setter메소드를 호출하여 값을 넣어주고, 데이터를 불러올때는 getter메소드를 호출하여 값을 불러올 수 있습니다.

     

    이를 통해 데이터 무결성을 보장할 수 있고, 데이터를 불러오는 경우에도 외부에서 직접 데이터에 접근하지 못하게 해서 개발자가 의도한대로 값을 보여줄 수 있습니다.

     

    이에 따라 Test 클래스를 다음과 같이 수정할 수 있습니다.

     

    public class Test{
    
    	  public static void main(String [] args){
    	    
    	    Car benz = new Car();
    	    System.out.println("--------------벤츠--------------");
    	    benz.setPrice(300);
    	    benz.setColor("blue");
    	    benz.drive(80);
    	    System.out.println("price : "+benz.getPrice());
    	    System.out.println("color : "+benz.getColor());
    
    	    Car porsche = new Car();
    	    System.out.println("--------------포르쉐--------------");
    	    porsche.setPrice(400);
    	    porsche.setColor("yellow");
    	    porsche.drive(90);
    	    System.out.println("price : "+porsche.getPrice());
    	    System.out.println("color : "+porsche.getColor());
    	    
    	    Car audi = new Car();
    	    System.out.println("--------------아우디--------------");
    	    audi.setPrice(500);
    	    audi.setColor("red");
    	    audi.drive(100);
    	    audi.stop();
    	    System.out.println("price : "+audi.getPrice());
    	    System.out.println("color : "+audi.getColor());
    	  }
    	}

     

     

    Test 클래스를 실행한 결과 화면인데요, 아우디의 price변수에 500을 할당한 코드가 실행되지 않은 것을 확인할 수 있습니다.

     

     

    tip) eclipse에서는 getter/setter메소드를 자동으로 생성해주는 기능이 있습니다.

     

    에디터에 마우스를 놓고 우클릭한 후, Source > Generate Getters and Setters

     

     

    Getter/Setter를 생성하고자하는 변수를 선택해준 후 Generate버튼을 누르면 자동으로 각 변수에 대한 Getter/Setter를 생성해줍니다. 위의 Source메뉴에는 코딩할 때 유용한 기능들이 많이 있으니 나중에 이 부분만 따로 정리해도 좋을 것 같습니다.

     

    객체 생성시 메모리 구조

    이렇게 객체를 생성하면 JVM에 의해 데이터가 메모리에 할당되는데요, 그림으로 표현하면 다음과 같습니다.

     

    각각의 객체를 가지고있는 변수들은 Stack에 적재되고, 이는 실제 데이터가 저장된 Heap의 주소값을 저장하게 됩니다. Car Class내의 데이터들은 Heap에 저장되는데, 그 중에서도 int타입인 price는 바로 값이 저장되고, String인 color는 주소값이 저장되는 것을 볼 수 있습니다.

     

    즉, primitive타입은 값이 저장되고 Object타입은 주소값이 저장된다는 것을 알 수 있습니다.

     

     

    'Language > Java' 카테고리의 다른 글

    [JAVA] Static이란? / Garbage Collector  (0) 2019.10.06
    [JAVA] 접근제한자(Access Modifier)  (0) 2019.10.06
    [JAVA] Java 환경설정 / eclipse 설치  (0) 2019.10.05
    [JAVA] Java 환경설정 / JDK 설치  (0) 2019.09.29
    [JAVA] Java 시작하기  (0) 2019.09.29
Designed by Tistory.