Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 스프링 입문(무료)
- 스프링 db1 - 스프링과 문제 해결
- jpa - 객체지향 쿼리 언어
- 스프링 고급 - 스프링 aop
- 자바의 정석 기초편 ch2
- 자바의 정석 기초편 ch7
- 게시글 목록 api
- 자바의 정석 기초편 ch14
- 스프링 mvc1 - 스프링 mvc
- 자바의 정석 기초편 ch6
- 자바의 정석 기초편 ch8
- 자바의 정석 기초편 ch4
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch3
- 스프링 mvc2 - 타임리프
- 2024 정보처리기사 수제비 실기
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch13
- 스프링 db2 - 데이터 접근 기술
- 스프링 mvc2 - 로그인 처리
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch1
- @Aspect
- jpa 활용2 - api 개발 고급
- 자바의 정석 기초편 ch9
- 스프링 mvc1 - 서블릿
- 코드로 시작하는 자바 첫걸음
- 타임리프 - 기본기능
- 자바의 정석 기초편 ch11
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch7 - 22 ~ 23 [캡슐화, 다형성] 본문
1) 캡슐화
(1) 접근제어자를 사용하는 이유?
- 외부로부터 데이터를 보호하기 위해서 -> 캡슐화
- 멤버변수에 직접 접근하지 못하게 하고 메서드를 통해 간접적으로 쓸 수 있게 함.
- 외부에는 불필요하고 내부적으로만 사용되는 부분을 감추기 위해 사용함
- 접근제어자는 좁을수록 좋고 필요할 때 넓히는 것이 좋음
(2) 캡슐화 예제1 - 캡슐화 전
- 시간을 정의하는 클래스에 hour를 직접 변경하지 못하도록 캡슐화 진행
- 변수들이 default 변수여서 같은 패키지내에서는 마음껏 수정이 가능함
class Time {
int hour; // 0 ~ 23사이의 값을 가져야 함.
int minute;
int second;
}
public class TimeTest {
public static void main(String[] args) {
Time t = new Time();
t.hour = 25; // iv hour를 직접 변경 = 0 ~ 23값이 아니어도 실행 됨
System.out.println(t.hour);
}
}
(2) 캡슐화 예제2 - 캡슐화 후
- 변수들을 private으로 선언하여 같은 클래스가 아니면 변수를 사용하지 못하도록 캡슐화
- 캡슐화된 값을 수정하기 위해서는 생성한 setHour()를 호출해서 간접적으로 변수의 값을 저장해야함
- setHour() 메서드에서 값을 수정할 때 검증 코드를 추가하여 0 ~ 23 사이의 숫자만 입력되도록함 -> 아무값이나 저장하지 못하도록 제약 조건을 적용할 수 있음
- 캡슐화된 값을 불러오기 위해서는 생성한 getHour()를 호출해서 간적접으로 변수의 값을 호출해야함
- 이러한 형태로 getter, setter를 만들어서 주로 사용함
class Time {
// 아래변수를 private로 지정하여 직접 변경 불가
private int hour; // 0 ~ 23사이의 값을 가져야 함.
private int minute;
private int second;
public void setHour(int hour) { // 값 저장(쓰기) 메서드 작성
// 메서드 추출 - 조건식을 주석없이 이해하기 쉽도록(의미가 명확하도록) 메서드로 추출
if(isNotValidHour(hour))
return;
this.hour = hour;
}
// 매개변수로 넘겨진 hour가 유효한지 확인해서 알려주는 메서드
// 해당 메서드는 Time클래스에서밖에 안쓰기 때문에 public으로 할 필요 없음
private boolean isNotValidHour(int hour) { // 추출한 메서드를 private
return hour < 0 || hour > 23;
}
public int getHour() { return hour; }; // 값 반환(읽기) 메서드
}
public class TimeTest {
public static void main(String[] args) {
Time t = new Time();
// t.hour = 25; // iv 직접 변경 -> 주석처리
t.setHour(21); // 메서드를 통해 간접적으로 데이터 초기화
System.out.println(t.getHour());
t.setHour(100); // 메서드의 조건에 맞지 않아 값이 변경되지 않음
System.out.println(t.getHour());
}
}
(3) 메서드 추출 단축키
- 재사용 가능한 코드들을 메서드화 시키는 IDE의 기능
- 추출할 코드들을 드래그 후 커맨드 + 옵션 + M (인텔리제이, 이클립스 동일함)
2) 다형성(polymorphism)
- 6장 ~ 7장 다형성까지 복습 필수(다형성을 모르면 다음 진도를 나가기 어려움)
- 조상타입 참조변수로 자손 타입 객체를 다루는 것
(1) 다형성을 통한 객체 생성
// 일반적인 객체 생성 방법
Tv t = new Tv();
SmartTv s = new SmartTv();
// 조상클래스명 참조변수 = new 자손클래스명();
// 타입이 불일치 하지만 다형성으로 인해서 생성 가능
Tv t = new SmartTv();
(2) 객체와 참조변수의 타입이 일치할 때와 일치하지 않을 때의 차이
- Tv클래스 (조상클래스)의 멤버 : 5개
- SmartTv (자손클래스)의 멤버 : 7개 (조상5개 + 2개)
// 조상 클래스
class Tv {
// Tv의 속성(멤버변수)
boolean power; // 전원상태(on/off)
int channel; // 채널
// Tv의 기능(메서드)
void power() { power = !power; }
void channelUp() { ++channel; }
void channelDown() { --channel; }
}
// Tv클래스(조상)의 멤버를 SmartTv클래스(자손)에 상속
class SmartTv extends Tv {
String text; // 캡션(자막)을 보여 주기 위한 문자열
void caption() { /*내용 생략*/ }
}
- SmartTv s = new SmartTv(); -> 참조변수 타입과 객체의 타입이 동일
- SmartTv의 참조변수 s 호출 시 모든 멤버 사용 가능
- Tv t = new SmartTv(); -> 다형성으로 조상 타입의 참조변수에 자손타입의 객체를 참조
- Tv의 참조변수 t 호출 시 Tv클래스(조상클래스)의 멤버만 사용 가능
- 자손타입의 멤버는 사용 불가능
(3) 자손 타입의 참조변수로 조상타입의 객체를 가리킬 수 없음
- Tv t = new SmartTv(); -> 조상 타입의 참조변수에 자손 타입 객체의 참조값을 저장, 다형성 적용
- SmartTv s = new Tv(); -> 자손 타입의 참조변수에 조상 타입 객체의 참조값을 저장하면 에러 발생
- 참조변수 타입을 리모콘이라고 가정하고 실제 객체를 기능을 가진 장비라고 비유했을 때 장비의 기능이 리모콘의 버튼보다 많은 것은 허용 되지만 그 반대의 경우에는 컴파일 에러 발생 -> 다음 강의에서 자세히 다룸
- 장비의 모든 기능을 리모콘에 담지 않아도 리모콘 작동에 문제가 없지만 리모콘에 버튼은 있는데 아무기능이 작동하지 않는 버튼이 있는것은 일반적이지 않은 상황이기때문이라고 이해하면 되며 버튼이 있으면 모든 기능이 있어야 함
3) QnA
Q.참조변수의 타입은 인스턴스(객체)의 타입과 반드시 일치 해야 하나?
- A. No. 일치하는 것이 보통이지만 일치하지 않을 수도 있음 = 다형성
Q.참조변수가 조상타입일 때와 자손타입일 때의 차이?
- A. 참조변수로 사용할 수 있는 멤버의 개수가 달라짐
- 조상의 멤버만 사용가능하고, 자손클래스에서 생성된 멤버는 사용 불가능
Q.자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 있나?
- A. No. 허용 불가
- 자손 클래스 타입의 참조변수가 조상 타입의 객체를 그냥 참조 할 수 있다면, 실제 객체에 존재하지 않는 멤버에 접근하려는 시도가 발생할 수 있기에 허용하지 않음
** 출처 : 남궁성의 정석코딩_자바의정석
'유튜브 공부 > JAVA의 정석 기초편(유튜브)' 카테고리의 다른 글
자바의 정석 기초편 ch7 - 27 ~ 30[매개변수다형성,여러종류의 객체를 배열로 다루기] (0) | 2023.11.27 |
---|---|
자바의 정석 기초편 ch7 - 24 ~ 26[참조변수의형변환,instanceof 연산자] (1) | 2023.11.27 |
자바의 정석 기초편 ch7 - 17 ~ 21 [제어자, static, final, abstract, 접근제어자] (0) | 2023.11.24 |
자바의 정석 기초편 ch7 - 10 ~ 16[참조변수 super, 생성자super(), 패키지, 클래스 패스, import문, static import문] (2) | 2023.11.23 |
자바의 정석 기초편 ch7 - 5 ~ 9[단일상속, Object클래스,오버라이딩, 오버로딩 vs 오버라이딩] (3) | 2023.11.23 |