개발 일기

20250908 OOP 3대 concept 본문

TIL

20250908 OOP 3대 concept

종현종현 2025. 9. 8. 21:06

오늘은 자바 OOP의 3대 Concept에 대해서 배웠다.

 

출처: https://velog.io/@pak4184/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-%EC%A0%95%EB%A6%AC-1%EC%9E%A5

 

 

자바의 OOP 3대 concept

1. Encapsulation (은닉화)

정의 : 데이터(변수)와 그 데이터를 조작하는 메서드를 하나의 클래스로 묶고 데이터를 외부로부터 숨겨 내부 구현을 보호하는 것이다.

목적 : 외부에서 객체의 내부 데이터 직접 접근하는 것을 막아 데이터의 일관성과 무결성을 유지하고, 다른 객체의 영향을 받지 않도록 하는 것이다.

 

이 은닉성은 자바에서 접근제어자를 통해 실형시킬 수 있다.

public : 모든 클래스에서 접근 가능

// 파일: A.java
package p1;

public class A {
    public int i = 10;
    
    public int getI() {
    	return i;
    }
}

// 파일: B.java
package p1;

public class B {
	
	public static void main(String[] args) {
		A a = new A();
		System.out.println(a.getI()); // 10 출력
	}
}

// 파일: C.java
package p2;

import p1.A;

public class C {
	
	public static void main(String[] args) {
		A a = new A();
		System.out.println(a.getI()); // 10 출력
	}
}

 

같은 패키지 안에서도 접근 가능하고 다른 패키지에서도 접근이 가능하다.

 

default : 동일 패키지 내의 클래스에서 접근 가능

// 파일: A.java
package p1;

public class A {
    int i = 10;   // 접근제어자 없음 → 같은 패키지에서만 접근 가능

    int getI() {
        return i;
    }
}

// 파일 : B.java
// 같은 패키지
package p1;
public class B {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.i);      // 접근 가능
        System.out.println(a.getI()); // 접근 가능
    }
}

// 파일 : C.java
// 다른 패키지
package p2;
import p1.A;

public class C {
    public static void main(String[] args) {
        A a = new A();
        // System.out.println(a.i);      // 접근 불가
        // System.out.println(a.getI()); // 접근 불가
    }
}

 

같은 패키지는 접근 가능하지만 다른 패키지에서는 접근 불가능하다.

 

private : 자기 자신 클래스에서만 접근 가능

// 파일: A.java
package p1;

public class A {
    private int i = 10;   // 클래스 내부에서만 접근 가능

    private int getI() {
        return i;
    }

    // 외부 접근을 위해 public 메서드 제공
    public int accessI() {
        return i;
    }
}

// 같은 패키지
package p1;
public class B {
    public static void main(String[] args) {
        A a = new A();
        // System.out.println(a.i);      // private라 접근 불가
        // System.out.println(a.getI()); // private라 접근 불가
        System.out.println(a.accessI()); // public 메서드를 통해서만 접근 가능
    }
}

 

protected : 동일 패키지 내의 클래스나 해당 클래스를 상속받은 클래스에서 접근 가능

// 파일: A.java
package p1;

public class A {
    protected int i = 10;   // 같은 패키지 + 상속 관계만 접근 가능

    protected int getI() {
        return i;
    }
}

// 같은 패키지
package p1;
public class B {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.i);      // ✅ 같은 패키지라서 접근 가능
        System.out.println(a.getI()); // ✅ 접근 가능
    }
}

// 다른 패키지
package p2;
import p1.A;

public class C extends A {
    public static void main(String[] args) {
        C c = new C();
        System.out.println(c.i);      // ✅ 상속받았으므로 접근 가능
        System.out.println(c.getI()); // ✅ 접근 가능
    }
}

// 다른 패키지, 상속 X
package p2;
import p1.A;

public class C {
    public static void main(String[] args) {
        A a = new A();
        // System.out.println(a.i);      // ❌ 접근 불가
        // System.out.println(a.getI()); // ❌ 접근 불가
    }
}

 

2. Inheritance (상속)

상속은 자식클래스에서 부모클래스로부터 부모의 자원을 물려받는 것을 말한다.

 

기본 문법

class Parent { /* ... */ }
class Child extends Parent { /* ... */ }

 

예시

package com.ureca;

public class InheritanceTest {
    public static void main(String[] args) {
        // 부모 타입 객체
        A a = new A();
        a.printI();  // A의 메서드 실행

        // 자식 타입 객체
        B b = new B();
        b.printI();  // 오버라이드된 B의 메서드 실행
        b.printJ();  // B에 새로 정의된 메서드 실행
    }
}

class A {
    int i = 10;

    public void printI() {
        System.out.println("A의 i: " + i);
    }
}

class B extends A {
    int j = 1000;

    @Override
    public void printI() {
        System.out.println("B에서 오버라이드된 i: " + i);
    }

    public void printJ() {
        System.out.println("B의 j: " + j);
    }
}

 

B는 A의 필드와 메서드를 물려받는다. 

 

3. Polymorphism (다형성)

다형성은 상속과 깊이 연결된 개념이다. 부모 타입의 참조 변수가 자식 객체를 가리킬 수 있고, 실행 시점에 실제 객체 타입에 맞는 메서드가 호출되는 것을 말한다.

 

// Animal.java
class Animal {
    public void sound() {
        System.out.println("동물이 소리를 냅니다");
    }
}

// Dog.java
class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("멍멍!");
    }
    
    public void fetch() {
        System.out.println("공을 가져옴");
    }
}

// Cat.java
class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("야옹!");
    }
}

// Main.java
public class Main {
    public static void main(String[] args) {
        // 부모 타입 참조 변수로 자식 객체 생성
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        Animal a3 = new Animal();

        a1.sound(); // Dog의 sound() 실행 → "멍멍!"
        a2.sound(); // Cat의 sound() 실행 → "야옹!"
        a3.sound(); // Animal의 sound() 실행 → "동물이 소리를 냅니다"

        // 다형성 배열
        Animal[] animals = {a1, a2, a3};
        for (Animal a : animals) {
            a.sound(); // 각 객체의 실제 타입에 맞는 메서드 호출
        }

        // 다운캐스팅 필요: 자식 전용 메서드 호출
        if (a1 instanceof Dog) {
            Dog d = (Dog) a1;
            d.fetch(); // 정상 실행
        }
    }
}

 

 

'TIL' 카테고리의 다른 글

250910 자바  (0) 2025.09.10
20250909 자바 및 과제  (0) 2025.09.09
20250907 자바스크립트 V8 엔진  (0) 2025.09.07
20250904 TypeScript  (0) 2025.09.04
20250903 TypeScript  (0) 2025.09.04
Comments