Part5 클래스와 객체

클래스 선언

  • 클래스
    • 자바는 객체를 만들기 위해 반드 클래스를 먼저 만들어야 한다. 클래스는 객체를 만들기 위한 일종의 틀이다.
      • 붕어빵이 객체라면, 붕어빵 틀은 클래스
      • 자동차 클래스 생성
      • 컴파일하여 디스크에 Car라는 클래스를 생성한다.
      • 자동차 클래스가 생성되었다고 해서 자동차가 만들어 진것은 아니다.
        public class Car{
        }


  • Car객체 생성하기 (자동차 만들기)
    • new 연산자는 new 연산자 뒤에 나오는 생성자를 이용하여 메모리에 객체를 만들라는 명령.
    • 메모리에 만들어진 객체를 인스턴스(instance)라고도 한다.
    • 이렇게 만들어진 객체를 참조하는 변수가 c1, c2 이다.
    • 아래의 코드가 실행되면 Car라는 객체가 2개가 만들어지고 각각의 객체를 참조하는 c1과 c2변수가 선언된다.
        public class CarExam{ 
            public static void main(String args[]){
                Car c1 = new Car();
                Car c2 = new Car();
            } 
        }

참조타입

참조형 타입은 기본형 타입을 제외한 모든 타입입니다. 앞서 배웠던, 배열도 참조형이고, 클래스도 모두 참조 타입이다.

  • 기본형 타입: boolean, char, byte, short, int, long, float, double
  • 참조형 타입: 기본형 타입을 제외한 모든 타입
  • 참조형 변수
    • Stirng str = new String(“Hello);
      • str 변수 앞에 기본형 타입이 아닌 String 클래스가 적혀있다.
      • 이퀄(=) 뒤에는 new 다음에 생성자라는 것이 있다.
      • new 라는 키워드는 객체를 메모리에 올려준다. 이렇게 메모리에 올라간 객체를 인스턴스라고 말한다.
    • 메모리에 올라간 인스턴스를 가리키는 변수, 참조하는 변수, 레퍼런스 하는 변수가 str 이다. 레퍼런스 한다라는 것은 변수가 인스턴스를 가지고 있는게 아니라 말 그대로 가리킨다는 의미이다.
    • str이라는 변수에는 메모리의 위치 값이 저장되는 것이다. 메모리의 위치값이 저장된다고 하더라도, 어떤 메모리에 저장되는지 그 정보를 알 수 있는 방법은 없다. 그렇기 때문에 str변수는 String 인스턴스를 참조한다라고만 알면 된다.

String 클래스

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

자바 인스턴스 생성 방법

  • new 연산자를 이용하지 않고 인스턴스를 만드는 경우
    • “hello”라는 문자열이 메모리 중에서 상수가 저장되는 영역에 저장된다. 상수는 변하지 않는 값을 의미.
    • String str2 = “hello”; 이 문장이 실행될 때에 hello 라는 문자열 상수는 이미 만들어져 있으므로 str1이 참조하는 인스턴스를 str2도 참조한다.
    String str1 = "hello";
    String str2 = "hello"; 
  • new 연산자를 이용해서 인스턴스를 만드는 경우
    • new연산자를 이용하여 인스턴스를 만들면 인스턴스는 무조건 새롭게 만들어진다.
    • String str4 = new String(“hello”); 이 문장이 실행될때도 새롭게 만들게 되므로, str3 과 str4는 서로 다른 인스턴스를 참조한다.
    • 변수끼리 == 로 비교하면 서로 같은 것을 참조하는지 비교한다.
    • String은 다른 클래스와 다르게 new를 사용하지 않고 사용할 수 있다. 메모리를 아끼려면 String은 new를 사용하지 않고 사용하는 것이 좋다.
    • String은 불변 클래스이다. 불변이란 String이 인스턴스가 될때 가지고 있던 값을 나중에 수정할 수 없다.
    • String은 문자열과 관련된 다양한 메소드를 가지고 있다. 메소드를 호출한다 하더라도 String은 내부의 값이 변하지 않는다.
    • String이 가지고 있는 메소드중 String을 반환하는 메소드는 모두 새로운 String을 생성해서 반환한다.
    String str3 = new String("hello");
    String str4 = new String("hello");

필드(filed) 선언

자동차는 자동차 이름, 자동차 번호를 가지고 있고, 자동차는 달리고 멈추는 기능이 있따. 여기에서 가지고 있는 것을 속성이라고 한다. 자바에서는 이러한 속성을 필드(Field)라는 용어로 사용한다.

  • 이름과 번호를 필드로 가지고 있는 Car 클래스 선언
    public class Car{
        String name;    
        int number;
    }
  • Car 클래스를 인스턴스화 하기
    Car c1 = new Car();
    Car c2 = new Car();
    //Car라는 인스턴스가 메모리에 2개 만들어 진다. 객체별로 name과 number라는 속성을 가진다.
  • 속성 이용하기
    • 참조 변수 다음에 나오는 점(dot)은 참조변수가 참조하는 객체가 가지고 있는 것을 사용할 때 사용
    //c1.name은  c1이 참조하는 객체의 name 을 의미.

    c1.name = "소방차";  //c1이 참조하는 객체의 name을 소방차로 설정 
    c1.number = 1234;   // c1.number = 1234란 c1이 참조하는 객체의 number를 1234 로 설정 

    c2.name = "구급차"  //c2가 가리키는 객체의name을 구급차로 설정
    c2.number = 1004;  //c2가 가리키는 객체의 number를 1004로 설정


    System.out.println(c1.name);  //콘솔에 c1이 참조하는 객체의 name 을 출력합니다. 
    System.out.println(c1.number); //콘솔에 c1이 참조하는 객체의 number 를 출력합니다. 

    String name = c2.name;   //c2가 참조하는 객체의 name 을 String 타입 변수 name 도 참조하게 합니다.

메소드란?

  • 필드가 물체의 상태라면, 물체의 행동에 해당하는게 메소드다. car에 이름과 번호가 있기도 하지만, car는 앞으로 전진할 수도 있고 후진하는 행동도 할 수 있다.
    • 메소드는 입력값이 있고, 그 입력값을 받아서 무언가 한 다음 결과를 도출해 내는 수학의 함수와 비슷한 개념이다.
    • 이때 입력값을 매개변수라고 하고, 결과값을 리턴값이라고 한다.
      • 인자(Argument)는 어떤 함수를 호출시에 전달되는 값을 의미한다.
      • 매개 변수(Parameter)는 그 전달된 인자를 받아들이는 변수를 의미한다.
    • 메소드란 클래스가 가지고 있는 기능이다. 클래스 안에 선언된다.

메소드(Method) 선언

  • 매개변수도 없고 리턴하는 것도 없는 형태의 메소드
    • 리턴하는 것이 없을 경우 void라고 작성합니다.
    public class MyClass{
        public void method1(){
            System.out.println("method1이 실행됩니다.");
        }
    }
    
  • 정수를 받아들인 후, 리턴하지 않는 메소드
    • 받아 들이는 값은 어떤 타입이라도 상관없다.
    • 받아 들이는 값의 수는 여러개 일 수 있다. 여러개일 경우 콤마(,)로 구분한다.
    public class MyClass{       
        public void method2(int x, int y){
            System.out.println(x + " 를 이용하는 method2입니다.");
        }   
    }
    
  • 정수를 받아들인 후, 정수를 반환하는 메소드
    public int method3(int y){
        System.out.println(y + " 를 이용하는 method5입니다.");
        return 5;
    }
    

String 클래스의 메소드

  • 문자열 길이 구하기
    • str.length()는 str이 참조하는 문자열의 길이를 구해서 int 타입으로 리턴해주는 메소드이다.
  • 문자열 붙이기(concat)
    • str.concat(“world”) 메소드는 str이 참조하는 문자열 hello 에다가 메소드의 인자로 들어온 문자열 world를 붙여서 String 타입으로 리턴하는 메소드다.
    • String Class는 불변 클래스로, 메소드가 수행되면, 새로운 문자열을 만든다. 그러므로, 원래 클래스는 변하지 않는다.
  • 문자열 자르기(subString)
    • str.subString(1,3)은 str이 참조하는 문자열을 인덱스 1번부터 3번까지 자른 결과이다.
    • str.subString(2)는 str이 참조하는 문자열을 2번 인덱스부터 마지막까지 자른 결과를 의미한다.

변수의 scope와 static

변수의 scope: 프로그램상에서 사용되는 변수들은 사용 가능한 범위를 가진다. 그 범위를 변수의스코프라고 한다.

  • 변수가 선언된 블럭이 그 변수의 사용범위이다.
    • 클래스의 속성으로 선언된 변수 globalScope의 사용 범위는 클래스 전체이다.
    • 매개변수로 선언된 int value는 블럭 바깥에 존재하기는 하지만, 메서드 선언부에 존재하므로 사용범위는 해당 메소드 블럭 내이다.
    • 메소드 블럭내에서 선언된 localScope 변수의 사용범위는 메소드 블럭 내이다.
    public class ValableScopeExam{

        int globalScope = 10;   // 인스턴스 변수 

        public void scopeTest(int value){   
            int localScope = 10;
            System.out.println(globalScope);
            System.out.println(localScpe);
            System.out.println(value);
        }
    }
    
  • main메소드에서 사용하기
    • 같은 클래스 안에 있는데 globalScope 변수를 사용 할 수 없다.
    • main은 static한 메소드이다. static한 메소드에서는 static 하지 않은 필드를 사용 할 수 없다.
    public class VariableScopeExam {
        int globalScope = 10; 

        public void scopeTest(int value){
            int localScope = 20;            
            System.out.println(globalScope);
            System.out.println(localScope);
            System.out.println(value);
        }   
        public static void main(String[] args) {
            System.out.println(globalScope);  //오류
            System.out.println(localScope);   //오류
            System.out.println(value);        //오류  
        }   
    }
    
  • static
    • 같은 클래스 내에 있음에도 해당 변수들을 사용할 수 없다.
    • main 메소드는 static 이라는 키워드로 메소드가 정의되어 있다. 이런 메소드를 static 한 메소드라고 한다.
    • static한 필드(필드 앞에 static 키워드를 붙임)나, static한 메소드는 Class가 인스턴스화 되지 않아도 사용할 수 있다.
    public class VariableScopeExam {
        int globalScope = 10; 
        static int staticVal = 7;

        public void scopeTest(int value){
            int localScope = 20;        
        }

        public static void main(String[] args) {
            System.out.println(staticVal);      //사용가능 
        }

    }
    
  • static한 변수는 공유된다.
    • static하게 선언된 변수는 값을 저장할 수 있는 공간이 하나만 생성된다. 그러므로, 인스턴스가 여러개 생성되도 static한 변수는 하나다.
    • globalScope같은 변수(필드)는 인스턴스가 생성될 때 생성되기 때문에 인스턴스 변수라고 한다.
    • staticVal같은 static한 필드를 클래스 변수라고 한다.
    • 클래스 변수는 레퍼런스.변수명 하고 사용하기 보다는 클래스명.변수명 으로 사용하는 것이 더 바람직하다.
      • VariableScopeExam.staticVal
    public class VariableScopeExam {
        int globalScope = 10; 
        static int staticVal = 7;

        public void scopeTest(int value){
            int localScope = 20;        
        }

        public static void main(String[] args) {
            System.out.println(staticVal);      //사용가능 
        }

    }
    

열거형(enum)

  • 자바는 열거타입을 이용하여 변수를 선언할 때 변수타입으로 사용할 수 있다.
    • 열거형은 JDK5에서 추가되었다.
    • JDK5 이전에는 상수를 열거형 대신 사용
      • 상수를 이요한는 방법
    public class EnumExam {
        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;                  
        }
    }
    
  • 상수를 사용했을 때의 문제점
    • String으로 선언된 gender1 에는 MALE,FEMALE 둘 중 한가지 값을 갖기 원하는데, gender1의 type이 String 이기 때문에 gender1 = “소년”; 이렇게 수행 되어도 전혀 문제가 되지 않는다.
    • 실행할 때 원했던 값인 MALE,FEMALE이 아닌 다른 값이 들어오게 되므로 문제를 발생시킬 수 있다.
  • 해결 방법
    • 이런 문제를 발생시키지 않게 하기 위해 열거형을 사용한다.
    • 열거형 정의 및 사용 방법
    // 정의 방법
    enum Gender{
        MALE, FEMALE;
    }
      
    // 사용 방법
    Gender gender2;

    gender2 = Gender.MALE;
    gender2 = Gender.FEMALE;

    //Gender타입의 변수에는 MALE이나 FEMALE만 대입이 가능. 다른 값은 저장할 수가 없다.  
    

댓글남기기