[JAVA] 클래스
객체와 객체 지향 프로그래밍(OOP : Object - Oriented Programming)
객체 지향 프로그래밍이란, 객체를 중심으로 프로그램 구조를 설계하고 프로그래밍 하는 것을 객체 지향 프로그래밍이라고 한다.
객체란, 우리 실생활에 존재하는 모든 것으로 생각할 수 있다. Ex) 컴퓨터, 연필, 책 등등 (눈에 보이는 물체들)
또한 객체는 일반적으로 상태를 표현할 수 있고 우리가 행동으로 실행할 수 있는 모든 것을 말한다.
클래스란 ?
클래스는 객체를 생성하기 위한 제작 설명서이다. 쉽게 말해서 어떤 물건을 만들기 위한 '틀'이라고 생각할 수 있다. 따라서 우리는 클래스를 기반으로 객체를 생성한다. 하나의 설명서로 여러 개의 물건을 만들 수 있듯이, JAVA에서는 하나의 클래스로 여러 개의 객체를 생성하고 사용할 수 있다.
클래스의 선언 방법
class 클래스명 {
필드 선언
메소드() {
실행할 문장;
}
}
이런식으로 작성할 수 있다.
클래스 구성
클래스는 클래스를 바탕으로 생성된 객체가 가져야할 특징과 요소들로 구성되어 있는데, 그 요소에는 필드, 메소드, 생성자가 있다.
필드
객체가 가져야 할 데이터 상태를 저장하는 변수를 말한다. 하지만 우리는 변수라고 부르지 않고 필드라고 부른다. 필드에 선언 시 초기화를 동시에 진행할 수 있다.
public class Car {
int wheel = 4; // 필드 선언 및 초기화
}
필드의 사용
변수와 마찬가지로 필드의 값을 읽거나 변경할 수 있다. 클래스 안에서는 기존에 변수를 사용했던 것처럼 사용할 수 있다.
public class Car {
int wheel = 4; // 필드 선언 및 초기화
wheel = 5; // wheel의 값을 5로 변경한다.
}
또한, 필드를 선언한 클래스가 아닌 다른 클래스에서도 사용할 수 있다. 그 방법은 다른 클래스에서 객체를 생성한 후 그 객체의 필드에 접근할 수 있다.
public class Car {
int wheel = 4;
}
public class Test01 {
public static void main(String[] args) {
Car c = new Car(); // 객체 생성
System.out.println("wheel의 개수는 " + c.wheel + "개 입니다.");
c.wheel = 5; // c 객체의 데이터 wheel에 접근해 값을 5로 변경
System.out.println("wheel의 개수는 " + c.wheel + " 개 입니다.");
}
}
이런식으로 사용할 수 있다.
메소드
객체의 기능을 담당하는 중괄호 { } 블록을 말한다. 특정 기능을 수행하는 코드를 따로 빼서 중괄호 안에 작성하며, 1개의 메소드는 1개의 기능을 수행한다. 메소드를 사용하는 목적은 재사용성에 용이하고, 소스코드가 간결해지는 장점 때문에 사용한다.
메소드의 선언
1. 메소드 이름을 생각한다.
ride(){}
2. 매개변수를 생각한다.
ride(){} // 매개변수가 있다면 괄호() 안에 작성
3. 실행할 문장을 작성한다.
ride(){
System.out.println("달립니다.");
System.out.println("씽씽씽");
}
4. 리턴 값을 작성한다.
ride() {
System.out.println("달립니다.");
System.out.println("씽씽씽");
// 리턴 값이 있을 시 "return 값;" 으로 작성
}
5. 리턴 타입을 결정한다.
void ride(){
System.out.println("달립니다.");
System.out.println("씽씽씽");
// 리턴 값이 있을 시 "return 값;" 으로 작성
}
리턴 값이 있을 땐 리턴값의 자료형을 반환 타입으로 작성하고, 리턴 값이 없을 땐 반환 타입을 void로 작성한다.
메소드의 주의 사항
메소드를 선언 시엔 중괄호{} 가 있고, 반드시 메소드 밖에서 선언하고, 메소드를 사용 시엔 중괄호{} 가 없으며, 반드시 메소드 안에서 사용한다.
메소드의 사용 방법
public class Car {
int wheel = 4;
void ride() { // 메소드 선언
System.out.println("달립니다.");
System.out.println("씽씽씽");
}
}
public class Test01 {
public static void main(String[] args) {
Car c = new Car(); // 객체 생성
c.ride(); // 메소드 사용
c.ride();
c.ride();
}
}
생성자
메소드 중에서 객체를 생성할 때 반드시 호출해야 하는 메소드가 있다. 이 메소드는 객체를 생성하면서 객체 변수를 초기화하는 역할을 하는데, 이를 생성자라고 한다.
생성자의 선언
생성자는 클래스명과 이름이 같다. 그런데 이전에 우리가 메소드를 선언하지 않아도 사용할 수 있었던 것은 우리가 직접 선언해주지 않아도 자동으로 기본 생성자가 생성되기 때문이다.
public class Car {
int wheel = 4;
Car() { // 기본 생성자 - 안에는 비어있는 형태로 존재
}
void ride() {
System.out.println("달립니다");
System.out.println("씽씽씽");
}
}
생성자를 통해 객체 변수를 초기화 한다는 것은, 단순히 어떠한 값을 초기화 한다는 뜻이 아니라, 필드와 메소드를 호출하는 등 객체를 사용하기 위해서는 객체 변수가 메모리에 올라가야 하는데, 메모리에 객체 변수를 올려주는 역할을 생성자가 해주고 있다는 뜻이다.
위처럼 각 객체가 가지게 되는 필드와 메소드를 인스턴스 멤버라고 말한다.
그렇다면 정적 멤버인 static은 무엇일까 ?
static이란 모든 객체들이 공유하며 사용하는 하나의 필드와 메소드를 정적 멤버라고 부른다.
정적 멤버의 선언
class Student {
static int age; // 정적 멤버 필드
static void introduce() { // 정적 멤버 메소드
System.out.println("안녕하세요");
}
}
원래 static의 사전적 의미는 '고정된' 이라는 뜻으로, 프로그래밍 언어에서는 '클래스에 고정되었다' 라는 의미로 쓰이고 있고, 쉽게 말해서 객체가 아닌 클래스에 의존적인 요소라고 생각할 수 있다. 따라서 static이 앞에 붙은 멤버들은 객체를 생성하지 않고 바로 사용할 수 있다. 그 이유는 객체를 생성할 때 메모리에 올라가는 것이 아니라, 프로그램을 시작할 떄 메모리에 올라가고 프로그램이 종료될 때 메모리에서 사라지기 때문이다.
static 사용법
public lass Student {
static String schoolName = "코리아 고등학교"; // 정적 필드 선언
static void goToSchool() { // 정적 메소드 선언
System.out.println("학교에 갑니다.");
}
}
public class Test01 {
public static void main(String[] args) {
System.out.println(Student.schoolName(; // 정적 필드 호출
Student.goToSchool(); // 정적 메소드 호출
}
}
// 출력 결과
// 코리아 고등학교
// 학교에 갑니다.
위와 같이 객체마다 가지는 데이터가 아닌 모든 객체가 같은 값을 가져야 할 경우에 정적 멤버를 사용하는 것이 더 효율적이다.