본문 바로가기
프로그래밍 언어/Java

[Java] Class와 Instance (객체 형태)

by 까망 하르방 2021. 3. 7.
반응형

Class와 Instance

클래스 = 객체를 만들기 위한 설계도 :: 정의

인스턴스는 = 설계도에 의해 만들어진 제품 :: 호출

public class Person {
    private String name;
    public int age;
    
    // 이름없이 생성
    public Person() {
        
    }
    
    // 이름을 가지고 생성
    public Person(String s) {
        name = s;
    }
    
    public String getName() {
        return name;
    }
}

(1)  클래스 접근권한

접근 권한을 표시하는 것으로, public 접근 권한은

다른 모든 클래스들이 이 클래스에 대해 사용 혹은 접근이 가능함을 뜻한다.

ex) 비워놓거나 public / protected / private 등이 존재

 

(2)  클래스명

'Person'이라는 이름의 클래스를 정의하면 보통 첫글자를 대문자로 표기한다.

 

(3)  필드(field)

값이 저장할 멤버 변수를 선언한다.

멤버 변수 혹은 필드라고 부른다. 접근 지정자를 통해 접근정도를 제어할 수 있으며

static 키워드를 통해 클래스 멤버로 사용할 수도 있다.

 

(4) 생성자

클래스의 이름과 동일한 메소드를 생성자(constructor)라고 부른다.

우선 클래스의 객체가 생성될 때만 호출되는 메소드라는 것만 알아두자.

 

(5) 메소드(method)

메소드는 실행 가능한 함수이며 객체의 행위를 구현한다.

 

[예시 코드]

public class Person {
    private String name;
    public int age;
    
    public Person() {
        
    }
    
    public Person(String s) {
        name = s;
    }
    
    public String getName() {
        return name;
    }
    
    public static void main(String[] args) {

        Person p;
        
        p = new Person();
    
    }
}

 

분석

단계 ①에서 객체를 생성하기 전 객체를 가리킬 레퍼런스 변수의 선언을 한 것이다.

아직 Person 객체가 생성되지 않은 상태.

변수 psms Person 타입의 객체에 대한 레퍼런스를 가지는 변수의 선언일 뿐 객체 자체는 아니다.

현재 어떤 객체도 가리키고 있지 않은 상태이다.

 

C++에서는 단계 만으로도 실제 객체가 생성되며 변수 p 자체가 객체이다.

그러나 자바에서는 레퍼런스 변수를 생성한 것인지 Person 객체가 생성된 것은 아니다.

자바에서는 반드시 new 키워드를 통해 처럼 객체를 생성한다.

 

예시

▶ 절차  어떤 문제 함수화   어떤 문제 클래스화

대형 프로젝트에서는 관련 있든 없든 많은 코드들이 존재한다.

아래 코드를 그러한 코드 中 일부로 가정

public static void main(String[] args) {
    // 아래의 로직이 1000줄 짜리의 복잡한 로직이라고 가정하자.
    System.out.println(10 + 20);
    System.out.println(20 + 40);
}

 

우선 위의 코드에서 하고자 하는 부분은 

중복을 제거하는 것이다. (현재 덧셈 작업이 중복되어 있다.)

중복을 제거하기 위해 메소드를 사용하겠다.

public class CalculatorDemo2 {
    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 class ClaculatorDemo3 {
    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의 의미를 계산을 위한 좌항과 우항이 아니라

그래프의 디자인을 변경하는 코드로 사용했거나,

'right' 변수에 대해 누군가는 '권리', 누군가는 '오른쪽 '이라는 의미를 사용할 수 있다.

혹은 메소드 자체를 덮어 씌울수도 있다. 하나의 프로그램 안에서 메소드나 변수의 의미가 달라지게 되는 것이다.

 

그렇기 때문에 클래스class를 통해서 공용으로 사용할 수 없으며  섞이지 않게 하는 것 설계가 필요하다.

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();
    }
}

'클래스'라는 장치를 더 두어 연관되어 있는 변수와 메소드를 하나의 그룹으로 묶어서 그룹핑하였다.

즉, 연관되어 있는 것들(변수, 메소드 등)끼리만 모으자는 의미이다.

어떻게 하면 데이터(변수)와 연관되어 있는 행위들을 모을 수 있을지 고민한 결과인 것이다.

 

 

 

반응형

댓글