본문 바로가기

Web Development/Java

[Java] 객체지향개념5

제어자(modifier)?

1. 제어자란

-클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여

▶ 접근제어자: public, protected, (default), private

▶ 그외: static, final, abstract, native, trasient, synchronized, volatile, strictfp

-하나의 대상에 여러개의 제어자를 조합해서 사용할 수 있으나 접근제어자는 단 하나만 사용 가능

 

2. static - 클래스의, 공통적인

static이 사용될 수 있는 곳: 멤버변수, 메서드, 초기화 블럭

▶ 멤버변수에 사용될 때

     -모든 인스턴스에 공통적으로 사용되는 클래스변수가 됨

     -클래스변수는 인스턴스를 생성하지 않고도 사용 가능

     -클래스가 메모리에 로드될 때 생성됨

▶ 메서드에 사용될 때

     -인스턴스를 사용하지 않고도 호출이 가능한 static 메서드가 됨

     -static 메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 없음

 

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

final이 사용될 수 있는 곳: 클래스, 메서드, 멤버변수, 지역변수

▶ 클래스에 사용될 때

     -변경될 수 없는 클래스, 확장될 수 없는 클래스가 됨

     -final로 지정된 클래스는 다른 클래스의 조상이 될 수 없음 (상속계층도의 마지막이라는 뜻)

▶ 메서드에 사용될 때

     -변경될 수 없는 메서드가 됨

     -final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없음

▶ 멤버변수/지역변수에 사용될 때

     -변수 앞에 final이 붙으면 값을 변경할 수 없는 상수가 됨

 

4. 생성자를 이용한 final 멤버변수 초기화

-final이 붙은 변수는 상수이므로 보통은 선언과 동시에 초기화

 △ 인스턴스 변수의 경우 생성자에서 초기화 할 수 있음

 

class Card {
	final int NUMBER;
	final String KIND;
	static int width = 100;
	static int height = 250;
	
	Card(String kind, int num) {
		KIND = kind;
		NUMBER = num;
	}
}

 

한번 값이 지정되면 바뀌지 않아야 하는 변수이므로 final 변수이지만 생성자에서 초기화

 

5.abstract - 추상의, 미완성의

abstract가 사용될 수 있는 곳: 클래스, 메서드

▶ 클래스에 사용될 때

     -클래스 내에 추상메서드가 선언되어 있음을 의미함

메서드에 사용될 때

     -선언부만 작성하고 구현부는 작성하지 않은 미완성 메서드임을 의미함

-> 추상메서드는 상속을 통해서 자손 클래스에서 완성되어야만 인스턴스 생성 가능

 

6. 접근 제어자(access modifier)

: 멤버 또는 클래스에 사용되어 외부로부터의 접근을 제한함

-접근 제어자가 사용될 수 있는 곳: 클래스, 멤버변수, 메서드, 생성자

 

▶ private: 같은 클래스 내에서만 접근이 가능

▶ (default): 같은 패키지 내에서만 접근이 가능

▶ protected: 같은 패키지 내에서, 다른 패키지의 자손클래스에서 접근이 가능

▶ public: 접근 제한 없음

 

7. 접근제어자를 이용한 캡슐화

접근제어자를 사용하는 이유?

-외부로부터 데이터를 보호하기 위해서

-외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서

 

접근제어자를 이용해서 멤버변수들은 private으로 지정해 내부에 감추고 메서드들은 public으로 지정해 외부에 노출시킴으로써

같은 클래스에 정의된 멤버들끼리는 서로 자유롭게 접근하고 외부에서는 메서드를 통해서만 멤버변수에 접근할 수 있는 구조로 만듦

 

8. 생성자의 접근제어자

-일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치함

-생성자에 접근 제어자를 사용함으로써 인스턴스의 생성을 제한할 수 있음

일반적인 경우에는 연산자 new를 통해서 인스턴스를 생성하는데,

생성자의 접근제어자를 private으로 하면 연산자 new를 통해서 인스턴스를 생성할 수 없음

대신 내부적으로 객체를 생성해서 접근제어자를 private으로 해서 감추고 public 메서드를 통해 생성된 객체에 접근함

+생성자의 접근제어자가 private인 경우에는 다른 클래스의 조상이 될 수 없음.

  자손 클래스의 인스턴스를 생성하면 조상의 생성자를 호출하는데 조상의 생성자가 private이라 호출할 수 없기 때문

  -> 클래스 앞에 final을 붙여줘서 상속을 통해 확장할 수 없는 클래스라는 것을 알려주는 것이 좋음

 

9. 제어자의 조합

1) 메서드에 static과 abstract를 함께 사용할 수 없다.

   : static 메서드는 몸통(구현부)이 있는 메서드에만 사용 가능

2) 클래스에 abstract와 final을 동시에 사용할 수 없다.

   : 클래스에 사용되는 final은 클래스를 확장 할 수 없다는 의미, abstract는 상속을 통해서 완성되어야 한다는 의미

     -> 서로 모순됨

3) abstract의 접근제어자가 private일 수 없다.

   : abstract 메서드는 자손클래스에서 구현해주어야 하는데 접근제어자가 private이면 자손클래스에서 접근할 수 없음

4) 메서드에 private과 final을 같이 사용할 필요는 없다.

   : 접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문에 둘 중 하나만 써도 충분함

 

 

다형성?

1. 다형성

-여러 가지 형태를 가질 수 있는 능력

-하나의 참조변수로 여러 타입의 객체를 참조할 수 있는 것

  -> 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있는 것

 

자기 자신의 참조변수로 객체를 다루는 것과 조상타입의 참조변수로 객체를 다루는 것의 차이

: 사용할 수 있는 멤버의 개수

 

-조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있지만,

 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수 는 없음

 : 리모콘에 정의된 기능이 실제 제품의 기능보다 많아서는 안됨

 

2. 참조변수의 형변환

-서로 상속관계에 있는 타입간의 형변환만 가능

▶ 자손타입 -> 조상타입 (up-casting) : 형변환 생략가능

▶ 조상타입 -> 자손타입 (down-casting) : 형변환 생략불가

실제 인스턴스 멤버의 개수가 리모콘의 기능 개수보다 많아야 형변환 가능

-> 결국 중요한건 실제 인스턴스

 

3. instanceof 연산자

-참조변수가 참조하는 인스턴스의 실제 타입을 체크하는데 사용 (형변환이 가능한지 알려줌)

-이항연산자이고, 피연산자는 참조형 변수와 타입. 연산결과는 true, false.

-instanceof의 연산결과가 true이면 해당 타입으로 형변환이 가능함

 

4. 매개변수의 다형성

-참조형 매개변수는 메서드 호출시 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있음

 

void buy(Product p) {
	money -= p.price;
	bonusPoint += p.bonusPoint;
}

 

Product 클래스는 모든 제품 클래스의 조상이라서 Tv 인스턴스, Computer 인스턴스, Audio 인스턴스 모두 참조 가능

-> 새로운 제품 클래스가 추가되어도 새로운 buy 메서드를 추가할 필요가 없음

 

5. 여러 종류의 객체를 하나의 배열로 다루기

: 조상타입의 배열에 자손들의 객체를 담을 수 있음

 

Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();

 

 

'Web Development > Java' 카테고리의 다른 글

[Java] 객체지향개념4  (1) 2024.01.16
[Java] 캡슐화, TDA 원칙  (2) 2024.01.13
[Java] 객체지향개념3  (1) 2024.01.09
[Java] 객체지향개념2  (1) 2024.01.09
[Java] 객체지향개념1  (1) 2024.01.09