이번 글에서는 Java 패키지와 자바에서 자주 사용하는 객체지향 프로그래밍의 핵심 개념들에 대해 알아보겠습니다.
패키지 (Package)
패키지는 자바에서 클래스들을 체계적으로 관리하기 위한 폴더 개념입니다. 패키지를 사용하면 클래스들이 이름이 충돌하는 것을 방지하고, 코드의 가독성을 높여줍니다. 패키지는 소문자로 작성해야 하며, 최상위 패키지의 이름은 java
로 시작할 수 없습니다.
패키지를 불러오는 방법은 import
키워드를 사용하는 것이며, 특정 패키지의 모든 클래스를 사용하고 싶다면 *
를 붙여 사용합니다.
import java.util.*; // java.util 패키지의 모든 클래스 사용
패키지는 서로 다른 패키지의 클래스들을 효율적으로 관리할 수 있게 해줍니다.
기본타입(Primitive Type) vs 참조타입(Reference Type)
자바에서 기본 타입(Primitive Type)은 정수, 실수, 문자, 논리값과 같은 데이터를 저장하는 타입입니다. 예를 들면 int
, char
, double
, boolean
등이 있습니다.
참조 타입(Reference Type)은 배열, 클래스, 인터페이스 등의 객체의 주소값을 저장하는 타입을 말합니다. 이들은 기본 타입과 달리 힙(heap) 메모리에 저장된 객체의 주소값을 참조합니다.
- 기본 타입: 변수에 실제 값이 저장됩니다.
- 참조 타입: 변수에 객체의 주소값이 저장됩니다.
특히 문자열은 참조 타입이기 때문에 ==
비교가 아닌 equals()
메서드를 사용하여 값을 비교해야 합니다.
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1.equals(str2)); // true
객체지향 프로그래밍 주요 개념
1. 상속(Inheritance)
상속은 기존 클래스를 확장하여 새로운 클래스를 만드는 방법입니다. 상속을 사용하면 기존 코드를 재사용할 수 있어 불필요한 코드 중복을 줄일 수 있습니다.
- 자식 클래스는
extends
키워드를 통해 부모 클래스를 상속받습니다. - 모든 자바 클래스는 자동으로
Object
클래스를 상속받습니다.
class Animal {
void sound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Bark");
}
}
2. 메서드 재정의(Overriding)
메서드 재정의(Overriding)는 부모 클래스에서 정의된 메서드를 자식 클래스에서 다시 정의하여 사용하는 것입니다. 부모 클래스의 메서드와 동일한 이름, 반환형, 매개변수를 가져야 하며, 재정의된 메서드가 호출됩니다.
class Animal {
void sound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
3. 메서드 중복(Overloading)
메서드 중복(Overloading)은 동일한 이름의 메서드를 매개변수의 타입이나 개수를 달리하여 여러 개 선언하는 것입니다.
class MathOperation {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
4. this와 super
this
는 현재 객체의 참조를 의미합니다. 클래스 내에서 멤버 변수나 다른 생성자를 참조할 때 사용됩니다.
public class Person {
String name;
Person(String name) {
this.name = name; // this는 현재 객체의 멤버 변수 참조
}
}
super
는 부모 클래스의 멤버를 참조할 때 사용됩니다. 특히super()
는 부모 클래스의 생성자를 호출하는 데 사용됩니다.
class Animal {
Animal() {
System.out.println("Animal Constructor");
}
}
class Dog extends Animal {
Dog() {
super(); // 부모 생성자 호출
System.out.println("Dog Constructor");
}
}
접근 제어자 (Access Modifier)
자바에서 접근 제어자는 클래스, 메서드, 변수의 접근 범위를 제어하는 데 사용됩니다.
public
: 모든 클래스에서 접근 가능.protected
: 같은 패키지 또는 상속 관계에 있는 클래스에서 접근 가능.default
: 같은 패키지 내에서만 접근 가능.private
: 같은 클래스 내에서만 접근 가능.
class MyClass {
public int publicVar;
protected int protectedVar;
int defaultVar; // 접근 제어자 없음 (default)
private int privateVar;
}
캡슐화 (Encapsulation)
캡슐화는 클래스의 멤버 변수에 직접 접근하지 못하게 하고, 공개된 메서드를 통해서만 접근하도록 하는 기술입니다. 이를 통해 데이터의 유효성을 검증하거나 보호할 수 있습니다.
getter
: 변수의 값을 가져오는 메서드.setter
: 변수의 값을 설정하는 메서드.
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
다형성 (Polymorphism)
다형성은 하나의 객체가 여러 가지 형태를 가질 수 있다는 개념입니다. 부모 타입으로 자식 객체를 참조할 수 있으며, 부모 클래스의 메서드만 사용할 수 있지만, 자식 클래스에서 재정의된 메서드가 실행됩니다.
class Animal {
void sound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
Animal animal = new Dog();
animal.sound(); // "Bark"
정적(Static) 키워드
static
키워드는 클래스 변수와 메서드에 사용되며, 객체를 생성하지 않고도 클래스 이름으로 접근할 수 있습니다. 또한, 모든 객체가 static
변수와 메서드를 공유하게 됩니다.
class MyClass {
static int staticVar = 10;
static void staticMethod() {
System.out.println("Static method");
}
}
싱글톤 패턴(Singleton Pattern)
싱글톤 패턴(Singleton Pattern)은 인스턴스를 하나만 생성하고, 그 인스턴스에 전역적으로 접근할 수 있도록 하는 디자인 패턴입니다. 이 패턴은 getInstance()
메서드를 통해 객체에 접근합니다.
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {} // private 생성자
public static Singleton getInstance() {
return instance;
}
}
final 키워드
final
클래스: 상속 불가.final
메서드: 재정의 불가.final
변수: 값을 변경할 수 없는 상수.
final class FinalClass { } // 상속 불가
추상 클래스 (Abstract Class)
추상 클래스는 객체를 생성할 수 없고, 자식 클래스가 반드시 재정의해야 하는 추상 메서드를 가질 수 있습니다.
abstract class Animal {
abstract void sound(); // 추상 메서드
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
인터페이스 (Interface)
인터페이스는 클래스 간의 상호 작용을 정의하는 메서드 명세서입니다. 인터페이스는 다중 상속이 가능하며, 이를 통해 다형성을 구현할 수 있습니다.
interface Animal {
void sound();
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
'🗄️ Backend > Java' 카테고리의 다른 글
Java API : 주요 클래스 및 I/O 스트림 사용법 (3) | 2024.10.10 |
---|---|
JAVA 예외 처리(Exception Handling)와 가비지 컬렉션 (Garbage Collection) (1) | 2024.10.10 |
JAVA 메서드와 객체지향 프로그래밍 (0) | 2024.10.10 |
JAVA 배열과 제어문(반복문) 정리 (0) | 2024.10.10 |
JAVA 연산자 총정리: 개념부터 예제까지! (3) | 2024.10.10 |