[JAVA] 객체지향 (2)
Inheritance(상속)
: 기존 클래스의 필드, 메서드를 자식 클래스에서 재사용하기 위한 것
- 생성자, 초기화 블록(static, instance)는 상속하지 않는다.
유지 보수에 유리
extends 키워드를 사용
· 컴파일 시점 extends가 없으면 컴파일러가 extends Object 붙여서 실행
- Object Class 는 모든 Class의 부모 클래스
상속 (is a 관계) : 자식 클래스 is a 부모 클래스
- 위 첨부 사진에서 SpiderMan is a Person.
자바는 단일 상속만 지원
※ 다중 상속 효과를 원한다면 1) interface 또는 2) 포함 관계(has a)로 구현 가능
포함 has a 관계
public class SpiderMan2 extends Person{
Spider spider = new Spider();
boolean isSpider;
public void fireWeb(){
if(isSpider) {
spider.fireweb();
}
else {
System.out.printLn("Person은 거미줄 발사 불가");
}
}
Spider 코드 수정하면 SpiderMan2에도 반영, 유지보수에 유리
메서드 오버라이딩 : 부모 클래스에 정의된 메서드 자식 클래스에 적합하게 수정(재정의)
조건 - 메서드 이름 동일해야 한다.
- argument의 개수, 타입, 순서가 같아야 한다.
- return type이 같아야 한다.
- 접근 제한자는 부모보다 범위가 넓거나 같아야 한다.
- 부모보다 더 큰 예외를 던질 수 없다.
@Override 를 통해 Override한 메서드인지 확인 가능
· super 키워드 : 부모 클래스의 필드/메서드 접근하고 싶을 때 사용
- 객체 생성시 자동 생성
- 자식 클래스의 생성자 첫 줄에 super 생성자 호출 가능
SpiderMan(){
super(); // 부모 생성자 호출 가능
}
· this 키워드 : 객체 자신의 필드/메서드 접근하고 싶을 때 사용
- 객체 자신 하나의 생성자에서 다른 생성자 호출 가능
- 생성자 첫 줄에 this 생성자 호출 가능
Encapsulation(캡슐화)
제한자 : 클래스, 변수, 메서드 선언부에 사용하며 부가적 의미를 부여한다.
- 선언 시 순서 상관 없음 (일반적으로 접근제한자를 맨 앞에 작성)
· 접근제한자 : 하나만 사용 가능
- public : 어디든 접근 가능
- protected : 상속관계에서만 적용 가능
- default(==package) : 같은 패키지면 다 접근 가능
- private : 자기자신(클래스) 내부에서만 접근 가능
제한자 | 접근가능범위 | |||
같은 클래스 | 같은 패키지 | 다른 클래스의 자식 클래스 |
전체 | |
public | O | O | O | O |
protected | O | O | O | |
package(default) | O | O | ||
private | O |
· 사용 제한자
- static : 메모리 클래스 영역 레벨의 요소 설정
- final : 요소 수정 불가능
- abstract : 추상 메서드 및 추상 클래스 작성
· 그 외
- synchronized : 멀티 스레드 동기화 처리
캡슐화 : 접근 제한자 사용을 통한 데이터 은닉과 보호.
- private 접근 제한자로 막기.
- 공개되는 메서드 (setter / getter) 를 통한 접근 통로 마련
· 객체 생성 제어와 Singleton 디자인 패턴
: 수정 가능 멤버 변수가 없고 기능만 있는 경우, 객체 생성/삭제에 많은 비용이 들어 재사용이 유리한 경우 객체 생성 제한이 필요하다.
- Singleton 디자인 패턴 : 작성한 코드에서 오로지 하나의 객체만 생성하고 싶을 때 사용
- 내부에서는 private에 접근 가능, 객체 담을 필드 하나를 private로 설정
- 외부에서 private에 접근 가능한 getter 생성
- 객체 생성 없이 외부에서 접근할 수 있도록 getter에 static 추가
- 외부에서는 언제나 getter를 통해 객체 참조
=> 하나의 객체 재사용
Polymorphism(다형성)
· 다형성 : 하나의 객체가 많은 타입을 가질 수 있다.
- 상속 관계에 있을 때 부모 클래스 타입에 자식 클래스 객체 넣을 수 있다.
· 다형성을 활용하여 다른 타입의 객체를 하나로 묶어 배열로 만들 수 있다.
- Object 데이터 타입 배열은 어떤 타입의 객체라도 다 저장할 수 있다. (Object 클래스는 모든 클래스의 부모 클래스다)
- 기본형은 참조형이 아니기 때문, Wrapper Class 활용 !
Integer - int
Character - char
Float - float
Double - double 등
- argument 다형성 : 부모를 argument로 처리한다면 객체의 타입에 따라 메서드를 추가하지 않아도 된다.
· 참조형 객체의 형 변환
- 묵시적 형 변환 : 자식 클래스(작은 집)에서 부모 클래스(큰 집)으로 이사. 형 변환 생략 가능
- 명시적 형 변환 : 부모 클래스(큰 집)에서 자식 클래스(작은 집)으로 이사. 형 변환 생략 불가
※ instanceof 꼭 사용해주기
instanceof : 객체에게 너는 본래 어떤 클래스 타입이니? 묻는 것. 안전하게 type cast 하는 방법이다.
ex)
Person person = new Person();
SpiderMan sMan = (SpiderMan) person;
sMan.fireWeb();
-> 오류 발생 ! 메모리의 객체에는 fireWeb 메서드 없음. 무늬만 spiderman인 person
· 참조 변수의 레벨에 따른 객체의 필드/메서드 연결
- 상속 관계에서 객체 필드 중복 : 참조 변수 타입에 따라 연결 달라짐
- 상속 관계에서 객체 메서드 중복 (메서드 Override) : 무조건 자식 클래스의 메서드 호출. Override는 참조변수의 클래스 타입과 관련 없음