클래스는 객체를 만들기 위한 설계도(청사진)이다. 클래스는 객체가 가져야 할 속성(필드) 과 동작(메소드) 를 정의한다. 클래스 자체는 실제로 존재하는 것이 아니고, 이를 기반으로 객체를 만들어야 실제로 동작하거나 데이터를 담을 수 있다.
프로그램의 구조를 논리적으로 나누고, 재사용 가능한 코드 블록을 만들 수 있다. 예를 들어, 여러 회원을 관리하는 시스템이 있다면 Member 라는 클래스를 정의하여 각 회원의 정보를 객체로 다룰 수 있다.
/*
* 클래스 예시
*/
// 회원을 나타내는 클래스
public class Member {
// 필드: 회원의 이름과 이메일
private String name;
private String email;
// 생성자: 객체가 생성될 때 필드 값을 초기화하는 메소드
public Member(String name, String email) {
this.name = name;
this.email = email;
}
// 메소드: 회원의 이름을 반환
public String getName() {
return name;
}
// 메소드: 회원의 이메일을 반환
public String getEmail() {
return email;
}
// 메소드 (동작)
public void introduce() {
System.out.println("My name is " + name + " and I am " + age + " years old.");
}
}
Member 클래스는 name과 email이라는 두 가지 데이터를 가지며, 이 데이터를 처리하는 메소드를 가지고 있다. 실제 데이터를 담고, 행동을 수행하는 것은 이 Member 클래스로 생성된 객체이다.
/*
* 객체 생성 예시
*/
public class Main {
public static void main(String[] args) {
// Member 클래스의 객체 생성
Member member1 = new Member("Alice", "alice@example.com");
// 객체의 메소드를 호출하여 데이터 확인
System.out.println(member1.getName()); // 출력: Alice
System.out.println(member1.getEmail()); // 출력: alice@example.com
}
}
필드는 클래스가 가지는 데이터(속성)을 의미한다. 필드는 객체가 상태를 가지게 해주는 요소로, 객체가 어떤 정보를 가지고 있는지 나타낸다. 예를 들어, 회원의 이름, 이메일 등이 필드가 될 수 있다.
public class Member {
private String name; // 필드: 회원의 이름
private String email; // 필드: 회원의 이메일
}
name과 email은 Member 클래스의 필드로, 각 Member 객체가 이 데이터를 가진다.
메소드는 클래스 안에 정의된 동작, 즉 객체가 할 수 있는 행동을 나타낸다. 예를 들어, 회원이 이메일을 변경하는 동작이나, 동물이 소리를 내는 동작 등을 메소드로 정의할 수 있다.
public class Member {
private String name;
private String email;
// 메소드: 이름을 출력하는 기능
public void printName() {
System.out.println("Name: " + name);
}
}
printName()은 Member 객체가 수행할 수 있는 행동(이름을 출력하는 기능)을 정의한 메소드
현실 세계의 사물이나 개념을 프로그래밍으로 표현한 것이다. 예를 들어, 현실에서의 "자동차"라는 개념은 프로그래밍에서 "자동차 객체"로 표현됩니다. 객체는 상태(속성)와 동작(행동)을 가집니다. 상태는 필드로, 동작은 메소드로 정의한다.
객체 생성이란, 객체는 클래스라는 설계도를 기반으로 만들어지는 실제 데이터나 기능을 가지는 실체이다. 클래스는 그 자체로는 동작하지 않고, 이를 기반으로 객체를 생성하여 그 객체가 동작을 수행한다.
객체를 생성하는 이유는 특정 기능이나 데이터를 다루기 위해서이다. 예를 들어, 회원(Member) 정보를 다루고 싶다면, Member 라는 클래스를 정의하고, 그 클래스의 객체를 생성해 데이터를 저장하거나 조작할 수 있다.
Member 객체는 하나의 회원을 의미하고, 여러 Member 객체를 통해 여러 회원을 관리할 수 있게 된다.// Member 클래스의 객체를 생성
Member member = new Member("Alice", "alice@example.com");
new 키워드를 사용하여 클래스 Member의 객체를 생성한 것이다. 이제 member 객체는 Member 클래스에서 정의한 동작(메소드)을 사용할 수 있다.
/*
* 객체 예시
*/
public class Car {
// 상태 (필드)
String model;
int year;
// 동작 (메소드)
public void drive() {
System.out.println("The car is driving");
}
}
/*---------------------------------------------*/
// 객체 생성 예시
public class Main {
public static void main(String[] args) {
Car myCar = new Car(); // 객체 생성
myCar.model = "Toyota";
myCar.year = 2020;
myCar.drive(); // 동작 호출
}
}
생성자는 객체가 처음 생성될 때 호출되는 메소드, 객체를 초기화하는 역할을 하며, 클래스가 새롭게 인스턴스화될 때, 생성자를 통해 필드에 초기값을 설정하거나 특정 작업을 수행**할 수 있다.
🤚 인스턴스화(Instantiation)? 클래스를 기반으로 실제 객체를 생성하는 과정을 의미한다. 즉, 클래스라는 설계도를 바탕으로 메모리에서 구체적인 형태의 객체를 만드는 것을 말한다.
예를 들어, Person이라는 클래스가 있고, 그 안에 이름과 나이를 저장하는 변수가 있다면, 생성자를 사용해 객체를 생성할 때 이름과 나이를 설정할 수 있다.
public class Person {
private String name;
private int age;
// 생성자: 객체를 만들 때 필드 값을 설정
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Person 객체를 만들 때 이름과 나이를 반드시 설정할 수 있게 하려면 생성자를 사용한다.
/*
* 초기화 작업 수행
*/
public class Person {
private String name;
private int age;
// 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("A new person has been created: " + name + ", Age: " + age);
}
public void introduce() {
System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
}
public static void main(String[] args) {
Person person1 = new Person("Alice", 30); // 객체 생성 시 메시지 출력
person1.introduce();
Person person2 = new Person("Bob", 25); // 또 다른 객체 생성 시 메시지 출력
person2.introduce();
}
}
/*
* 데이터 검증
*/
public class Account {
private String accountNumber;
private double balance;
// 생성자
public Account(String accountNumber, double initialBalance) {
if (initialBalance < 0) {
throw new IllegalArgumentException("Initial balance cannot be negative.");
}
this.accountNumber = accountNumber; // 매개변수 accountNumber를 필드에 할당
this.balance = initialBalance; // 매개변수 initialBalance를 필드 balance에 할당
System.out.println("Account created: " + accountNumber + ", Initial Balance: " + balance);
}
public void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount + ", New Balance: " + balance);
}
public static void main(String[] args) {
Account account1 = new Account("123-456-789", 1000.0);
account1.deposit(500.0);
// 다음 줄은 예외를 발생시킴
// Account account2 = new Account("987-654-321", -500.0);
}
}
/*
* 객체 생성 시 외부 리소스 초기화
*/
public class DatabaseConnection {
private String databaseUrl;
private String username;
private String password;
private boolean connected;
// 생성자
public DatabaseConnection(String databaseUrl, String username, String password) {
this.databaseUrl = databaseUrl;
this.username = username;
this.password = password;
this.connected = connectToDatabase(); // 데이터베이스에 연결
}
private boolean connectToDatabase() {
// 실제 데이터베이스 연결 로직이 들어갈 자리 (여기서는 단순히 true 반환)
System.out.println("Connecting to database at " + databaseUrl);
return true; // 데이터베이스 연결 성공
}
public boolean isConnected() {
return connected;
}
public static void main(String[] args) {
DatabaseConnection dbConnection = new DatabaseConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
System.out.println("Database connected: " + dbConnection.isConnected());
}
}
public class DatabaseConnection {
private String url;
private String username;
// 생성자: 데이터베이스 연결 정보를 받아 초기화
public DatabaseConnection(String url, String username) {
this.url = url;
this.username = username;
}
}
클래스에서 명시적으로 생성자가 없을 때 자동으로 제공되는 생성자이다. 기본 생성자는 매개변수가 없고, 객체 생성 시 별도의 초기화 작업이 필요 없는 경우에 사용된다.
public class Animal {
// 기본 생성자 (자동으로 제공됨)
}
// 생성된 객체
Animal a = new Animal(); // 기본 생성자로 객체 생성
객체를 만들 때 원하는 값을 전달하여 필드를 초기화할 때 사용된다.
Person p = new Person("Alice", 25); // "Alice"와 25를 전달하여 필드 초기화
✅ 생성자 내에서 매개변수를 사용하여 필드를 초기화하거나, 매개변수와는 별도로 메소드를 호출하여 다른 필드를 초기화할 수 있다. 이 과정에서 매개변수를 사용하는 것과 메소드를 호출하여 값을 설정하는 것은 모두 가능하다.
public class User {
// 필드
private String username;
private String password;
private boolean isActive;
// 생성자
public User(String username, String password) {
this.username = username; // 매개변수를 사용하여 필드 초기화
this.password = password; // 매개변수를 사용하여 필드 초기화
this.isActive = checkUserStatus(); // 메소드를 호출하여 필드 초기화
}
// 사용자 상태를 확인하는 메소드
private boolean checkUserStatus() {
// 실제 사용자 상태 확인 로직이 들어갈 자리
return true; // 예시로 항상 활성화 상태 반환
}
public void displayInfo() {
System.out.println("Username: " + username);
System.out.println("Active: " + isActive);
}
public static void main(String[] args) {
User user = new User("john_doe", "securePassword123");
user.displayInfo();
}
}
📝 전체적으로 정리하자면 …
클래스는 객체의 설계도로서, 객체가 가져야 할 속성(필드)과 동작(메소드)을 정의한다. 클래스는 여러 개의 필드와 메소드를 가질 수 있으며, 각 필드는 객체의 상태를 나타낸다. 메소드는 객체가 수행할 수 있는 작업이나 기능을 정의한다.
클래스 (Class) : 특정한 데이터 구조를 정의하며, 이 구조를 기반으로 객체를 생성할 수 있다. 클래스는 객체의 필드와 메소드를 포함한다.
필드 (Field) : 클래스의 속성을 나타내며, 객체의 상태를 저장하는 변수이다. 예를 들어, Car 클래스의 필드는 color와 model이 될 수 있다.
메소드 (Method) : 객체의 동작을 정의하는 함수이다. 클래스 내부에 정의되며, 객체가 수행할 수 있는 작업을 나타낸다. 예를 들어, Car 클래스는 drive()와 stop() 메소드를 가질 수 있다.
생성자 (Constructor) : 객체가 생성될 때 호출되는 특별한 메소드로, 주로 객체의 초기 상태를 설정하는 데 사용된다. 생성자는 클래스 이름과 동일하며, 매개변수를 통해 필드를 초기화할 수 있다.
객체 (Object) : 클래스를 기반으로 생성된 실체로, 클래스에서 정의된 필드와 메소드를 가지고 있다. 객체를 생성하기 위해서는 new 키워드를 사용하여 클래스를 인스턴스화한다.
public class Car {
// 필드
private String color;
private String model;
// 생성자
public Car(String color, String model) {
this.color = color; // 매개변수를 사용하여 필드를 초기화
this.model = model;
}
// 메소드
public void drive() {
System.out.println(model + " is driving.");
}
public void stop() {
System.out.println(model + " has stopped.");
}
public static void main(String[] args) {
// 객체 생성
Car myCar = new Car("Red", "Toyota"); // 생성자를 통해 객체를 생성
myCar.drive(); // 메소드 호출
myCar.stop(); // 메소드 호출
}
}
Car라는 클래스는 두 개의 필드(color, model), 두 개의 메소드(drive(), stop()), 그리고 하나의 생성자를 가지고 있다. Car 클래스를 기반으로 myCar라는 객체를 생성할 때 생성자가 호출되어 color와 model 속성이 초기화된다. 이후 myCar 객체를 통해 drive()와 stop() 메소드를 호출하여 해당 기능을 수행할 수 있다.
이처럼 클래스, 필드, 메소드, 객체, 생성자는 객체지향 프로그래밍(OOP)에서 매우 중요한 개념으로, 프로그램의 구조를 더 체계적이고 유연하게 만들어준다. 이들은 코드의 재사용성을 높이고, 유지보수를 용이하게 하며, 더 나은 구조를 갖춘 소프트웨어를 개발하는 데 기여한다.