Java Study
TIL - 객체 지향 프로그래밍 (2)
초코너무조코
2024. 12. 30. 11:38
728x90
자바 상속, 제어자, 다형성, 추상 클래스, 인터페이스, 내부 클래스 공부 로그
1. 상속(Inheritance)
- 개념: 부모 클래스의 필드와 메서드를 자식 클래스가 물려받는 것.
- 키워드: extends
- 특징:
- 코드 재사용성을 높임.
- 부모 클래스의 멤버를 자식 클래스에서 직접 사용하거나 오버라이딩 가능.
예제:
// 부모 클래스
class Animal {
String name;
void eat() {
System.out.println(name + " is eating.");
}
}
// 자식 클래스
class Dog extends Animal {
void bark() {
System.out.println(name + " is barking.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.name = "Buddy";
myDog.eat(); // 부모 클래스의 메서드 사용
myDog.bark(); // 자식 클래스의 메서드 사용
}
}
2. 제어자(Access Modifiers)
- 클래스, 필드, 메서드의 접근 범위를 지정.
- 종류:
- public: 모든 클래스에서 접근 가능.
- protected: 같은 패키지 및 상속받은 클래스에서 접근 가능.
- default(패키지-프라이빗): 같은 패키지 내에서만 접근 가능.
- private: 해당 클래스 내에서만 접근 가능.
예제:
class Test {
public int publicVar = 1;
protected int protectedVar = 2;
int defaultVar = 3;
private int privateVar = 4;
void display() {
System.out.println("Private Variable: " + privateVar);
}
}
public class Main {
public static void main(String[] args) {
Test obj = new Test();
System.out.println("Public Variable: " + obj.publicVar);
System.out.println("Protected Variable: " + obj.protectedVar);
System.out.println("Default Variable: " + obj.defaultVar);
// System.out.println(obj.privateVar); // 오류 발생 (private 접근 불가)
}
}
3. 다형성(Polymorphism)
- 개념: 하나의 참조 변수가 여러 객체의 메서드를 참조할 수 있는 능력.
- 종류:
- 컴파일타임 다형성: 메서드 오버로딩.
1.1 컴파일타임 다형성 (Compile-time Polymorphism)- 메서드 오버로딩(Method Overloading)을 통해 구현됩니다.
- 정의: 같은 이름의 메서드를 여러 개 정의하되, 매개변수의 개수, 타입, 순서를 다르게 작성하여 컴파일 시점에 어떤 메서드를 호출할지 결정합니다.
- 특징:
- 컴파일 시점에 메서드 호출이 결정됨.
- 반환값만 다르게 정의하면 오버로딩이 성립되지 않음.
1.2 런타임 다형성 (Runtime Polymorphism)- 메서드 오버라이딩(Method Overriding)과 업캐스팅(Upcasting)을 통해 구현됩니다.
- 정의: 부모 클래스의 메서드를 자식 클래스에서 재정의하여, 실행 시점에 어떤 메서드가 호출될지 결정됩니다.
- 특징:
- 실행 시점에 동작이 결정됨.
- 상속과 업캐스팅을 활용.
- 부모 클래스의 참조 변수를 사용해 자식 클래스 객체를 참조(업캐스팅).
- 부모 타입의 참조 변수로 여러 자식 클래스 객체를 다룰 수 있음.
- 동적 바인딩(Dynamic Binding)을 통해 실행 시점에 적합한 메서드를 호출.
2. implements 키워드와 다중 상속
2.1 implements로 인터페이스 다중 구현 가능
- 자바는 클래스의 다중 상속을 지원하지 않지만, 인터페이스는 다중 구현이 가능합니다.
- implements 키워드를 사용하여 여러 인터페이스를 한 클래스에서 구현할 수 있습니다.
3. 요약 및 학습 포인트
- 다형성:
- 컴파일타임 다형성: 메서드 오버로딩을 통해 구현. 호출할 메서드가 컴파일 시점에 결정됨.
- 런타임 다형성: 메서드 오버라이딩과 업캐스팅을 통해 구현. 실행 시점에 호출할 메서드가 결정됨.
- implements와 상속:
- 클래스는 다른 클래스를 하나만 상속(extends)할 수 있음.
- 클래스는 여러 인터페이스를 implements를 통해 다중 구현 가능.
- 클래스 상속과 인터페이스 구현을 함께 사용할 수 있음.
예제: 오버라이딩과 업캐스팅:
class Animal {
void sound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog(); // 업캐스팅
myAnimal.sound(); // Dog 클래스의 sound() 호출
}
}
4. 추상 클래스(Abstract Class)
- 개념: 객체를 생성할 수 없는 클래스. 공통 기능 정의와 함께 서브클래스에서 구현해야 할 메서드를 선언.
- 키워드: abstract
특징:
- 추상 메서드를 포함할 수 있다.
- 추상 메서드는 선언만 하고 구현은 서브클래스에서 담당.
예제:
abstract class Animal {
abstract void sound(); // 추상 메서드
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.sound();
myDog.eat();
}
}
5. 인터페이스(Interface)
- 개념: 클래스가 구현해야 하는 메서드의 청사진. 다중 상속을 지원하기 위해 사용.
- 키워드: interface
특징:
- 모든 메서드는 기본적으로 public abstract.
- 필드는 public static final.
- 한 클래스는 여러 인터페이스를 구현할 수 있다.
예제:
interface Animal {
void sound();
}
interface Pet {
void play();
}
class Dog implements Animal, Pet {
@Override
public void sound() {
System.out.println("Bark");
}
@Override
public void play() {
System.out.println("Playing fetch");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.sound();
myDog.play();
}
}
6. 내부 클래스(Inner Class)
- 개념: 클래스 내에 정의된 또 다른 클래스. 외부 클래스와 밀접한 관계를 가짐.
- 종류:
- 인스턴스 내부 클래스: 외부 클래스 객체를 통해 접근.
- 정적 내부 클래스: 외부 클래스와 독립적으로 접근 가능.
- 로컬 내부 클래스: 메서드 내에서 정의.
- 익명 내부 클래스: 일회성 클래스 정의와 객체 생성.
예제:
class Outer {
private String message = "Hello from Outer";
class Inner {
void display() {
System.out.println(message);
}
}
}
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 인스턴스 내부 클래스 접근
inner.display();
}
}
7. 배운 점
- 상속의 강력함: 부모 클래스의 코드 재사용 및 확장.
- 제어자의 중요성: 클래스 설계 시 데이터 캡슐화를 위한 접근 제한 설정.
- 다형성의 유용성: 코드 유연성과 확장성 향상.
- 추상 클래스와 인터페이스 비교: 추상 클래스는 공통 기능 구현을 포함하고, 인터페이스는 규격화에 초점.
- 내부 클래스 활용: 외부 클래스와 밀접하게 연결된 로직 캡슐화.
8. 추가 학습 계획
- 람다식과 함수형 인터페이스를 내부 클래스와 비교.
- 다형성 활용 예제와 디자인 패턴 적용.
- 제어자와 함께 패키지 구조를 고려한 설계 연습.
이번 학습을 통해 자바 객체지향 프로그래밍의 핵심 개념을 더 깊이 이해하고 실습으로 체화할 수 있었다. 앞으로 프로젝트에 이를 적용하여 더욱 발전할 계획이닷!
728x90