코드 스테이츠 9일차
클래스
클래스(Class)란?
객체를 정의한 '설계도(blueprint)' 또는 '틀(frame)’이라 정의할 수 있습니다. 즉, 클래스는 객체를 생성하는 데 사용되며, 반대로 객체는 클래스에 정의되고 설계된 내용 그대로 생성됩니다. 따라서 이 둘은 서로 떼려야 뗄 수 없는 불가분의 관계에 있습니다.
여기서 꼭 기억하고 넘어가야 할 한 가지는, 클래스는 객체 그 자체가 아니라 단지 객체를 생성하는 데 사용되는 하나의 틀이라는 사실입니다.
클래스는 객체 그 자체가 될 수 없습니다. 우리의 실생활로 예를 들자면 클래스와 객체의 관계는 마치 어떤 제품의 설계도와 제품과의 관계로 비유할 수 있습니다. TV의 설계도가 TV 그 자체가 될 수 없는 것처럼 클래스 또한 객체 그 자체가 될 수 없습니다.
인스턴스
클래스를 통해 생성된 객체를 우리는 해당 클래스의 인스턴스(instance)라 부릅니다. 또한 클래스로부터 객체를 만드는 과정을 우리는 인스턴스화(instantiate)라 지칭합니다.
클래스의 구성요소와 기본 문법
클래스는 기본적으로 class 키워드를 사용하여 다음과 같이 정의합니다. 클래스명은 주로 대문자로 시작하는 것이 관례입니다.
class 클래스명 { // 클래스 정의
-- 생략 --
}
클래스는 크게 네 가지의 요소로 구성되어 있습니다.
네 가지 구성요소는 각각 필드(field), 메서드(method), 생성자(constructor), 그리고 이너 클래스(inner class)입니다.
- 필드 - 클래스의 속성을 나타내는 변수입니다. 자동차로 예를 들면 모델명, 컬러, 바퀴의 수 등이 포함될 수 있습니다.
- 메서드 - 클래스의 기능을 나타내는 함수입니다. 자동차를 예로 들면 시동하기, 가속하기, 정지하기 등이 포함될 수 있습니다.
- 생성자 - 클래스의 객체를 생성하는 역할을 합니다. 뒤의 내용에서 좀 더 자세히 학습하도록 합니다.
- 이너 클래스 - 클래스 내부의 클래스를 의미합니다.
위의 구성 요소들 중 생성자를 제외한 나머지 3가지 요소를 우리는 클래스의 멤버(member)라 부릅니다.
이 중에서 필드와 메서드는 각각의 클래스가 가지는 속성(state)과 기능(behavior)을 대표합니다. 속성과 기능은 해당 클래스와 관련된 데이터의 집합이며, 핵심적인 정보를 담고 있다고 할 수 있습니다.
객체(Object)
객체란?
데이터와 이를 처리하는 메서드(Method)를 하나의 논리적인 단위로 묶어 놓은 것입니다. 즉, 객체는 자료와 기능을 가지고 있는 것으로, 실제 세계의 사물을 추상화해서 만든 것이라고 할 수 있습니다.
객체는 크게 속성과 기능이라는 두 가지 구성요소로 이뤄져 있습니다.
속성과 기능은 각각 필드와 메서드로 정의되는데, 일반적으로 하나의 객체는 다양한 속성과 기능의 집합으로 이뤄져 있습니다. 그리고 이러한 속성과 기능은 이너클래스와 함께 객체의 멤버(member)라 부릅니다.
객체의 생성
객체는 다음과 같이 생성합니다.
클래스명 참조_변수명; // 인스턴스를 참조하기 위한 참조변수 선언
참조_변수명 = new 생성자(); // 인스턴스 생성 후, 객체의 주소를 참조 변수에 저장
먼저 특정 클래스 타입의 참조변수를 선언합니다. 참조변수가 선언되면, 이제 new 키워드와 생성자를 통해 인스턴스를 생성하여 참조변수에 할당합니다.
여기서 참조 변수는 실제 데이터 값이 아니라 실제 데이터가 저장되어 있는 힙 메모리의 주소값을 가리킵니다. 좀 더 자세한 내용은 아래에서 살펴보도록 하겠습니다.
new 키워드는 생성된 객체를 힙 메모리에 넣으라는 의미를 가지고 있는데, 생성자(클래스와 동일한 이름을 가졌지만 뒤에 소괄호가 붙음)를 통해 객체가 만들어지면 해당 객체를 힙 메모리에 넣는 역할을 수행하게 됩니다.
이 과정을 간편하게 줄여서 다음처럼 선언할 수 있습니다.
클래스명 참조_변수명 = new 생성자();
객체의 활용
우리가 기억해야 할 가장 중요한 것은 .입니다. 포인트 연산자라고도 불리는데, 그 의미는 ‘해당 위치에 있는 객체 안을 보세요'라는 뜻을 가지고 있습니다.
우리는 이 .을 활용하여 특정 인스턴스 객체의 필드와 메서드, 즉 객체의 멤버들에 접근할 수 있습니다.
기본적인 문법은 다음과 같습니다.
참조 변수명.필드명 // 필드값 불러오기
참조 변수명.메서드명() // 메서드 호출
필드(Field)
필드
필드는 ‘클래스에 포함된 변수'를 의미하는 것으로 객체의 속성을 정의할 때 사용됩니다.
자바에서 변수는 크게 클래스 변수(cv, class variable), 인스턴스 변수(iv, instance variable), 그리고 지역 변수(lv, local variable)라는 세 가지로 구분될 수 있습니다.
이 중 우리가 필드라 부른 것은 클래스 변수와 인스턴스 변수이며, 이 둘은 다시 static 키워드의 유무로 구분할 수 있습니다.
tatic 키워드가 함께 선언된 것은 클래스 변수, 그렇지 않은 것은 인스턴스 변수입니다. 그리고 이 두 가지 변수 유형에 포함되지 않고 메서드 내에 포함된 모든 변수를 지역변수라 부릅니다.
class Example { // => 클래스 영역
int instanceVariable; // 인스턴스 변수
static int classVariable; // 클래스 변수(static 변수, 공유변수)
void method() { // => 메서드 영역
int localVariable = 0; // 지역 변수. {}블록 안에서만 유효
}
}
static
static 키워드란?
static은 클래스의 멤버(필드, 메서드, 이너 클래스)에 사용하는 키워드입니다.
static 키워드가 붙어있는 멤버를 우리는 ‘정적 멤버(static member)’라고 부르고 static이 붙어있지 않은 인스턴스 변수와 구분합니다.
이 둘을 구분하는 가장 큰 차이는 인스턴스 멤버는 기존에 우리가 배웠던 내용처럼 반드시 객체를 생성한 이후에 변수와 메서드에 접근하여 해당 멤버를 사용가능한 반면, static 키워드로 정의되어 있는 클래스 멤버들은 인스턴스의 생성 없이도 클래스명.멤버명 만으로도 사용이 가능하다는 점입니다.
메서드(Method)
메서드란?
“특정 작업을 수행하는 일련의 명령문들의 집합"을 의미한다.
클래스의 기능에 해당하는 내용들을 담당한다. 자동차를 예를 들면 시동걸기, 가속하기, 정지 등이 메서드로 정의되어있다.
메서드는 다시 크게 머리에 해당하는 메서드 시그니처(method signature)와 몸통에 해당하는 메서드 바디(method body)로 구분할 수 있습니다.
자바제어자 반환타입 메서드명(매개 변수) { // 메서드 시그니처
메서드 내용 // 메서드 바디
}
메서드의 시그니처는 순서대로 해당 메서드가 어떤 타입을 반환하는 가(반환 타입), 메서드 이름이 무엇(메서드명)이며 해당 작업을 수행하기 위해서 어떤 재료들이 필요한지(매개 변수)에 대한 정보를 포함하고 있습니다.
public static int add(int x, int y) { // 메서드 시그니처
int result = x + y; // 메서드 바디
return result;
}
만약 메서드의 반환타입이 void가 아닌 경우에는 메서드 바디({}) 안에 반드시 return 문이 존재해야 합니다. 리턴문은 작업을 수행한 결과값을 호출한 메서드로 전달합니다. 여기서 결과값은 반드시 반환타입과 일치하거나 적어도 자동 형변환이 가능한 것이어야 합니다.
메서드 오버로딩
하나의 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것을 의미합니다.
오버로딩의 가장 큰 장점은 하나의 메서드로 여러 경우의 수를 해결할 수 있다는 것입니다.
public class Overloading {
public static void main(String[] args) {
Shape s = new Shape(); // 객체 생성
s.area(); // 메서드 호출
s.area(5);
s.area(10,10);
s.area(6.0, 12.0);
}
}
class Shape {
public void area() { // 메서드 오버로딩. 같은 이름의 메서드 4개.
System.out.println("넓이");
}
public void area(int r) {
System.out.println("원 넓이 = " + 3.14 * r * r);
}
public void area(int w, int l) {
System.out.println("직사각형 넓이 = " + w * l);
}
public void area(double b, double h) {
System.out.println("삼각형 넓이 = " + 0.5 * b * h);
}
}
//출력값
넓이
원 넓이 = 78.5
직사각형 넓이 = 100
삼각형 넓이 = 36.0
위의 예시를 보면, Shape 클래스 안에 있는 모든 메서드들이 area()라는 메서드명을 가지고 있음에도 불구하고 각기 다른 출력값을 리턴하는 것을 확인하실 수 있습니다.
한 가지 꼭 기억해야 하는 점은 무조건 같은 메서드명을 사용한다고 해서 오버로딩이 되는 것이 아니라는 것입니다.
오버로딩의 조건을 정리하면 다음과 같습니다.
- 메서드를 오버로딩하려면
- 메서드의 이름이 같아야 합니다.
- 매개변수의 개수 또는 타입이 달라야 합니다.
'코드 스테이츠' 카테고리의 다른 글
코드 스테이츠 04/25 - 객체 지향 프로그래밍 심화1 (1) | 2023.04.25 |
---|---|
코드 스테이츠 4/24 - 객체지향 프로그래밍 기초 2 (0) | 2023.04.24 |
코드 스테이츠 4/20 - Java 기초 3 (0) | 2023.04.20 |
코드 스테이츠 4/19 - Java 기초 3 (0) | 2023.04.19 |
코드 스테이츠 4/18 - Java 기초 2 (0) | 2023.04.18 |