키워드
- 캡슐화
- 클래스와 객체, 객체와 메서드
- 변수와 메서드
- 인스턴스 메서드 vs 클래스 메서드(static)
- 캡슐화의 은닉성
- overloading
- 생성자
- Getters and Setters
서론
캡슐화
캡슐화란
- 데이터 구조와 함수를 하나의 영역에 모아놓는 작업
- 한곳에서 수정하면 다른 곳에서 에러 나면 안됨
- 우리가 Main에서 작업을 했지만 이제는 클래스를 하나 더 만들어서 분리하는 작업을 시작했다
왜 필요하냐면
- 구조화된 객체를 사용하는 함수는 구조 변경에 엄청 취약함
- 어디에서 하나 바꾸면 에러 나는데 그 원인이 어딨는지 한참 찾아야겠지
- 그래서 해결책은 바꾸면 오류가 나는 애들을 한곳에 모아두는 거임
- 그래서 모이고 모이고 해서 캡슐이 되는 거
어떻게 쓰냐면
- 그 전에 같은 클래스 내에 있을 때는 그냥 썼는데, 밖에 있는 애들을 쓰려면 클래스이름. 점을 찍어서 어디에 있는 함수들을 쓰는 건지 적어줘야한다
객체와 메서드의 관계
- 방법론은 어떤 문제를 해결하면서 나온다
- 간단 이해란 없지
[1]
void main(){
list = new ExamList();
ExamList.inputList(list);
ExamList.printList(list);
ExamList.saveList(list);
}
[2]
void main(){
list = new ExamList();
list.inputList();
list.printList();
list.saveList();
}
[1]은 함수가 나서서 모든 걸 처리하고 있다.
[2]는 객체를 필두로 척척 기능을 사용하고 있다.
객체가 나서는 게 훨씬 보기도 사용하기도 좋다.
사용하기에는 왜 좋은가?
어차피 우리는 다른 클래스에서 정의된 기능을 사용하는 건데, main에서는 함수 이름을 쓴다 한들 할 수 있는 게 없지? 값만 받아오면 되는 겁니다.
변수와 메서드
변수란?
왜 필요?
어떻게 쓰지?
- 클래스변수 (카드의 폭, 높이) : 모든 인스턴스에서 사용되는
- 인스턴스 변수 (카드의 무늬, 색) → 인스턴스 고유의
- 지역변수
메서드란?
왜 필요?
어떻게 쓰지?
- 클래스 메서드 (Static) : 인스턴스 변수를 사용할 수 없다
- 인스턴스 메서드 : 인스턴스 변수와 관련된 작업을 하는, 즉 메서드 작업을 할 떄 인스턴스가 꼭 필요한 메서드
인스턴스 메서드 VS (클래스|static) 메서드
인스턴스 메서드 VS 메서드(static)란?
- 메서드는 객체를 통해서만 호출되는 함수 = 인스턴스 함수 (더 많이 쓰임)
- 원래 형태의 메서드 = 고전함수 = static = 기본함수
- 객체위주나, 고전적 함수냐 그 정도의 차이가 있다
- static 일 때는 모든 데이터는 파라미터를 통해서만 전달되게 되어있음
어떻게 쓰냐면
- 인스턴스나 static 함수나 표현식만 달라진거임
- 근데 인스턴스 메서드는 파라미터로 전달받는게 아무것도 없잖아
근데 넘겨받는다고 했어 일임받았잖아 역할을
그럼 무슨이름으로 써야돼 ? → this
은닉성 맛보기
- 기능별로 분리된 캡슐들이 다른 캡슐이 자신의 캡슐을 깨뜨리지(값을 변경 등) 못하도록 보호할 수 있다.
생성자
생성자란?
- 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'
왜 생성자 필요?
- 우리가 처음에 생성하고 초기화할 때 쓰는 함수는 한번만 쓰여야되잖아
- 계속 불리면 안됨
어떻게 쓰이는 거냐면
- 생성자의 이름은 클래스의 이름과 같아야함
- 생성자도 오버로딩이 가능하기때문에 클래스 내에 여러개 생성자 존재할 수 있음
- 생성자라는 이름 때문에 오해하기 쉽지만, 인스턴스 초기화 역할을 하는 유사 메서드일뿐
- 모든 클래스에는 하나 이상의 생성자가 정의 돼 있어야함
- 기본 생성자를 만든 뒤 오버로딩하는 이유? 간결해서
- 근데 우리가 정의 안해줘도 괜찮았던 건 컴파일러가 제공하는 기본 생성자가 있기 때문임
- 만약 컴파일러가 생성해준 그대로 냅두면 괜찮은건데 ...
- 우리 손으로 오버로딩한 생성자를 만들었으면(매개변수 있는 생성자), 기본 생성자도 우리 손으로 정의를 해줘야함
- 인스턴스를 생성할 때는 (new) , 반드시 클래스 내부에 생성자 중의 하나를 선택해서 지정해야함
Card c = new Card();
여기에 클래스(참조형 이름이 Card인걸 보니 암튼) 이름이랑 똑같은
Card() 이거, 이게 생성자였던 거임... 초기화 하는 거였던 거임...
- 그래서 인스턴스를 생성할 때는,
- 클래스 → 어떤 클래스의 인스턴스를 생성할 것인가?
- 생성자 → 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?
생성자의 조건
- 객체가 생성 되자마자 무조건 제일 먼저 실행돼야 함
- 생성될 때 단 한번만 실행돼야 함
- 얘는 함수인듯 함수 아닌앤데, 함수 아니야, 그냥 생성자야, 초기화러, 초기화하는 역할을 하는 애임
- 그래서 생성자의 이름은 → 그 객체를 초기화 하는 애니까 객체의 형식 명칭을 쓰는 거임 → 왜냐면 객체 그 자체로 형식이잖아
- 그래서~ 반환타입도 없던거고, 클래스 이름이랑 똑같이 썼던 거였다..
- public void init() → public 클래스이름() : 원래는 void 를 써야하지만 모든 생성자가 리턴값이 없기때문에 생략
- 그래서 생성자는 이렇게 생건 거였다
Getters and Setters
- 문제상황: 클래스가 두개 있음(class1 메인, class2) 근데 캡슐화가 안됐는지...class2에서 변수명 수정했더니 class1에서 갑자기 에러가 뜸. class1은 class2의 kor 값이 필요한데...
- 그래서 탄생한게 getters and setters임
- class2 에서 getters and setter를 정의만 해놔주면
class1에서 getKor()해서 값을 받아올 수 있음
- getKor() 함수는 점수를 return 해주는 형태면 되겠고
- setKor() 함수는 class2가 class1에서 받아온 거임 (값을 설정)
- 그 값을 지역변수로 설정해서 쓰기만 하면 됨