자바 클래스

Tina Jeong·2021년 1월 19일
0

Re-자바

목록 보기
8/16

이번 포스트는 자바의 가장 핵심적이고 기본적인 내용을 정리할 예정이다. 자바 언어를 사용한다면 반드시 알고 있어야 하는 내용이고, 다음 포스트인 '상속'에 대한 빌드업이기도 하다.

클래스 정의하기


객체지향 Object-oriented

자바하면 객체지향이 먼저 떠오른다. 객체지향이란 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.

방금의 문장은 인간적이면서 너무너무 중요한 사고 방식인데..예시를 통해 다시 설명한다. LG 노트북 라인인 그램이 있다. 우리 생활 속 수많은 객체 중 하나인 그램을 관련된 데이터를 생각해본다. 실제로 노트북이 하는 일은 아주 많지만 2가지만 연상한다.

켜진 상태와 꺼진 상태, 저장 장치에 저장된 파일의 개수 이정도만 떠올리고, 이에 관련된 행위(작업)은 전원을 키고 끄기, 성능 향상을 위해 파일을 삭제하는 행위가 있다. 이를 UML 다이어그램으로 나타내면 다음과 같다.


노트북 이름을 저장하는 name, 저장된 파일 개수인 numOfFiles, on/off 상태를 나타내는 flag가 있으며, 데이터와 관련된 행위를 구현한 메소드들이 있다. 이 내용을 코드로 옮기면 자바 class가 된다. 그러므로 자바의 클래스는 객체의 설계도라고 볼 수 있다.

설계도 vs 실물

class가 설계도라면, instance는 설계도를 통해 제작된 실물이라고 볼 수 있다. 즉, 데이터를 기반으로 행위할 수 있는 주체이다. object라는 term은 instance를 의미할 때도 사용하며, 단순히 실생활에서의 객체를 말할 때도 사용한다. 넓은 의미로 사용된다. 고로 실제 그램도 객체이다.

이미지 출처: lg 전자 홈페이지

class : 설계도
instance : 행위할 수 있는 객체
object : 객체 (instance의 의미 포함)

그램 클래스 정의

자바에서 클래스를 정의하는 부분은 크게 3가지로 나누어 진다. 객체의 상태를 저장하는 멤버변수 부분, 상태와 관련된 행위를 하는 메소드 부분, instance를 만들 때 사용하는 생성자부분으로 나누어진다. 생성자는 보통 name,numOfFiles를 instance를 생성하면서 바로 넣어 멤버변수를 반드시 초기화하기 위해 사용하는데 parameterized constructor, 아래 예시는 파라미터가 없는 빈 생성자만 있으므로 생략할 수 있다.

public class LgGram {

    String name;
    int numOfFiles;
    boolean flag;
    
    LgGram() {
    
    }
    
    void turnOn() {
    }

    void turnOff() {
    }

    void accelerate() {
    }
}

이 때, class의 이름은 고유명사이므로 첫글자는 반드시 대문자로 작성해야 하며, class 키워드를 통해 클래스임을 명시한다. 또한, 접근 제한자 중 하나인 public으로 해당 클래스가 global scope임을 명시해 주었다.

메소드 정의하기


C/C++에서는 함수라고 하는데, 자바세계에서는 function term이 메소드method이다. LgGram 상태와 관련된 행위를 하는 메소드 부분을 정의하였다.

public class LgGram{

    String name;
    int numOfFiles;
    boolean flag;
    
    public LgGram() {
    }
    

    void turnOn() {
        if(!flag) flag= true;
        System.out.println("turn on "+name);
    }

    void turnOff() {
        if(flag) flag= false;
        System.out.println("turn off "+name);
    }

    void accelerate() {
        if(numOfFiles>=10) numOfFiles-=10;
        System.out.println("accelerate "+name);
    }
}

메소드의 구조는 다음과 같은데, 이번 예시에서는 접근제한자 부분에 아무것도 써주지 않았으므로 패키지 내에서 접근 가능한 default이다.

접근제한자 반환타입 메소드이름 (파라미터)

생성자 정의하기


이제 메소드는 정의했지만, 멤버 변수가 초기화되지 않았기 때문에 메소드가 의미가 없다. 생성자를 통해 instance를 만들면서 멤버 변수를 초기화해줄 것이다. 위에도 언급했지만, 생성자에는 파라미터가 없는 empty constructor와 파라미터가 포함된 parameterized constructor가 있다. 바로 parameterized constructor를 통해 초기화 한다.

String name ;
int numOfFiles;
boolean flag;


public LgGram(String name, int numOfFiles) {
        this.name = name;
        this.numOfFiles = numOfFiles;
}

public LgGram(String name, int numOfFiles, boolean flag) {
        this.name = name;
        this.numOfFiles = numOfFiles;
        this.flag = flag;
}

Q. setter 왜 안씀? 🤷‍♂️

맞다. 멤버 변수에 대한 getter/setter를 당연히 쓸 수 있다. 그렇지만 무조건 모든 멤버변수에 대해 getter/setter를 사용할 것이 아니라 최대한 해당 클래스 외부에 알려질 필요가 없는 변수들을 숨기면서information hiding 사용해야 한다.

그램 클래스에서는 name은 한번 정해지면 바뀌지 않고, 전원 상태를 나타내는 flag는 내부적으로 처리하면 되고, numOfFiles만 패키지내에서 setter를 통해 값을 조정할 일이 있을 것 같다. 그렇다면 다음과 같이 코드를 추가한다.

public String getName() {
        return name;
}

public int getNumOfFiles() {
        return numOfFiles;
}

void setNumOfFiles(int numOfFiles) {
        this.numOfFiles = numOfFiles;
}

this 키워드


지금 계속 this 키워드가 나오는데, this는 현재 위치한 클래스를 명시하기 위한 것이다. 똑같은 이름의 로컬 변수가 있더라도, this.멤버변수이름의 형태로 멤버변수를 지시하는 것이라 clarify하기 위한 키워드이다.

public void setNumOfFiles(int numOfFiles) {
        this.numOfFiles = numOfFiles; // 멤버변수 numOfFiles에 파라미터로 받은 numOfFiles를 넣어라.
}

new 키워드 instanciation


new는 지금까지 정의한 클래스를 instance를 만드는 instanciation 키워드이다. new를 써야지 행위할 수 있는, 메모리에 올라갈 수 있는 실제 객체가 된다. lgGram,lgGram2가 각각의 인스턴스가 된다. 하나의 설계도를 가지고 여러 개의 객체를 만들 수 있는 것reusability이다.

public static void main(String[] args) {
        LgGram lgGram = new LgGram("15ZD90N-VX50K",100);
        lgGram.turnOn();
        lgGram.turnOff();
        
        LgGram lgGram2 = new LgGram("16ZD90P-GX50K",100);
        lgGram2.turnOn();
        lgGram2.accelerate();
        lgGram.turnOff();
}

결과

turn on 15ZD90N-VX50K
turn off 15ZD90N-VX50K
turn on 16ZD90P-GX50K
accelerate 16ZD90P-GX50K
turn off 15ZD90N-VX50K

오늘은 상태와 행위를 가진 객체에 대해 설명했고, 다음에는 상속을 통한 객체간 유기적인 상호작용에 대해 정리할 것이다.

참고
https://docs.oracle.com/javase/tutorial/java/concepts/object.html
https://docs.oracle.com/javase/tutorial/java/concepts/class.html
https://www.oracle.com/java/technologies/object-oriented.html#1354

계속해서 문서를 업데이트하고 있습니다. 언제든지 댓글피드백 남겨주세요. 😉

profile
Keep exploring, 계속 탐색하세요.

0개의 댓글