티스토리 뷰
Java는 백기선님의 유튜브를 통해 공부한다.
목표
자바의 Class에 대해 학습하세요.
학습할 것 (필수)
- 클래스 정의하는 방법
- 객체 만드는 방법 (new 키워드 이해하기)
- 메소드 정의하는 방법
- 생성자 정의하는 방법
- this 키워드 이해하기
클래스 정의하는 방법
클래스의 개념
객체 지향 프로그래밍(OOP, Object-Oriented Programming)
객체 지향 프로그래밍에서는 모든 데이터를 객체(object)
로 취급하는데,객체(object)
는 대개 붕어빵
으로 비유된다.
이러한 객체(붕어빵)의 상태
와 행동
을 구체화하는 형태의 프로그래밍이 바로 객체 지향 프로그래밍이다.
클래스(class)
자바에서 클래스(class)란 객체를 정의하는 틀(붕어빵틀)
과 같다.
클래스는 객체의 상태를 나타내는 필드(field)=변수
(variable)와 객체의 행동을 나타내는 메소드
(method)로 구성된다.
인스턴스(instance)
자바에서 클래스를 사용하려면
해당 클래스 타입의 객체(object)를 선언해야 한다.
클래스로부터 객체를 선언하는 과정을 인스턴스 화라고 하고,
인스턴스는 메모리에 할당된 객체
를 의미한다.
자바에서는 하나의 클래스로부터 여러 개의 인스턴스를 생성할 수 있다.
이렇게 생성된 인스턴스는 독립된 메모리 공간에 저장된 자신만의 필드를 가진다.
하지만 해당 클래스의 모든 메소드
(method)는 해당 클래스에서 생성된 모든 인스턴스가 공유
하게 된다.
클래스의 예
ex)
클래스(class) <- 차라고 정의
Car
필드(field) <- Car(차)들의 속성
modelName = "람보르기니"
modelYear = 2016
color = "주황색"
maxSpeed = 350
메소드(method) < - 차들의 행동
accelerate()
brake()
인스턴스(instance) < - 객체
내 차(myCar) : 설계도에 의해 생산된 차량 < = `내 차` 라는 객체
친구 차(friendCar) : 설계도에 의해 생산된 또 다른 차량< - `친구 차` 라는 객체
즉, 자동차 인스턴스는 모두 위와 같은 필드와 메소드를 가지게 된다.
하지만 각 인스턴스마다 가지고 있는 값은 전부 다를 것이다.
클래스 구성요소
class Car { // 클래스 이름
private String modelName; // 필드
private int modelYear; // 필드
Car(String modelName, int modelYear) { // 생성자
this.modelName = modelName;
this.modelYear = modelYear;
}
public String getModel() { // 메소드
return this.modelYear + "년식 " + this.modelName + " " + this.color;
}
}
필드(field)
클래스의 필드(field)란 클래스에 포함된 변수(variable)
를 의미한다.
클래스 내에서 필드는 선언된 위치에 따라 다음과 같이 구분된다.
- 클래스 변수(static variable)
- 인스턴스 변수(instance variable)
- 지역 변수(local variable)
지난 포스팅 자바입문기 2에서 자세히 설명해놨다.
메소드(method)
클래스에서 메소드(method)란 어떠한 특정 작업을 수행하기 위한 명령문의 집합이라 할 수 있다.
생성자(constructor)
생성된 객체는 모든 인스턴스 변수가 아직 초기화되지 않은 상태
이다.
자바는 객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화
할 수 있는생성자(constructor)
라는 메소드를 제공한다.
클래스의 선언
자바에서 클래스를 선언하는 방법은 접근 제어자와 함께 class 키워드를 사용하면 된다.
자바에서 클래스는 다음과 같이 선언한다.
정의
ex)
public class Car{
//접근제어자 class 클래스이름 {
private String modelName;
//접근제어자 필드1의타입 필드1의이름;
private int modelYear;
//접근제어자 필드2의타입 필드2의이름;
...
public void brake(){}
//접근제어자 메소드1의 원형
//접근제어자 메소드2의 원형
...
}
public 멤버는 모든 객체에서 접근할 수 있지만,
private 멤버는 해당 객체 내의 멤버 변수나 메소드만이 접근할 수 있다.
클래스에서 사용되는 수식
- 접근 제어자 : 적용된 키워드에 따라 해당 객체, 메서드가 가시될 범위를 결정한다.
- public :
모든 클래스
에서 해당 클래스를 참조 가능하다. - package-private : 해당 클래스가 포함된
패키지 내
에서만 참조 가능하다. (지정이 없는 경우) - protect :
서브, 하위 클래스와 동일 패키지 내
부에 존재하는 클래스만 참조 가능하다. - private :
자기 자신
인 객체 내부에서만 참조 가능하다. (인터페이스도 JDK9부터 사용 가능)
- public :
- abstract : 해당 클래스, 메서드에서
구현부를 가지지 않고
상속 시 구현을 강제하는 지정 방식이다.추상
클래스, 인터페이스에서 사용된다.
- static : 해당 클래스가 인스턴스화 되어있지 않아도 사용 가능하다는 지정 방식이다.
- 위에서도 언급하였지만 생성 방식과 시점이 다르다.
- final : 해당 지정자가 작성된 것에 대해 상속이나 변경을
금지
한다는 의미이다.→ 하지만 private가 지정된 메서드나 final class에 대해선 명시하지 않아도 된다.- 변수 : 그 필드의
값이 변경
되는 것을 금지한다. - → 값을 해당 필드에서 초기화하지 않는다면, 생성자를 통한 초기화가 강제된다.
- 메서드 : 해당 클래스 타입을 상속받는 서브, 하위 클래스에서
오버라이딩
을 금지한다.
오버라이딩 ->부모클래스등의 메소드의 블럭안의 내용을 하위클래스에서 재정의하여 사용하는 것. - 클래스 : 해당 클래스의
상속
을 금지한다. (String, Integer.... 등)
- 변수 : 그 필드의
- → 일종의 관례로써 전역적으로 사용되는 static 요소들은 final을 붙인다고 한다.
- transient : 객체 직렬화 시에 직렬화 대상에서 제외한다. (이 경우 null로 처리된다.)
- volatile : 해당 지정자가 붙은 변수에 대해서는 스레드가 값을 캐시하지 않고, 메인 메모리에서 처리한다.
- 시간에 따라서 각 쓰레드가 참조하는 값이 달라지는 것을 방지한다.
- 하나의 쓰레드가 값을 증가시키고, 여러 쓰레드가 값을 읽는 경우 항상 최신의 값을 제공하기 위해서는 해당 지정자를 사용하는 것이 좋다.
- → 여러 쓰레드가 값을 증가시키고, 읽는다면 Atomic Variable을 사용하자.
- sysnchronized : 해당 지정자가 붙은 메서드와 스코프에 스레드 간
동기화
를 진행한다는 의미이다.- (이후에 알아보자.)
- native : 해당 지정자가 붙은 메서드는 Java 가 아닌 네이티브 코드를 사용하는 것을 의미한다.
- C/C++ 등으로 작성된 DDL이나 JNI에서 제공하는 코드를 말한다.
- strictfp : 해당 지정자가 붙은 Double, Float에 대하여서 IEEE 754 규격을 적용한다는 의미이다.
- 인터페이스나 메서드에 지정할 수 있다.
객체 만드는 방법 (new
키워드 이해하기)
인스턴스의 생성
다음과 같은 순서대로 Car 객체의 인스턴스를 생성할 수 있다.
우선 다음과 같이 객체를 참조하기 위한 참조 변수를 먼저 선언한다.
선언
클래스이름 객체참조변수이름;
Car myCar;
그 후, new
키워드를 사용하여 인스턴스를 생성하고,
해당 인스턴스의 주소를 미리 선언한 참조 변수에 저장하여 사용한다.
선언
객체참조변수이름 = new 클래스이름();
myCar = new Car();
동시에 할 수도 있다.
선언
클래스이름 객체참조변수이름 = new 클래스이름();
Car myCar = new Car();
메소드 정의하는 방법
메소드(method)
메소드(method)란 어떠한 특정 작업을 수행하기 위한 명령문의 집합이라 할 수 있다.
메소드의 사용 목적
클래스에서 메소드를 작성하여 사용하는 이유는중복되는 코드
의 반복적인 프로그래밍을 피할 수 있고, <-같은 행동(코드)을 따로 메소드로 만들어 준다.
모듈화로 인해 코드의 가독성
도 좋아지고,
문제가 발생하거나 기능의 변경이 필요할 때도 손쉽게 유지보수
를 할 수 있게 되기 때문이다.
메소드는 작성할 때 되도록 하나의 메소드가 하나의 기능만을 수행하도록 작성하는 것이 좋다.
메소드 정의
클래스에서 메소드를 정의하는 방법은 일반 함수를 정의하는 방법과 크게 다르지 않다.
자바에서 메소드를 정의하는 방법은 다음과 같다.
문법
접근제어자 반환타입 메소드이름(매개변수목록) { // 선언부
// 구현부
}
- 접근 제어(한)자 : 해당 메소드에 접근할 수 있는 범위를 명시한다.
- 반환 타입(return type) : 메소드가 모든 작업을 마치고 반환하는 데이터의 타입을 명시한다.
- 메소드 이름 : 메소드를 호출하기 위한 이름을 명시한다.
- 매개변수 목록(parameters) : 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시한다.
- 구현부 : 메소드의 고유 기능을 수행하는 명령문의 집합이다.
자바에서는 하나의 클래스에 같은 이름의 메소드를 둘 이상 정의할 수 없다.
하지만 메소드 오버로딩(overloading)
을 이용하면, 같은 이름의 메소드를 중복하여 정의할 수 있다.
메소드 오버로딩
메소드 오버로딩이란 매개변수의 개수나 타입을 다르게 메소드이름옆에 `(매개변수)'하여 같은 이름의 또 다른 메소드를 작성하는 것이다. 이러한 메소드 오버로딩을 사용함으로써 메소드에 사용되는 이름을 절약할 수 있다.
또한, 메소드를 호출할 때 전달해야 할 매개변수의 타입이나 개수에 대해 크게 신경을 쓰지 않고 호출할 수 있다.
메소드 시그니처(method signature)
란 메소드의 선언부에 명시되는 매개변수의 리스트를 가리킵니다. 만약 두 메소드가 매개변수의 개수와 타입, 그 순서까지 모두 같다면, 이 두 메소드의 시그니처는 같다고 할 수 있다.
다음 예제는 Car 클래스의 accelerate() 메소드를 정의하는 예제이다.
예제
class Car {
private int currentSpeed;
private int accelerationTime;
...
// ↓반환타입
① public void accelerate (int speed, int second) { // 선언부
//↑접근제어자 ↑메소드이름 (매개변수 , 매개변수 )
System.out.println(second + "초간 속도를 시속 " + speed + "(으)로 가속함!!"); // 구현부
}
.
.
.
}
위 예제의 ①번 라인에서는 accelerate() 메소드를 정의하고 있다.
이 메소드는 public
접근 제어자를 사용하여 선언되어 해당 객체를 사용하는 프로그램 어디에서나 직접 접근할 수 있다.
반환 타입에는 어떠한 값도 반환하지 않는다는 의미를 가진void
를 명시한다.
그 다음으로 메소드의 이름을 명시하고, 매개변수(파라미터)
로 int형 변수인 speed와 second를 전달받는다.
이렇게 전달받은 매개변수를 가지고 메소드 구현부에서 고유한 작업을 수행할 수 있는 것이다.
메소드 호출
자바에서 위와 같은 방법으로 정의한 메소드는 멤버 참조 연산자(.)
를 사용하여 호출할 수 있다.
자바에서 메소드를 호출하는 방법은 다음과 같다.
문법
-
객체참조변수이름.메소드이름(); // 매개변수가 없는 메소드의 호출
-
객체참조변수이름.메소드이름(인수1, 인수2, ...); // 매개변수가 있는 메소드의 호출
Car myCar = new Car(); // 객체를 생성함.
myCar.accelerate(60, 3); // myCar 인스턴스의 accelerate() 메소드를 호출함.
다음 예제는 실제로 accelerate() 메소드를 정의하고 호출하는 예제이다.
예제
class Car {
private int currentSpeed;
private int accelerationTime;
public void accelerate(int speed, int second){
System.out.println(second + "초간 속도를 시속 " + speed + "(으)로 가속함!!");
}
}
public class Method01 {
public static void main(String[] args) {
Car myCar = new Car(); // 객체 생성
myCar.accelerate(60, 3); // 메소드 호출
}
}
실행 결과
3초간 속도를 시속 60(으)로 가속함!!
생성자 정의하는 방법
인스턴스 변수의 초기화
클래스를 가지고 객체를 생성하면, 해당 객체는 메모리에 즉시 생성된다.
하지만 이렇게 생성된 객체는 모든 인스턴스 변수가 아직 초기화되지 않은 상태이다.
자바에서 클래스 변수와 인스턴스 변수는 별도로 초기화하지 않으면, 다음 값으로 자동 초기화된다.
변수의 타입 | 초깃값 |
---|---|
char | '\u0000' |
byte, short, int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 또는 0.0D |
boolean | false |
배열, 인스턴스 등 | null |
생성자(constructor)
자바에서는 객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화할 수 있는 생성자(constructor)
라는 메소드를 제공한다.
자바에서 생성자(constructor)의 이름은 해당 클래스의 이름과 같아
야 한다.
즉, Car 클래스의 생성자의 이름은 Car가 된다.
이러한 생성자는 다음과 같은 특징을 가진다.
- 생성자는 반환값이 없지만, 반환 타입을
void
형으로 선언하지 않는다. - 생성자는 초기화를 위한 데이터를 인수로 전달받을 수 있다.
- 하나의 클래스가 여러 개의 생성자를 가질 수 있다.
- 즉, 생성자도 하나의 메소드이므로, 메소드 오버로딩이 가능하다는 의미이다.
- 생성자는 클래스의 이름과 같아야하기 때문에 오버라이딩은 불가능하다.
다음 예제는 Car 클래스를 선언하면서 여러 개의 생성자를 선언하는 예제이다.
예제
Car(String modelName) {}
Car(String modelName, int modelYear) {}
Car(String modelName, int modelYear, String color) {}
Car(String modelName, int modelYear, String color, int maxSpeeds) {}
생성자의 선언
자바에서 클래스 생성자를 선언하는 문법은 다음과 같다.
문법
-
클래스이름() { ... } // 매개변수가 없는 생성자 선언
-
클래스이름(인수1, 인수2, ...) { ... } // 매개변수가 있는 생성자 선언
Car(String modelName, int modelYear, String color, int maxSpeeds) { this.modelName = modelName; this.modelYear = modelYear; this.color = color; this.maxSpeed = maxSpeed; this.currentSpeed = 0;
위의 예제처럼 클래스의 생성자(constructor)는 어떠한 반환값도 명시하지 않음에 주의해야 한다.
생성자의 호출
자바에서는 new 키워드를 사용하여 객체를 생성할 때 자동으로 생성자가 호출됩니다.
class Car {
private String modelName;
private int modelYear;
private String color;
private int maxSpeed;
private int currentSpeed;
Car(String modelName, int modelYear, String color, int maxSpeed) {
this.modelName = modelName;
this.modelYear = modelYear;
this.color = color;
this.maxSpeed = maxSpeed;
this.currentSpeed = 0;
}
public String getModel() {
return this.modelYear + "년식 " + this.modelName + " " + this.color;
}
}
public class Method02 {
public static void main(String[] args) {
Car myCar = new Car("아반떼", 2016, "흰색", 200); // 생성자의 호출
System.out.println(myCar.getModel()); // 생성자에 의해 초기화되었는지를 확인함.
}
}
실행 결과
2016년식 아반떼 흰색
기본 생성자(default constructor)
자바 컴파일러는 컴파일 시 클래스에 생성자가 하나도 정의되어 있지 않으면
자동으로 기본 생성자를 추가한다.
기본 생성자는 매개변수를 하나도 가지지 않으며, 아무런 명령어도 포함하고 있지 않다.
문법
클래스이름() {}
다음 예제는 자바 컴파일러가 Car 클래스에 자동으로 추가해 주는 기본 생성자의 예제이다.
Car() {}
위와 같이 기본 생성자는 어떠한 매개변수도 전달받지 않으며, 기본적으로 아무런 동작도 하지 않는다.
다음 예제는 Car 클래스에 생성자를 정의하지 않고, 기본 생성자를 호출하는 예제이다.
예제
class Car {
private String modelName = "소나타";
private int modelYear = 2016;
private String color = "파란색";
public String getModel() {
return this.modelYear + "년식 " + this.color + " " + this.modelName;
}
}
public class Method03 {
public static void main(String[] args) {
Car myCar = new Car(); // 기본 생성자의 호출
System.out.println(myCar.getModel()); // 2016년식 파란색 소나타
}
}
실행 결과
2016년식 파란색 소나타
만약 매개변수를 가지는 생성자를 하나라도 정의했다면, 기본 생성자는 자동으로 추가되지 않는다.
따라서 매개변수를 가지는 생성자를 하나 이상 정의한 후 기본 생성자를 호출하면, 오류가 발생할 것이다.
예제
class Car {
private String modelName;
private int modelYear;
private String color;
private int maxSpeed;
private int currentSpeed;
① Car(String modelName, int modelYear, String color, int maxSpeed) {
this.modelName = modelName;
this.modelYear = modelYear;
this.color = color;
this.maxSpeed = maxSpeed;
this.currentSpeed = 0;
}
public String getModel() {
return this.modelYear + "년식 " + this.modelName + " " + this.color;
}
}
public class Method04 {
public static void main(String[] args) {
② Car myCar = new Car(); // 기본 생성자의 호출
③ // Car myCar = new Car("아반떼", 2016, "흰색", 200); // 생성자의 호출
System.out.println(myCar.getModel()); // 생성자에 의해 초기화되었는지를 확인함.
}
}
위의 예제는 ①번 라인에서 4개의 매개변수를 갖는 생성자를 정의하고 있다.
따라서 자바 컴파일러는 Car 클래스에 별도의 기본 생성자를 추가하지 않을 것이다.
하지만 ②번 라인에서는 기본 생성자를 호출하여 인스턴스를 생성하려고 하고 있다.
따라서 자바 컴파일러는 오류
를 발생시킬 것이며, ③번 라인과 같이 4개의 매개변수를 전달해야만 인스턴스가 생성될 것이다.
this 키워드 이해하기
this와 this()
this 참조 변수
this 참조 변수는 인스턴스가 바로 자기 자신
을 참조하는 데 사용하는 변수이다.
크게 세 가지의 사용법이 있는데
1. 지역변수와 이름이 같은 `멤버변수`를 해당 지역에 접근할 때
2. 자신의 `객체`를 다른 클래스에게 넘길 때
3. 자신의 `생성자`를 호출할 때
예제
class Car {
private String modelName;
private int modelYear;
private String color;
private int maxSpeed;
private int currentSpeed;
Car(String modelName, int modelYear, String color, int maxSpeed) {
this.modelName = modelName;
this.modelYear = modelYear;
this.color = color;
this.maxSpeed = maxSpeed;
this.currentSpeed = 0;
}
...
}
위의 예제처럼 생성자의 매개변수 이름과 인스턴스 변수의 이름이 같을 경우에는 인스턴스 변수 앞에 this 키워드를 붙여 구분해만 한다. 이렇게 자바에서는 this 참조 변수를 사용하여 인스턴스 변수에 접근할 수 있다.
이러한 this 참조 변수를 사용할 수 있는 영역은 인스턴스 메소드뿐이며, 클래스 메소드에서는 사용할 수 없다.
모든 인스턴스 메소드에는 this 참조 변수가 숨겨진 지역 변수로 존재하고 있다.
this() 메소드
this() 메소드는 생성자 내부에서만 사용할 수 있으며, 같은 클래스의 다른 생성자
를 호출할 때 사용한다.
this() 메소드에 인수를 전달하면, 생성자 중에서 메소드 시그니처(매개변수 리스트)가 일치하는 다른 생성자를 찾아 호출해 줍니다.
다음 예제는 this 참조 변수와 this() 메소드를 사용한 예제이다.
예제
class Car {
private String modelName;
private int modelYear;
private String color;
private int maxSpeed;
private int currentSpeed;
Car(String modelName, int modelYear, String color, int maxSpeed) { //<- 3) 인수가 입력된 객체를 생성함
this.modelName = modelName;
this.modelYear = modelYear;
this.color = color;
this.maxSpeed = maxSpeed;
this.currentSpeed = 0;
}
Car() {
this("소나타", 2012, "검정색", 160); // <- 2) 매개변수가 있는 다른 생성자를 호출하고 인수를 입력함
}
public String getModel() {
return this.modelYear + "년식 " + this.modelName + " " + this.color;
}
}
public class Method05 {
public static void main(String[] args) {
Car tcpCar = new Car(); //<- 1) 매개변수가 없는 생성자를 호출함
System.out.println(tcpCar.getModel()); //<- 4) 생성된 객체에 getModel 메소드를 적용하여 출력한다.
}
}
실행 결과
2012년식 소나타 검정색 // 1, 2 , 3 , 4 순서
위의 예제에서 매개변수를 가지는 첫 번째 생성자는 this
참조 변수를 사용하여 인스턴스 변수에 접근하고 있다.
또한, 매개변수를 가지지 않는 두 번째 생성자는 내부에서 this()
메소드를 이용하여 첫 번째 생성자를 호출한다.
이렇게 내부적으로 다른 생성자를 호출하여 인스턴스 변수를 초기화할 수 있다.
단, 한 생성자에서 다른 생성자를 호출할 때에는 반드시 해당 생성자의 첫 줄에서만 호출할 수 있다.
'코딩 > Java' 카테고리의 다른 글
Java 입문기 07. 패키지 (0) | 2021.07.15 |
---|---|
Java 입문기 06. 상속 (0) | 2021.07.15 |
JavaEE : Web Application 웹 제작하기 기초 (0) | 2021.07.14 |
Java Server Pages : JSP (0) | 2021.07.14 |
Java 입문기 04. 제어문 (0) | 2021.07.13 |
- Total
- Today
- Yesterday
- 인스턴스
- 큐플레이
- 접근지시자
- 1인개발
- Modifying
- 반복문
- HTTPS
- JSP
- 선택문
- 메소드
- javaee
- JavaScript
- JVM
- TSC
- Coding
- aws
- 파이썬게임
- typescript
- Java Web
- error
- 생성자
- nohup
- Java
- 제어문
- 접근제한자
- extends
- Tkinter
- 코딩
- 메소드 디스패치
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |