럿고의 개발 노트

[프로그래머스] 자바 입문 > Part5. 클래스와 객체 본문

Java Note/[프로그래머스] 자바 입문(동영상 강의)

[프로그래머스] 자바 입문 > Part5. 클래스와 객체

KimSeYun 2020. 1. 23. 17:30

[프로그래머스] 자바 입문

Part5. 클래스와 객체

1. 클래스 선언

클래스


  • 자바는 객체지향언어로 프로그램을 구성하는 요소들을 객체로 보고 이것이 상호작용 하도록 프로그래밍을 함

  • 자바는 객체를 만들기 위해 반드시 클래스를 먼저 만들어야 함.

  • 클래스는 객체를 만들기 위한 일종의 틀이라고 생각하면 됨.

  • 예를들어서 붕어빵이 객체라면 붕어빵 틀이 클래스

  • 그러나 붕어빵 틀 클래스가 생성되었다고 해서 붕어빵이 만들어진 것은 아님.

  • 즉, 붕어빵틀을 이용해서 객체를 생성해야 함.

  • 그때 사용하는 것이 new연산자로 new연산자 뒤에 나오는 생성자를 이용해 메모리에 객체를 생성

  • 메모리에 만들어진 객체를 인스턴스(instance)라고 함

  • 클래스 선언 방법

          class 클래스명 {
              ....
          }
public class Car { // Car라는 클래스를 생성
    // 설계도를 만드는 것과 유사하다고 생각하면 됨

}
public class CarExam {

    public static void main(String[] args) {
        Car c1 = new Car(); // 객체 생성
        Car c2 = new Car(); // 객체 생성
        Car c3 = new Car(); // 객체 생성
        // new 연산자는 뒤에 나오는 생성자를 이용해 메모리에 객체를 만들수 있음
        // 메모리에 있는 객체를 인스턴스라고 할수 있음
        // c1, c2, c3은 객체를 참조하는 참조 변수라고 생각하면 됨
    }
}

2. 참조타입

참조타입


  • 기본형 타입

    • 논리형 : boolean
    • 문자형 : char
    • 정수형 : byte, short, int, long
    • 실수형 : float, double
  • 참조형 타입

    • 기본형 타입을 제외한 모든 타입으로 배열, 클래스 등 모두 참조 타입
  • new라는 키워드로 객체를 메모리에 올려주고, 메모리에 올라간 객체를 인스턴스라고 함

  • 메모리에 올라간 인스턴스를 가르키는 변수, 참조하는 변수, 레퍼런스한 변수 모두 같은 말로 사용

  • 참조한다, 레퍼런스 한다라는 것은 변수가 인스턴스를 가지고 있는게 아니라 말그대로 가르킨다는 의미

  • 메모리의 위치값이 저장되는 것으로 위치값이 저장된다고 하더라도 어떤 메모리에 저장되는지에 대한 정보를 알 수 없기 때문에 그냥 참조한다라고 표현

public class ReferenceDataType {
    public static void main(String[] args) {
        int i = 4; // 기본형 타입

        String str = new String("Hello"); // 참조형 타입
        // String은 클래스로 뒤에 생성자가 존재
        // new라는 키워드는 클래스를 메모리에 올려달라는 의미
        // 메모리에 올라간 클래스를 인스턴스
        // str = 참조변수 = 레퍼런스변수(String을 가지는것이 아니라, 가르킨다(참조)는 의미)
        // str에는 메모리 위치값이 저장

    }
}

3. String 클래스

String 클래스


  • 자바에서 문자열을 표현하는 클래스 중 가장 많이 사용

  • new 연산자를 이용하지 않고 인스턴스를 만드는 경우와 new 연산자를 이용해서 인스턴스화를 하는 경우 두가지 존재

  • 차이점은 new연산자는 무조건 새롭게 만들어지는데, 이용하지 않는 경우 문자열이 메모리 중에서 상수를 저장하는 영역에 저장됨

  • 메모리를 아끼기 위해서 new연산자를 사용하지 않고 사용하는 것이 좋음.

  • 불변 클래스

  • 다양한 메소드를 가지고 있음.

  • 그러나 메소드를 호출해도 내부의 값이 변하지 않음

    • String을 반환하는 메소드들은 모두 새로운 String을 생성해서 반환
public class StringExam {
    public static void main(String[] args) {
        // String 클래스 : 문자열을 표현하는 자바에서 가장 많이 사용하는 클래스
        // new라는 연산자를 이용하지 않아도 인스턴스 생성 가능

        String str1 = "Hello"; // str1에서 hello라는 문자열이 상수들이 저장되는 메모리 공간에 저장
        String str2 = "Hello"; // Hello라는 인스턴스를 위에서 만들고, str2에서는 메모리에 Hello를 찾고 있다면 그 Hello를 가르키는 방식
        // 따라서 str1과 str2는 같은 인스턴스를 참조하고 있다고 생각하면 됨

        String str3 = new String("Hello"); // 상수영역을 참조하지 않고 힙영역에 만들게 됨.
        String str4 = new String("Hello"); // 상수영역을 참조하지 않고 힙영역에 만들게 됨.
        // 따라서 str3과 str4는 같은 인스턴스를 참조하고 있지 않다.

        if(str1 == str2) { // 객체는 '=='연산자를 사용하면, 같은 영역을 가르키고 있는지 찾는 것
            System.out.println("str1과 str2은 같은 레퍼런스입니다.");
        }
        if(str1 == str3) { // 실행 X
            System.out.println("str1과 str3은 같은 레퍼런스입니다.");
        }
        if(str3 == str4) { // 실행 X
            System.out.println("str3과 str4는 같은 레퍼런스입니다.");
        }
        System.out.println(str1); // Hello
        System.out.println(str1.substring(3)); // substring은 입력된 인덱스부터 짤라서 보여주는 것

        System.out.println(str1); // 위에서 잘랐지만, 변하지 않는다.
        // String의 가지고 있는 가장 큰 특징은 값이 변하지 않는다는 것을 알고 있어야 함


    }
}

4. 필드(field) 선언

필드(field) 선언


  • 자동차가 이름, 번호를 가지고 있는 것처럼 객체도 속성을 가질 수 있음.

  • 이러한 속성들을 필드(field)라고 함.

  • 참조 변수 다음에 나오는 점(.)은 참조변수가 참조하는 객체가 가지고 있는 것을 사용할때 사용

public class Car { // Car라는 클래스를 생성
    // 설계도를 만드는 것과 유사하다고 생각하면 됨
    // 필드 선언 : 타입 필드명

    String name; // 이름 필드 선언
    int number; // 번호 필드 선언
}
public class CarExam {

    public static void main(String[] args) {
        Car c1 = new Car(); // 객체 생성
        Car c2 = new Car(); // 객체 생성
        Car c3 = new Car(); // 객체 생성
        // new 연산자는 뒤에 나오는 생성자를 이용해 메모리에 객체를 만들수 있음
        // 메모리에 있는 객체를 인스턴스라고 할수 있음
        // c1, c2, c3은 객체를 참조하는 참조 변수라고 생각하면 됨

        c1.name = "소방차"; // 필드에 갑 넣기
        c1.number = 1234; // 필드에 값 넣기

        c2.name = "구급차"; // 필드에 값 넣기
        c2.number = 1111; // 필드에 값 넣기

        System.out.println(c1.name); // 필드 출력
        System.out.println(c1.number);
        System.out.println(c2.name);
        System.out.println(c2.number);   
    }
}

5. 메소드란?

메소드(Method)


  • 물체의 행동에 해당(차로 예를 들자면 전진, 후진과 같은 기능)

  • 메소드는 인자, 매개변수(입력값)가 있으며, 그 입력값을 받아서 무언가를 한 다음 리턴값(결과값)를 도출해 내는 수학의 함수와 비슷

자바 메소드 이미지

  • 매개변수(Parameter) : 전달된 인자를 받아들이는 변수

  • 인자(Argument) : 어떤 함수를 호출시에 전달되는 값

  • 메소드는 클래스가 가지고 있는 기능이므로 클래스 안에 선언해야 함.

메소드(Method) 선언

public class MyClass {
    // 메소드(Method)는 클래스가 가지고 있는 기능을 의미
    // 그래서 클래스 내부에 선언
    // 선언방법 : public 리턴타입 메소드명(매개변수들){
    // .....
    // }
    // 리턴타입은 결과값의 타입이다. 
    // 리턴타입이 있는지 없는지, 매개변수가 있는지 없는지에 따라 다양하게 메소드를 정의할 수 있음

    // 리턴타입도 없고 매개변수도 없을때의 메소드
    public void method1() {
        // void란 리턴타입이 없다는 것을 의미
        System.out.println("m1이 실행됨...");
    }

    // 매개변수를 정수로 받고 실행하고 리턴을 하지 않는 메소드
    public void method2(int x) {
        System.out.println(x + "를 이용한 m2 실행");
    }

    // 매개변수는 없지만, 정수를 리턴은 있는 경우
    public int method3() {
        System.out.println("m3 실행");
        return 10; // 값을 돌려주는 키워드(return)
    }

    // 정수인 매개변수를 2개 받고, 리턴은 하지 않는 경우
    public void method4(int x, int y) {
        System.out.println(x + y + "m4 실행");
    }

    // 매개변수가 있고, 리턴을 하는 경우(둘다 정수형)
    public int method5(int y) {
        System.out.println(y + "를 이용한 m5 실행");
        return y*2;
    }
}

메소드의 사용

  • 메소드를 사용하기 위해서는 메소드를 정의한 클래스가 생성되어 있어야 함(인스턴스화)

  • 객체를 생성할때는 new 연산자를 사용.

  • 메소드를 사용할때는 생성된 클래스를 참조하는

    레퍼런스변수.메소드명()

으로 사용가능.

public class MyClassExam {
    public static void main(String[] args) {
        MyClass myclass = new MyClass(); // 클래스 생성
        myclass.method1(); // MyClass에 method1를 실행(매개변수 X, 리턴 X)

        myclass.method2(10); // MyClass에 method2를 실행(매개변수(정수형) O, 리턴 X)

        int value = myclass.method3(); // MyClass에 method3를 실행(매개변수 X, 리턴(정수) O)
        // method3은 리턴값이 있다보니, 리턴값을 받을 변수가 필요
        System.out.println(value); // method3에서 리턴받은 값 출력

        myclass.method4(5, 10); // MyClass에 method4를 실행(매개변수(정수) O, 리턴 X)

        int value2 = myclass.method5(55); // MyClass에 method5를 실행(매개변수(정수) O, 리턴(정수) O)
        // 리턴 값을 변수에 저장
        System.out.println(value2); // method5에서 리턴받은 값을 출력
    }
}

6. String클래스의 메소드

String class가 제공하는 메소드 이용하기

  • Java API

  • length() : 문자열 길이

  • concat() : 문자열 붙이기

  • subString() : 문자열 자르기

public class StringMethodExam {

    public static void main(String[] args) {
        // String str = new String("Hello");
        String str = "Hello World"; // 위의 생성방법과 동일함

        System.out.println(str.length()); // 문자열 길이 : 11, 공백도 포함

        System.out.println(str.concat(" Java")); // 문자열과 문자열을 결합하는 메소드 : Hello World Java
        System.out.println(str); // Hello World
        // concat를 실행하여도, str의 값을 변경하지 않음, (불변클래스)
        // 따로 concat를 실행한 객체를 새로 만듦
        // 왜냐하면, String객체는 상수부분에서 가르키는(참조)하는 것뿐이여서 그렇다
        str = str.concat(" Java"); // 따라서 이렇게 str에다가 따로 값을 넣어줘야 함.
        System.out.println(str);

        // substring은 문자열을 자르는 메소드
        System.out.println(str.substring(3)); // 시작부분만 인자로 받아서 시작부터 맨끝부분까지 출력
        System.out.println(str.substring(3, 7)); // 시작부분과 끝부분을 인자로 받아서 인자에서 설정한 인덱스 사이를 출력    
    }
}

7. 변수의 scope와 static

변수의 스코프

  • 변수들의 사용 가능 범위
  • 선언된 블럭이 그 변수의 사용 범위

static

  • static한 필드(필드 앞에 static 키워드를 붙힌)나, static한 메소드는 class가 인스턴스화가 되지 않아도 사용 가능

  • static한 변수의 특징은 공유된다는 것으로, 값을 저장할 수 있는 공간을 하나만 생성하여 인스턴스가 여러개 생성되어도 static한 변수의 저장공간은 하나뿐임.

public class VariableScopeExam {
    // 변수의 사용범위는 변수가 선언된 블록

    int globalScope = 10; // 이 변수는 클래스 내 전체에서 사용할 수 있는 변수이지만, 인스턴스가 생성될때 생성되기때문에 인스턴스 변수라고 함
    static int staticVal = 7; //static한 필드를 클래스 변수라고 함

    public void scopeTest1(int value) {
        int localScope = 20;
        System.out.println(globalScope); // 10
        System.out.println(localScope); // 20
        System.out.println(value); // 매개변수도 사용가능
    }

    public void scopeTest2(int value2) {
        System.out.println(globalScope);
//        System.out.println(localScope); 사용 불가능
//        System.out.println(value); 사용 불가능
        System.out.println(value2);
    }

    public static void main(String[] args) {
//        System.out.println(globalScope); 사용 불가
//        System.out.println(localScope); 사용 불가
//        System.out.println(value); 사용 불가
//        System.out.println(value2); 사용 불가
        // 모든 클래스는 인스턴스화 하지 않은 채로 사용할 수 없다.
        // static 키워드는 클래스가 인스턴스화가 되지 않아도 사용할 수 있음
        // 그러나 static화를 하지 않은 필드는 사용할 수 없다.(외부에서)
        System.out.println(staticVal); // static한 변수이기때문에 main메소드에서 사용 가능

        // static화하지 않은 변수를 사용하는 방법은 객체를 생성하면 됨
        VariableScopeExam v1 = new VariableScopeExam();
        System.out.println(v1.globalScope); // static하지 않은 변수이기때문에 객체를 생성 후에 출력 가능
        VariableScopeExam v2 = new VariableScopeExam();
        v1.globalScope = 10;
        v2.globalScope = 20;
        System.out.println(v1.globalScope); // 각자 따로 생성했기 때문에 10
        System.out.println(v2.globalScope); // 각자 따로 생성했기 때문에 20
        v1.staticVal = 50;
        v2.staticVal = 100;
        // static화한 변수는 값을 저장할수 있는 곳이 하나밖에 없어서 값을 공유
        // 따라서 인스턴스 변수라고도 함
        System.out.println(v1.staticVal);
        System.out.println(v2.staticVal);

        System.out.println(VariableScopeExam.staticVal); // 클래스 변수는 레퍼런스.변수명 하고 사용하기 보다는 클래스명.변수명으로 사용하는 것이 더 바람직함.
    }
}

8. 열거형(enum)

열거형(enum)

  • 변수를 선언할때 변수타입을 지정할 수 있음

  • JDK5부터 추가가 되었으며, 그 전에는 상수를 열거형 대신 사용함.

  • 상수를 사용했을때 두개의 값만 갖기를 원하는데, 다른 값이 들어와도 문제가 전혀 되지 않았던 점이 발생하게 되면서 열거형이 나오게 됨.

  • 특정 값만 가져야 한다면 열거형을 사용하는 것이 좋음

    public class EnumExam {
      // 자바는 열거타입을 이용하여 변수를 선언할때 변수 타입으로 사용할 수 있음
      // JDK5에서 추가된 문법
      // 열거형이 등장하기 이전에는 public static final을 대신으로 사용 했음
      public static final String MALE="MALE";
      public static final String FEMALE = "FEMALE";
    
      public static void main(String[] args) {
          String gender1;
          gender1 = EnumExam.MALE;
          gender1 = EnumExam.FEMALE;
    
          // MALE과 FEMAL 둘중에 하나만 들어가게 하고 싶지만, 다른 값들도 다 들어감
          gender1 = "boy";
    
          Gender gender2;
          gender2 = Gender.MALE;
          gender2 = Gender.FEMALE;
    
          //gender2 = "boy"; // enum에 정의되지 않은 값이기 때문에 다른값을 저장할 수 없음
      }
    }
    

// 열거형 선언
enum Gender {
MALE, FEMALE;
}

````

※ 출처

[프로그래머스] 자바 입문

Comments