JAN's History
자바의 정석 - CH7 객체지향 언어 2 - 2 본문
1. 제어자
- 클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미 부여
- 하나의 대상에 여러 제어자를 같이 사용 가능(접근 제어자는 하나만)
1-2. static : 클래스의, 공통적인
클래스 변수 : 인스턴스 변수 앞에 static을 붙이면 된다.
인스턴스 변수는 각각 고유한 값을 가지지만 클래스 변수는 모든 인스턴스가 공통된 값을 공유한다.
Ex) 카드의 모양이 모두 같다면 무늬와 높이가 클래스 변수가 될 수 있다.
static의 사용방법 3가지
1. 인스턴스변수(iv)앞에 static을 사용하면 클래스 변수(cv)를 만들 수 있다. (간단한 초기화)
2. static{복잡한 초기화 기능}을 사용하면 클래스 초기화 블럭이 만들어진다.
3. static 뒤에 메서드를 사용하면 static 메서드가 된다. 인스턴스 변수(iv)와 인스턴스 메서드는 사용불가하다.
=> iv 멤버들은 객체를 만들고 나서 사용해야하기 때문! static은 객체 생성없이 사용가능하다.
1-3 final : 마지막의 변경될 수 없는
변경될 수 없는 클래스이므로 마지막 클래스라고 할 수 있다.(부모가 될 수 없음)
Ex) String, Math ..
final의 사용법 3가지
1. class 앞에 붙으면 조상(=부모)이 될 수 없다.
2. 메서드 앞에 붙으면 오버라이딩(=조상 메서드를 덮어쓰는 것)이 될 수 없다.
3. 지역변수, 멤버변수 앞에 붙으면 값을 변경할 수 없는 상수가 된다.
=> final이 붙은 변수는 상수이므로 보통은 선언과 초기화를 동시에 하지만, 인스턴스변수의 경우 생성자에서 초기화 할 수 있다.
1-4 abstract : 추상의, 미완성의
몸통{}이 없는 클래스는 추상메서드이다. = 미완성 메서드(선언부만 있고 구현부가 없다)
추상메서드를 포함한 클래스가 추상클래스이다.
인스턴스 생성 불가.
1-5 접근제어자
4개 중 1개만 사용이 가능하다.
public은 class 앞에만 붙일 수 있고, 멤버에는 public, protected, (default), private 모두 붙일 수 있다.
private은 같은 클래스 내에서만 사용가능하기 때문에 다른 클래스에서는 에러가 난다.
private, defalut 둘다 에러가 난다.
default는 같은 패키지 내에서만 사용 가능하기 때문.
private, defalut, protected 셋다 에러가 난다.
MyChild는 자손이라서 protected가 사용 가능했지만 MyparentTest2는 상관 없는 패키지라서 에러.
1-6 캡슐화 : 접근 제어자를 이용하는 것.
접근 제어자를 사용하는 이유
- 외부로부터 데이터를 보호하기 위해서
- 외부에서는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해
public 메서드를 이용해 간접접근을 가능하게하지만,
if문으로 0 이하거나 23 이상인 hour값만 거르게 되어 return값을 통해 외부접근을 막는다.
=> 위에 t.hour = 25;처럼 직접 접근을 막아 데이터를 보호한다. (엉뚱한 값이 되지 않도록 막음)
hour < 0 || hour > 23 부분을 드래그 후 alt + shift + M을 누르면 메서드화 가능!
접근제어자는 최소화 할 수록 좋다.
2. 다형성
- 여러 가지 형태를 가질 수 있는 능력
- 조상 타입 참조 변수로 자손 타입 객체를 다루는 것
원래는 위처럼 타입이 일치한 상태에서 참조변수를 갖는데
Tv(조상) t = new CaptionTv(자손)(); 처럼 타입이 불일치한 상태에서 참조변수를 갖는 것!
- 객체와 참조변수 타입이 일치할 때와 일치하지 않을 때의 차이?
1. SmartTv s = new SmartTv();
: 참조변수와 인스터스의 타입이 일치하는 경우
=> SmartTv에 멤버(=기능)가 7개고, SmartTv리모콘도 7개의 버튼이 있어서 모두 사용할 수 있다.
즉, 모든 기능을 사용할 수 있다.
2. Tv t = new SmartTv();
: 조상 타입 참조변수로 자손 타입 인스턴스 참조하는 경우
=> Tv리모콘의 버튼이 5개고, SmartTv의 멤버(=기능)가 7개라서 나머지 2개의 멤버는 사용할 수 없다.
즉, 일부만 사용 가능하다.
(+ 조상이니까 멤버가 같거나 적을 수 밖에 없음)
But 반대의 경우는 안된다.
SmartTv s = new Tv(); 에러!
=> 사용할 수 있는 멤버의 개수가 더 많은데 조금 사용하는 것은 가능하지만,
버튼이 더 많은데 기능이 더 적은 것은 잘못 호출할 수 있기 때문에 에러가 난다.
2-2 참조변수의 형변환 : 사용할 수 있는 멤버의 개수를 조절하는 것
기본형의 형변환 double x => '3.6' - > int x = '3' 처럼 값이 바뀐다.
But 참조변수의 형변환은 주소값, 객체의 값이 바뀌는 것이 아니라 멤버의 개수가 바뀐다.
- 조상 자손 관계의 참조변수는 서로 형변환 가능
car와 FireEngine, Car와 Ambulance도 형변환 가능 But FireEngine<->Ambulance는 형변환 X
1. FireEngine f = new FireEngine(); 은 =일치
2. Car c = f;는 형변환 일치 X => 그래서 조상인 Car 타입으로 형변환하기 위해 (Car) 붙이기.
Car c = f;는 Car에 멤버가 4개라서 FireEngine에 c.water()을 사용할 수 없다.
즉, 참조변수의 형변환을 통해 5개 쓸 수 있는 것을 4개로 줄인 것이다. (리모콘을 변경하는 것!)
3. FireEngine f2 = c; 도 형변환 일치 X => 자손인 FireEngine 타입으로 형변환 (FireEngine) 붙임.
FireEngine은 5개 다 쓸 수 있다.
car.water();는 Car 클래스 안에 water가 없기 때문에 오류
참조변수가 가리키는 실제 객체의 개수가 중요!
그 객체의 멤버 개수가 만약 5개라면 그걸 넘으면 안된다.
그 5개 이내에서 줄이고 늘리는 것은 상관 없다.
fe.water()에서 fe는 water를 가지고 있으니 컴파일은 되지만
위에 FireEngine fe = (FireEngine)c; 에서 형변환 에러가 발생한다.
=> FireEngine은 5개의 멤버를 가지고 있고 Car은 4개의 멤버를 가지고 있어 에러가 발생.
실제 가리키고 있는 멤버의 개수가 4개이므로 그것을 벗어나면 안됨!!
2-3 instanceof 연산자
- 참조 변수의 형변환 가능여부 확인에 사용. 가능하면 true 반환.
1. 확인 : 형변환을 해도 되는지 => intanceof 사용
2. 형변환 진행
void doWork(Car c)에서 new Ambulance()가 들어오면 아래 FireEngine랑 형변환이 안된다.
이럴 때 instanceof 사용!
if (c instanceof FireEngine) = c 가 FireEngine인가 ? => 맞으면 True로 아래 형변환 진행
else if (c instanceof Ambulance) // c가 Ambulance 인 경우.
Ambulance a = (Ambulance) c;
최고조상까지도 instanceof 하면 True가 나온다.
=> 형변환 가능하다는 뜻
그래서 Object obj = (Object)fe;
Car c = (Car)fe;도 가능
참조 변수의 형변환을 하는 이유 : 참조변수(리모콘)을 변경함으로써 사용할 수 있는 멤버의 개수를 조절하기위해.
=> 리모콘을 교체해서 5개의 멤버 중 4개만 사용할 수 있도록 하는 것.
2-4 매개변수의 다형성
- 참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.
다형성 장점 1 : 다형적 매개 변수 (지금은 이거)
다형성 장점 2 : 하나의 배열로 여러종류 객체 다루기
다형성 방법 1 : Tv t = new SmartTv(); => 조상타입의 참조변수로 자손객체를 다루는 것(조상타입의 멤버까지 쓰기위함)
다형성 방법 2 : 참조변수의 형변환 - 리모콘 바꾸기. (사용가능한 멤버개수 조절을 위함)
다형성 방법 3 : instanceof 연산자 (형변환 가능여부 확인)
전에서는 buy 메서드에 오버로딩을 통해 Tv t, Computer c, Audtio a를 다 적어야 해서 코드 중복 + 길이가 늘어난다는 문제점이 있었다.
그러나 다형성을 사용하면 Product가 조상이고 Tv, Computer, Audio를 자손으로 삼아 모든 멤버를 사용할 수 있으므로,
코드의 길이도 짧아질 수 있고 더 간편하게 사용할 수 있다는 장점이 생긴다.
위에 저 두문장이 b.buy(new Tv1());과 같다.
=> 참조변수를 만들지 않고도 객체를 생성할 순 있지만, 그렇게 되면 buy메서드 내에서만 사용이 가능하게 된다.
2-5 여러 종류의 객체를 배열로 다루기
다형성 장점 1 : 다형적 매개 변수
다형성 장점 2 : 하나의 배열로 여러종류 객체 다루기 (지금은 이거)
- 조상 타입의 배열에 자손들의 객체를 담을 수 있다.
1. product [] cart = new Product[10];으로 10개짜리 배열을 만든다.
2. product p (tv, computer, audio가 들어있음)가 입력되면 cart 배열에 하나씩 증가되어 쌓이게 된다.
=> i값을 증가시켜 배열에 차곡차곡 저장하는 방법 ! (기본적인 방법)
Vector 는 object를 멤버로 가지고 있어 모든 종류의 배열을 객체 저장할 수 있다.
https://github.com/castello/javajungsuk_basic/blob/master/javajungsuk_basic_src/ch07/src/Ex7_9.java
GitHub - castello/javajungsuk_basic: 자바의 정석 기초편 관련 자료입니다.
자바의 정석 기초편 관련 자료입니다. Contribute to castello/javajungsuk_basic development by creating an account on GitHub.
github.com
=> 예제 이해해보기
'자바' 카테고리의 다른 글
자바의 정석 - CH8 예외처리 (0) | 2023.04.12 |
---|---|
자바의 정석 - CH7 객체지향 언어 2 - 3 (0) | 2023.04.12 |
자바의 정석 - CH7 객체지향 언어 2 - 1 (0) | 2023.04.10 |
자바의 정석 - CH6 객체지향 언어 1 - 2 (0) | 2023.04.07 |
자바의 정석 - CH6 객체지향 언어 1 - 1 (0) | 2023.04.07 |