내일배움캠프 6일차 TIL - 제어자, 캡슐화, 다형성

iy·2023년 12월 26일

TIL

목록 보기
5/37

제어자(modifier)

  • 클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미 부여
접근 제어자그 외
public
protected
(default)
private
static
final
abstract
native
trandient
synchronized
volatile
strictfp
  • 하나의 대상에 여러 제어자를 같이 사용가능(접근 제어자는 하나만)
public class ModifierTest {
    public static final int WIDTH = 200; // 여러 제어자를 사용할 때 접근 제어자는 제일 왼쪽에 명시해준다.
    ...
}

static - 클래스의, 공통적인

  • 멤버변수
    • 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 된다.
    • 클래스 변수는 인스턴스를 생성하지 않고도 사용 가능하다.
    • 클래스가 메모리에 로드될 때 생성된다.
  • 메서드
    • 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다.
    • static 메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 있다.
class StaticTest {
    // 간단 초기화
    static int width = 200; // 클래스 변수(static 변수)
    static int height = 120; // 클래스 변수(static 변수)

    static { // 클래스 초기화 블럭
        // static 변수의 복잡한 초기화 수행
    }

    static int max(int a, int b){ // 클래스 메서드(static 메서드)
        return a > b ? a : b;
    }
}

final - 마지막의, 변경될 수 없는

  • 클래스
    • 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
      그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
  • 메서드
    • 변경될 수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
  • 멤버변수,지역변수
    • 변수 앞에서 final이 붙으면, 값을 변경할 수 없는 상수가 된다.
final class FinalTest { // 조상이 될 수 없는 클래스 
    final int MAX_SIZE = 10; // 값을 변경할 수 없는 멤버변수(상수) (이땐 일반적으로 변수 설정을 대문자로 해줌)

    final void getMaxSize() { // 오버라이딩할 수 없는 메서드(변경 불가)
        final int LV = MAX_SIZE; // 값을 변경할 수 없는 지역변수(상수)
        retuen MAX_SIZE;
    } 
}

abstract - 추상의, 미완성의

  • 클래스
    • 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.
  • 메서드
    • 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다.
abstract class AbstractTest { // 추상클래스(추상 메서드를 포함한 메서드)
    abstract void move(); // 추상메서드(구현부가 없는 메서드)
} // 미완성 클래스, 미완성 메서드 
AbstractTest a = new AbstractTest(); // 에러 : 미완성인 추상클래스의 인스턴스 생성불가

접근 제어자(access modifier)

  • private : 같은 클래스 내에서만 접근이 가능하다.
  • (default) : 같은 패키지 내에서만 접근이 가능하다.
  • protected : 같은 패키지 내에서 접근 가능하고 다른 패키지의 자손 클래스에서 접근이 가능하다.
  • public : 접근 제한이 전혀 없다.

public > protected > (default) > private


캡슐화와 접근 제어자

  • 접근 제어자를 사용하는 이유
    • 외부로부터 데이터를 보호하기 위해
    • 외부에는 불필요하고 내부적으로만 사용되는 부분을 감추기 위해서
public class Time {
    public int hour;
    public int minute;
    public int second;
}

이렇게 접근 제한 없이 클래스를 생성하면

Time t = new Time();
t.hour = 25; // 멤버변수에 직접 접근

외부에서 멤버변수에 직접 접근할 수 있기 때문에 데이터 보안에 취약해진다.

public class Time {
    // 접근 제어자를 private으로 하여 외부에서 직접 접근하지 못하도록 한다.
    private int hour;
    private int minute;
    private int second;

    public int getHour() { return hour; }
    public void setHour(int hour) {
        if(hour < 0 || hour > 23) return;
        this.hour = hour;
    }
    // 메서드는 public 이라서 메서드를 통해서 iv에 간접 접근이 가능함
    // 외부로부터 직접적인 접근을 막는게 중요*****
}

내부에서만 메서드 사용을 할 때 private으로 하면 후에 코드 수정을 했을 때 class안에서만 변경 후 테스트를 하면 됨 (테스트해야 할 부분이 많이 줄어듬)

다형성(polymoriphism)

  • 여러 가지 형태를 가질 수 있는 능력
    • 조상 타입 참조 변수로 자손 타입 객체를 다루는 것
class Tv{
    boolean power; //전원상태
    int channel; //채널

    void power() { power != power; }
    void channelUp(){ ++channel; }
    void channelDown(){ --channel; }
}

class SmartTv extends Tv {
    String text; //캡션(자막)을 보여주기 위한 문자열
    void caption() {/*내용생략*/}
}
Tv t = new Tv();
SmartTv s = new SmartTv();

원래는 이렇게 타입이 일치해야 하는데 다형성의 특징에 의해

Tv t = new SmartTv(); //타입 불일치

타입이 불일치 해도 가능

  • 객체와 참조변수의 타입이 일치할 때와 일치하지 않을 때의 차이는?
SmartTv s = new SmartTv(); //참조 변수와 인스턴스의 타입이 일치 - 타입이 일치하면 모든 기능 사용가능함
// 리모컨에 기능 수 만큼 버튼이 있다고 생각하면 됨
Tv t = new SmartTv(); //조상 타입 참조변수로 자손 타입 인스턴스 참조(타입 불일치) -기능을 가지고 있지만 사용은 일치하는 타입 기능들만 사용 가능하다고 생각하면 됨
// 리모컨에 기능은 다 들어있지만 일치하지 않은 타입들은 버튼이 만들어져 있지 않아서 사용이 불가능하다고 생각하면 됨
  • 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.
Tv t = new SmartTv(); //OK 허용.
// 기능이 있어서 사용 못 하는 건 가능
SmartTv s = new Tv(); //에러 허용안됨
// 이 경우는 기능은 부족한데 더 많은 버튼들이 만들어져 있다고 생각하면 됨
// 없는 기능을 버튼으로 만들어놓는 건 안됨

👀
어떤 프로그램을 만드는지에 따라 어떤 접근제어자를 사용할지 잘 고민해 봐야겠다.
오늘 들었던 강의 중 다형성에 대한 강조를 많이 들었는데 정리한 내용들, 예제에 표시해놓은 주석을 꼼꼼히 읽고 다시 한번 정리해둬야겠다.

📑 참고
1. https://youtu.be/Hmu7YH8AXmI?si=8CwUA3iBmV6RLnxI
2. https://youtu.be/Qm08p4Vk2sw?si=C9T5NCp1QKQsjofI
3. https://youtu.be/3NuVD8eOMfc?si=4V-jlN4vyk6iA5Ki
4. https://youtu.be/fw7Nm_li0pE?si=TJm0jjRUNtWEXDSr

0개의 댓글