-
[스터디 5주차]JAVA 클래스프로그래밍 언어/JAVA 2021. 6. 11. 15:35더보기
목표: 자바의 Class에 대해 학습
1. 클래스 정의하는 방법
클래스에는 객체를 생성하기 위한 필드와 메소드가 정의되어 있어 마치 객체의 설계도같은 역할을 한다.
클래스를 정의하는 방법은 먼저 클래스 이름을 정해야한다.
클래스 이름은 다른 클래스와 식별할 목적으로 사용되므로 자바에서만의 식별자 작성 규칙에 따라 만들어야 한다.
식별자 작성 규칙은 아래와 같다.
- 하나 이상의 문자로 이루어져야 한다.
- 숫자는 클래스 이름의 첫 번째 글자로 올 수 없다.
- '$', '_' 이외의 특수 문자는 사용할 수 없다. ($, _는 사용할 수 있지만 첫 번째 글자로는 올 수 없다.)
- 자바 키워드는 사용할 수 없다.
관례적으로 클래스 이름이 한 단어라면 첫 자를 대문자로 하고(ex, Car, Bottle) 두개 이상의 단어가 혼합된 이름을 사용한다면 각 단어의 첫 자를 대문자로 작성(ex, OpenCar, SwitchChannel)한다.
클래스 이름을 정했다면 클래스이름.java로 소스 파일을 생성하고 여기서 소스 파일명과 클래스 이름은 동일해야한다.
소스 파일을 생성하면 소스 파일에 아래와 같이 클래스를 선언한다.
public class 클래스이름 { }
여기서 public class라는 코드에서 public이 무엇인지 궁금할 것이다.
public 접근 제한자 중 하나로 package, Class가 동일하지 않아도 모든 접근이 가능하도록 해준다.
즉, public으로 만들어진 클래스는 다른 패키지나 클래스에서도 접근이 가능하다는 것이다.
일반적으로 소스 파일당 하나의 클래스를 선언하지만 두 개 이상의 클래스 선언도 가능하다.
(되도록이면 소스 파일당 하나의 클래스를 선언하는 것이 좋다.)
public class 클래스이름 { } class 클래스이름2 { }
두 개 이상의 클래스가 선언된 소스 파일을 컴파일하면 바이트 코드파일(.class)은 파일 내에서 선언한 클래스 갯수만큼 생긴다.
여기서 주의할 점은 소스 파일이름과 동일한 이름의 클래스 선언에만 public 접근 제한자를 붙여야한다.
그러면 public class외에 그냥 class로 선언된 클래스는 접근 제한자가 무엇일까?
접근제한자가 생략된 경우에는 default로 동일 package에서만 접근을 허용한다. default는 자동으로 선언되어 지므로 변수, 메소드 앞에 명시적으로 적어서는 안된다.
2. 객체 만드는 방법 (new 키워드 이해하기)
객체를 만드는 방법을 알아보기 전에 객체(object)란 무엇인지 알아보자.
객체란 물리적으로 존재하거나 추상적인 개념 중에서 자신만의 속성(특징)을 가지고 있고 다른 것(다른 객체)과 식별 가능한 것을 의미한다.
예를 들어, 물리적으로 존재하는 것 중 객체라고 말할 수 있는 것은 사람, 자동차, 책 등이 있고
추상적인 개념 중 객체라고 말할 수 있는 것은 주문, 계급, 강의 등이 있다.
이러한 객체는 속성과 동작으로 구성되어 있다.
자동차라는 객체를 생각했을 때 속성은 색깔, 크기, 문 갯수 등이 속성이고 멈추다, 가다, 기어를 바꾸다 등이 동작이다.
자바에서는 속성을 필드, 동작은 메서드라고 부른다.
이제부터 객체를 만드는 방법을 알아보자.
위에서 클래스를 만들었다면 클래스로부터 객체를 만드는 방법은 new 연산자를 사용하면 된다.
new는 클래스로부터 객체를 생성시키는 연산자이다.
new 키워드 뒤에는 생성자가 오는데 생성자는 클래스() 형태를 가진다.
이렇게 new 키워드를 가지고 생성한 객체는 메모리 힙(heap)영역에 생성하고 생성한 객체가 메모리의 어느 위치에 있는지 알려주기위해 객체의 주소를 return한다.
return된 주소를 참조 타입인 클래스 변수에 저장하게 되고 변수를 통해 객체를 사용한다.
클래스명 변수; 변수 = new 클래스명();
3. 메소드 정의하는 방법
메소드를 정의하는 것은 선언부(리턴타입, 메소드이름, 매개변수선언)와 실행 블록으로 구성된다.
여기서 선언부를 메소드 시그니처(signature)라고도 한다.
메소드 이름 앞에 있는 리턴 타입은 메소드가 실행된 후 넘겨줄 결과값이 있는 경우에 해당 리턴값의 타입을 쓴다.
만약, 리턴값이 없다면 리턴 타입을 생략하거나 void라고 쓰면된다.
메소드이름은 자바 식별자 규칙에 맞게 작성해야 하는데 규칙은 아래와 같다.
- 숫자로 시작하면 안되고 $와 _를 제외한 특수문자 사용이 불가하다.
- 관례적으로 메소드명은 소문자로 작성한다.
- 서로 다른 단어가 혼합된 이름이라면 뒤이어 오는 단어의 첫 글자는 대문자로 작성한다.
메소드 이름은 해당 메소드가 어떠한 기능을 하는지 알 수 있도록 지어주는 것이 좋다.
메소드 이름 옆에 ( )안의 매개변수는 외부로부터 데이터를 받아와 사용할 경우에만 명시하고 생략도 가능하다.
만약에 사용할 매개 변수의 개수가 정해져있지 않다면 매개 변수를 배열 타입을 선언하면 된다.
4. 생성자 정의하는 방법
생성자(Constructor)는 new 연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당하며 생성자를 실행시키지 않고 클래스로부터 객체를 만들 수 없다.
모든 클래스에는 하나 이상의 생성자가 반드시 존재하는데 클래스 내부에 생성자 선언을 생략했더라도 컴파일러는 기본 생성자를 바이트 코드에 자동으로 추가시킨다.
<기본 생성자 형태>
클래스명() { }
하지만, 객체를 다양하게 초기화시키기 위해서는 명시적으로 생성자를 클래스내에서 선언해주는 것이 좋다.
그러면 생성자를 정의하는 방법을 알아보자.
클래스명 (매개변수1, 매개변수2, ....) { // 객체 초기화 코드 }
생성자를 정의하는 방법은 클래스 내에 위와 같은 형태로 선언하면 된다.
메소드와 비슷한 형태를 가지지만 리턴 타입이 없고 생성자명은 클래스명과 같다.
클래스명 옆 ( ) 안에 매개변수를 선언하는데 생략이 가능하고 매개변수는 new 키워드로 생성자를 호출할 때 외부의 값을 생성자 블록 내부로 전달하는 역할을 한다.
외부에서 주는 데이터들을 이용해서 객체를 초기화하려면 생성자도 다양화되어야한다.
예를 들어, 외부에서 주는 데이터가 없다면 기본 생성자로 객체를 생성해야하고 외부에서 데이터가 제공되면 해당 데이터를 받아들여 객체를 생성할 수 있어야한다.
이렇게 여러 경우를 받아들여 객체를 생성하도록 생성자 오버로딩(Overloading)을 제공한다.
생성자 오버로딩은 매개 변수를 달리하는 생성자를 여러 개 선언하는 것이다.
예시를 보면 아래와 같다.
public class Car { //필드 String model = "혀대"; String color; int madeYear; //생성자 Car () { } Car (String Color) { } Car (String color, String model) { } Car (String color, int madeYear) { this.color = color; this.madeYear = madeYear; } }
하지만 아래의 코드처럼 매개 변수의 타입, 개수, 선언된 순서가 똑같고 매개 변수 이름만 바꾸는 것은 생성자 오버로딩이 아니다.
public class Car { //필드 String model = "혀대"; String color; int madeYear; int length; //생성자 Car (int madeYear, int length) { } Car (int length, intmadeYear) { }
5. this 키워드 이해하기
this 키워드는 객체가 객체 자신을 부를 때 사용하는 것이다.
즉, 내가 내 자신을 '나'라는 단어로 표현하는 것처럼 객체는 객체 자신을 this라고 하는 것이다.
이러한 this는 어떨 때 쓰일까?
필드(field)를 초기화 할 때 클래스 { } 안이고 생성자나, 메소드 밖에서 초기화 할 수도 있다.
또한, 생성자 { }안에서 초기화 할 수도 있다.
생성자에서 초기화하는 경우는 객체 생성 시점에 외부에서 주어진 값들로 초기화해야하고 싶을 떄이다.
코드를 보며 이해해보자.
public class Car { //필드 String model = "혀대"; String color; int madeYear; //생성자 Car (String c, int m) { color = c; madeYear = m; } }
model, color, madeYear이라는 필드가 존재하고 model은 필드를 선언할 때 초기값을 선언했다.
그리고 color, madeYear은 객체 생성 시점에 매개값으로 값을 받아 초기화한다.
즉, Car c1 = new Car("red", 2021);이렇게 객체를 생성하면서 준 매개값으로 초기화되는 것이다.
위와 같은 경우에서는 this를 쓸 필요는 없다.
하지만, 생성자의 매개 변수 이름은 관례적으로 필드와 같은 이름으로 한다.
이 경우에 필드와 매개 변수 이름이 동일하기 때문에 생성자 내부에서 해당 필드에 접근할 수 없다.
그 이유는 동일한 이름의 매개 변수가 필드보다 사용 우선순위가 높기 때문이다.
public class Car { //필드 String model = "혀대"; String color; int madeYear; //생성자 Car (String color, int madeYear) { color = ...; madeYear = ...; } }
즉, 코드로 보면 생성자에서 사용한 color, madeYear은 필드를 의미하는 것이 아닌 생성자의 매개변수를 가리키게 된다.
여기서 this가 쓰이는 것이다.
this.필드명을 쓰게 되면 객체 자신의 참조가 되어 필드를 가리킬 수 있다.
public class Car { //필드 String model = "혀대"; String color; int madeYear; //생성자 Car (String color, int madeYear) { this.color = color; this.madeYear = madeYear; } }
이렇게 코드를 쓰면 객체를 생성할 때 받은 매개값으로 필드를 초기화할 수 있다.
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
[JAVA 예외 처리] MySQLNonTransientConnectionException (0) 2021.06.13 향상된 for문 (0) 2021.06.11 [스터디 4주차] JAVA 제어문 (0) 2021.06.06 eclipse 프로젝트와 Github 저장소 연결하기 (0) 2021.05.31 [스터디 3주차] JAVA 연산자 (0) 2021.05.30