[코드스쿼드 코코아 과정] 클래스, 인스턴스, 그리고 객체

Kyu·2020년 11월 4일
0

클래스와 인스턴스가 무엇인지 알기전에 왜 필요한지 부터 알아야한다.

public static void main(String[] args) {
	System.out.println(10 + 20);
    	System.out.println(20 + 40);
}

다음과 같은 코드에서 프린트하는 각각의 코드가 1000줄짜리의 복잡한 로직이라고 상상해보자. 그러면 이런 무의미하게 나열된 총 2000줄짜리의 코드들을 프로그래밍을 배우는 사람이라면 누구든지 줄이고자 할것이다. 좀 더 구체적으로 말하자면 유지보수성과 가독성 등을 위해 코드의 중복을 재거해야할 것이다. 이 중복을 제거하기 위해 가장 좋은 방법이 메소드를 사용하는 것이다.

🌟 참고 : 코드를 더 개선하고 효율적으로 만드는 행위를 refactoring이라고 한다.

public static void sum(int left, int right) {
	System.out.println(left + right);
    
}

public static void main(String[] args) {
	sum(10, 20);
    sum(20, 40);
}

위에 코드 처럼 리팩토링할 수 있을 것이다.

그런데 이런 메소드들이 많아지면 어떤 문제들이 발생할까?

    public static void avg(int left, int right) {
        System.out.println((left + right) / 2);
    }
 
    public static void sum(int left, int right) {
        System.out.println(left + right);
    }
 
    public static void main(String[] args) {
        int left, right;
 
        left = 10;
        right = 20;
 
        sum(left, right);
        avg(left, right);
 
        left = 20;
        right = 40;
 
        sum(left, right);
        avg(left, right);
    }
 
}

이렇게 메소드를 사용해서 리팩토링을 했는데 문제가 발생한다. 예를 들어, 누군가가 left, right 변수가 적힌 코드와 sum, avg라고 명명한 메소드를 불러오는 코드 사이에 다른 사람이 여러 로직들을 넣었고, 내가 의도하려했던 계산으로 활용하려는 메소드의 이름을 다른 방식으로 사용한다면, 유지보수가 어려워질것이다.

개발자들 사이에서 조금더 명확하게 calculate_left, calculate_right, calculate_sum, calculate_avg 라고 더 구체적으로 명시하자고 서로 약속할 수도 있다. 하지만 또 개발자들이 사용하는 언어를 개발하는 개발자들은 이런 문제점을 보완하기 위해 고민한다.

그들은 변수로 상징되는 데이터들과 연산으로 상징되는 이 메소드들을 어떻게 서로 연관되어 있는 것들 끼리 그룹핑할것이냐는 고민말이다. 그렇게 해서 만들어진 결론이 객체 지향 프로그래밍이다.

서로 연관 되어 있는 데이터, 연산을 그룹핑할 수 있는 기능을 제공해서 마침 메소드가 그랬던거처럼 언어차원에서 문법적, 기능적 제공을 시작했고 자바는 적극적으로 그것을 채용하여 본격적으로 처음부터 객체 지향 프로그램으로 시작한 언어라고 할 수 있다.

객체지향이라는 문법적인 개념을 도입한다.

class Calculator{
    int left, right;
      
    public void setOprands(int left, int right){
        this.left = left;
        this.right = right;
    }
      
    public void sum(){
        System.out.println(this.left+this.right);
    }
      
    public void avg(){
        System.out.println((this.left+this.right)/2);
    }
}
  
public class CalculatorDemo4 {
      
    public static void main(String[] args) {
          
        Calculator c1 = new Calculator();
        c1.setOprands(10, 20);
        c1.sum();       
        c1.avg();       
          
        Calculator c2 = new Calculator();
        c2.setOprands(20, 40);
        c2.sum();       
        c2.avg();
    }
  
}

결론부터 말하자면 이 코드에서 클래스, 인스턴스, 객체와 같은 개념이 전부 나타난다. 코드를 한 줄씩 살펴보면서 이해하는 것은 아마 이런 어려운 개념들을 전체 이해하는데 쉬운 접근일 것이다.

Calculator c1 = new Calculator(); 의 우항부터 살펴보자면, Calculator가 객체라고 할 수 있고, 이 객체를 새로 만들어 c1이라는 변수에 담은 것이다. c1 왼쪽의 Caclculator는 데이터타입을 말하고, Calculator라는 객체를 새로 만들면서 직접 데이터타입을 정의해준 것이라고 할 수 있다. 그리고 데이터타입과 객체의 이름은 같아야한다.

그 다음 코드 c1.setOprands(10, 20); 를 살펴보자. 우리가 Calculator라는 객체를 담은 c1 객체에서 setOprands라는 메소드에 10과 20이라는 인자를 전달한다는 것을 의미한다.

c1.sum();c1.avg();는 메소드에 아무것도 안넣었지만 호출해서 사용함으로써 결과값 30과 15가 나올 것이다.

여기서 c1 객체는 클래스라는 로직을 가지고 있는 것이다. 그리고 Calculator를 새롭게 만들고 그것을 c1이라는 변수에 담으로써 구체적인 객체가 되고 이것을 인스턴스라고 부른다.

구체적인 객첼ㄹ 만들기 위해서, 즉 인스턴스를 만들기 위해 그 객체가 어떤 모습이고 어떤 메소드와 어떤 변수로 이루어져있는가에 대한 정보를 담고 있는 설계도가 있어야한다. 그 설계도가 클래스인 것이다.

다시 코드로 돌아가서,

class Calculator{
    int left, right;
      
    public void setOprands(int left, int right){
        this.left = left;
        this.right = right;
    }
      
    public void sum(){
        System.out.println(this.left+this.right);
    }
      
    public void avg(){
        System.out.println((this.left+this.right)/2);
    }
}
  
public class CalculatorDemo4 {
      
    public static void main(String[] args) {
          
        Calculator c1 = new Calculator();
        c1.setOprands(10, 20);
        c1.sum();       
        c1.avg();       
          
        Calculator c2 = new Calculator();
        c2.setOprands(20, 40);
        c2.sum();       
        c2.avg();
    }
  
}

가장 첫 줄에 classs calculatorclass가 의미하는 것은 calculator라고 하는 객체의 설계도를 컴퓨터에게 알려주는 역할이자 단어이자 약속이다.

🌟 팁 : 객체를 바라볼때 하나의 독립된 프로그램으로 바라보아라. 그 프로그램안에 메소드와 변수들이 있는 것이다. 메소드의 집합이 객체이기도 하다.

this.left = left; 에서 this는 나도 잘 모르겠다. 더 공부가 필요하다 하지만 this를 쓰면 left에 담긴 변수가 class 전역에서 쓸수 있게 된다는 사실은 인지해야 한다.

결론적으로 객체는 상태와 행위의 집합이라 할 수 있다. 상태는 인스턴스가 가지고 있는 변수들의 집합이고 행위는 메소드를 호출하는 행위라고 여겨볼 수 있다.

profile
TIL 남기는 공간입니다

0개의 댓글