타입
클래스가 곧 타입, 클래스가 청사진(설계도면)인데 사용하기 위해 heap에 만들라는 타입
다형성을 쓰는 이유
- 두 클래스간의 의존관계를 줄이기 위해(TestA, TestB)
- 연주자객체들을 객체배열을 이용해서 한 번에 연주시키기 위해
다형성*
- ‘서로 다른 형태’ → 타입(자료형)이 다양하다
- 상속으로 인해 파생된 기술이다.
- 자식클래스를 작성할때 부모클래스의 맴버뿐만아니라 타입또한 물려받는다.
- 부모타입의 레퍼런스로 여러개의 자식객체들을 취급할 수 있는 것
- 원클래스는 원이라는 타입이면서 도형이라는 타입을 가지고 있다
- 삼각형 클래스는 삼각형 타입이면서 도형이라는 타입을 가지고 있다
- 즉, 객체를 생성할때 도형이라는 레퍼런스 타입으로도 사용할 수 있다
- => 상위타입의 레퍼런스로 하위 타입의 객체의 주소를 보관할 수 있다
클래스 형변환
- up casting(JVM이 자동으로 추가해주는 코드이다.)
- 부모타입의 레퍼런스는 모든 자식의 주소를 가질 수 있지만,
자식 타입의 레퍼런스는 부모의 주소를 가질 수 없다 - sonata는 Object이면서 sonata이면서 Car타입을 갖고있다
- 하지만 반드시 sonata는 Car와 상속관계에 있어야한다
- sonata에 의한 산출물을 상위의 타입에 대입하는 것 → 자동형변환
- 부모타입의 레퍼런스는 모든 자식의 주소를 가질 수 있지만,
- down casting(명시적 형변환)
- (자식객체의 주소를 받은 부모) 참조형 변수를 가지고 자식의 멤버를 참조해야 할 경우, 후손 클래스 타입으로 참조형 변수를 형 변환해야 한다
- c라는 레퍼런스는 sonata 객체를 가지고 있지만, 타입이 Car이다
- c.moveSonata(); 메소드를 호출할때 c는 car타입(car, sonata, avante를 다 갖고 있다.)이기때문에 메소드가 있는 객체타입으로 임시적으로 형변환을 해주어야 sonata에 있는 sonatamove로 찾아갈 수 있다. ((Sonata)c).moveSonata();
- 소나타가 아니라 다른 객체로 형변환을 하면 클래스캐스트에러!!
- 레퍼런스 주소를 참조해서 사용을 하는건데 어디에 있는지 알기위해선 sonata의 형변환을 해줘야한다
객체배열과 다형성
- 다형성을 이용하여 상속관계에 있는 여러 개의 자식클래스를 부모 클래스의 배열에 저장 가능
- 따로 객체를 만들어서 사용하는 것 보다 훨씬 더 효율적이다.
매개변수와 다형성
- 메소드 호출시 다형성을 이용하여 부모타입의 매개변수를 사용하면, 자식타입의 객체를 받을수 있다.
instanceof 연산자
- 비교하는 레퍼런스와 클래스타입과 일치하는지 확인할 때 사용
public void method(Car c){
if(c instanceof sonata){
((sonata)c).moveSonata(); //참일때 실행
}
//다운캐스팅의 예외처리 : false일때 실행하지 않고 빠져나와서 down casting이 일어나지 않는다.
}
method(new Sonata);
- 해당타입에 맞춰 동작할 수 있도록 하기 위해서 사용한다
바인딩
- 실제 실행할 메소드 코드와 호출하는 코드를 연결시키는 것을 바인딩이라고 한다.
동적바인딩*
- 오버라이딩된 메소드가 먼저 실행된다.
- 컴파일시에 (소스코드와 메소드 헤드부분이 모두 연결되어 있다.) 실행할 당시의 객체 타입이 담기는데 그 기준으로 바인딩 되는 것을 동적 바인딩이라고 말한다.
동적바인딩 성립 요건
- 상속 관계로 이루어져 다형성이 적용된 경우에, 메소드 오버라이딩이 되어 있으면 정적으로 바인딩 된 메소드 코드보다 오버라이딩 된 메소드 코드를 우선적으로 수행하게 된다.
- 실행할 당시의 객체 타입에 맞춰 수행한다.
- 부모 클래스에 move 메소드가 있으면 다운캐스팅을 하지 않아도 된다.
하지만, move메소드가 없다면 컴파일에러 발생
추상클래스
- 몸체 없는 메소드(abstract가 있는 메소드)를 포함한 클래스
- 추상 클래스일 경우 클래스 선언부에 abstract 키워드를 사용
추상메소드
- 몸체({}) 없는 메소드를 추상 메소드라고 한다
- 추상 메소드의 선언부에 abstract 키워드를 사용한다
- 상속시, 반드시 구현해야 하는 메소드이다. (오버라이딩 강제화 해줄 목적)
추상클래스의 특징
- 미완성 클래스(abstract 키워드 사용)
- abstract 메소드가 포함된 클래스 -> 반드시 abstract 클래스
- 자체적으로 객체 생성 불가 -> 반드시 상속하여 객체 생성
- 일반적인 메소드, 변수도 포함할 수 있다
- abstract메소드가 없어도 abstract 클래스 선언 가능하다.
- 객체 생성은 안되나, ref변수 type으로는 사용 가능하다.
추상클래스의 장점
- 일관된 인터페이스 제공
- 부모클래스를 쓰려고 하는 사람과 자식클래스를 쓰려고 하는 사람의 중간 다리 역할을 해서 틀로써 하기위해 playManagement
- 꼭 필요한 기능 강제함
- (공통적이긴 하나, 자식클래스에서 특수화되는 기능)
- cry() 닭은 꼬끼고 호랑이는 어흥 → 특수화
- (공통적이긴 하나, 자식클래스에서 특수화되는 기능)
인터페이스
- 상수형 필드와 추상 메소드만을 작성할 수 있는 추상 클래스의 변형체이다
- 강제성 부여 → 공통적인 틀을 작성할 수 있게
- 메소드의 통일성을 부여하기 위해서 추상 메소드만 따로 모아 놓은것
- 관련 없는 클래스들을 하나의 상위타입의 역할로 묶고 싶을때 인터페이스 사용
인터페이스 특징
- 모든 인터페이스의 메소드는 묵시적으로 public이고 abstract이다.
- 전역변수는 묵시적으로 public static final이다.
- → 따라서 인터페이스 변수의 값 변경 시도는 컴파일시 에러를 발생
- 객체 생성은 불가, 참조형 타입으로서는 가능하다
import java.io.Serializable;
import java.util.Comparator;
//추상메소드만 맴버로 가질 수 있는 추상클래스를 인터페이스라고 한다.
//상수 필드만 맴버로 추가할 수 있다.
//인터페이스간 상속은 extends를 사용하며 다중 상속을 지원한다.
//클래스에서 인터페이스 상속 시 implements 키워드를 사용하지만
//인터페이스간 상속은 implements 사용이 불가능하다.
public interface IProduct extends Serializable/*, Comparator*/
/*implements Iterator*/{
//상수필드는 반드시 선언과 동시에 초기화가 되어 있어야 한다.
//모든 필드는 묵시적으로 public static final이다.
/*public static final */String Product_NAME = "상품명";
//인터페이스 안에 선언된 메소드는 모두 추상메소드이기 때문에
//선언시 public abstract를 생략할 수 있다.
//따라서 후손은 오버라이딩시 반드시 public으로 해야 한다.
/*public abstract void agstImethod();*/
void abstImethod();
//인터페이스 내에서는 몸체 있는 메소드 작성이 불가능하다.
/*void method() {}*/
}
인터페이스 장점
- 상위 타입의 역할로 다형성을 지원하여 연결해주는 역할 수행
- 상속을 받을때 임플리먼츠라는 키워드 사용
- 해당 객체가 다양한 기능을 제공시에도 인터페이스에 해당하는 기능만을 사용하게 제한할 수 있다.
- 공통 기능상의 일관성 제공 / 공동 작업을 위한 인터페이스 제공 => 행위(메소드)의 강제화
인터페이스 상속
- Interface는 다중 상속을 지원하며 class가 상속을 받을 때에는 implements라는 키워드를 사용한다.
- Interface간의 상속시에는 extends 키워드 사용 가능하고, 다중상속을 지원한다.
- Interface 이용하여 단일 상속의 제한점을 극복할 수 있다.
[접근제한자] interface 인터페이스명
extends 부모인터페이스명, 부모인터페이스명, …{}
[접근제한자] class 클래스명 extends 부모클래스명
implements 부모인터페이스명, 부모인터페이스명, …{}
인터페이스끼리의 상속은 다중상속을 지원
import java.io.Serializable;
//인터페이스 상속의 경우 implements 키워드를 사용한다.
//extends 키워드는 단일 상속만 지원하지만,
//implements 키워드는 다중 상속도 지원한다.
public class Book extends Product/*, Date*/ implements IProduct, Serializable{
public Book() {}
public void printBook() {
System.out.println("Book 클래스의 printBook() 실행...");
}
@Override
public void abstMethod() {}
//인터페이스의 추상메소드는 오버라이딩 시 반드시 public으로 접근제한자를 설정해야 한다.
@Override
public void abstImethod() {}
@Override
public String toString() {
return "Book 클래스의 toString() 메소드 실행...";
}
}
인터페이스 VS 추상클래스*
- 인터페이스는 abstract라는 추상클래스로 작성해야한다.
- 모든 메소드는 묵시적으로 추상메소드이다
- 단. 추상클래스는 반드시 명시해야함
'JAVA > 이론 정리 및 예제' 카테고리의 다른 글
[JAVA/자바] #7_2 날짜/시간 처리 실습문제 (0) | 2021.09.17 |
---|---|
[JAVA/자바] #10_1 기본API / 예제 (0) | 2021.09.17 |
[JAVA/자바] #8_1 상속 / 예제 (0) | 2021.09.17 |
[JAVA/자바] #6_5 메소드(method)/ 예제 (0) | 2021.09.14 |
[JAVA/자바] #6_4 생성자(constructor) / 예제 (0) | 2021.09.14 |