25.02.26 (수) 13일차 Java

허배령·2025년 2월 26일

괴발개발 TIL

목록 보기
13/54

다형성

  • 상속을 이용한 기술부모클래스 타입 참조변수 하나로
    상속 관계에 있는 여러 타입의 자식객체를 참조할 수 있는 기술
부모클래스 변수명 = new 자식클래스();

클래스 형변환

업 캐스팅(Up Casting)

  • 상속관계에 있는 부모, 자식 클래스 간에 부모타입의 참조형 변수
    모든 자식 타입 객체의 주소를 참조할 수 있음
//Sonata 클래스는 Car 클래스의 후손
Car c = new Sonata();
//Sonata클래스형에서 Car클래스형으로 바뀜

* 부모로부터 상속 받은 멤버만 참조 가능

다운 캐스팅(Down Casting)

  • 부모타입 참조변수가 자식객체를 참조하는 기술
  • 업 캐스팅이 적용된 상태에서만 진행할 수 있다!!
  • 부모타입을 자식타입으로 "강제형변환" 해서
    자식객체의 본래 필드, 메서드를 사용가능하게 한다!
//Sonata 클래스는 Car 클래스의 후손
Car c = new Sonata();
((Sonata)c).moveSonata();
System.out.println(((Tesla)c1).getBatteryCapacity());
		// 주의!
		// "." 연산자 (Tesla) 형변환하는 연산자보다 우선순위 높음
		// 그래서 형변환 하는 부분을 ()로 묶어주고 . 연산을 진행해야
		// Tesla 객체의 getBatteryCapacity()를 사용할 수 있음

** 클래스 간의 형 변환은 반드시 상속 관계인 클래스 끼리만 가능 **
** 업 캐스팅 상태였을 때!! **

객체배열과 다형성

  • 다형성을 이용하여 상속 관계에 있는 하나의 부모 클래스 타입의 배열 공간에
    여러 종류의 자식 클래스 객체 저장 가능
Car[] carArr = new Car[5]; 

carArr[0] = new Sonata();
carArr[1] = new Avante();
carArr[2] = new Grandure();
carArr[3] = new Spark();
carArr[4] = new Morning();

매개변수와 다형성

  • 다형성을 이용하여 메소드 호출 시 부모타입의 변수 하나만 사용해 자식 타입의 객체를 받을 수 있음
public void execute() {
	driveCar(new Sonata()); 
	driveCar(new Avante());
	driveCar(new Grandure());
}

public void driveCar(Car c) {}

바인딩

  • 실제 실행할 메소드 코드와 호출하는 코드를 연결 시키는 것

정적 바인딩

  • 프로그램이 실행되기 전 컴파일 단계에서 메소드와 메소드 호출부를 연결
Car c1 = new Car("경유엔진", "경유", 8); // 평범한 객체
		
		System.out.println(c1.toString());
		// edu.kh.poly.ex1.model.dto.Car.toString()
		// Car 객체에 있는 toString() 메서드를 호출
		// 프로그램 "실행 전"
		// 컴파일러는 toString() 메서드가 Car에 있는 걸로 인식해서
		// c1.toString() 호출코드와
		// edu.kh.poly.ex1.model.dto.Car.toString() 메소드 코드를 연결
		// => 정적 바인딩!

동적 바인딩

  • 컴파일 시 정적 바인딩된 메소드를 실행할 당시의 객체 타입을 기준으로 바인딩 되는 것
Car c2 = new Spark("경차엔진", "휘발유", 4, 0.5);	// 업캐스팅
		// 업캐스팅 적용 -> 부모 부분만 참조 가능한 상태
		
		System.out.println(c2.toString());
		// edu.kh.poly.ex1.model.dto.Car.toString()
		// 참조변수 c2가 Car타입이므로
		// toString() 호출코드와 Car의 toString() 메소드 코드를 연결
		// => 정적 바인딩
		
		// 실행 해보면 자식(Spark)의 toString()이 호출되는 것을 확인
		// 경차엔진 / 휘발유 / 4 / 0.5
		// -> 컴파일 시에는 부모(Car)와 바인딩 == 정적바인딩
		
		// -> "실행 시"에는 정적바인딩보다 자식(Spark)에서 오버라이딩 된
		// toString() 메서드가 우선시 되어 Spark의 메서드와 바인딩
		// => 동적바인딩

동적 바인딩 성립요건

  • 상속 관계로 이루어져 다형성이 적용된 경우, 메소드 오버라이딩이 되어 있으면
    정적으로 바인딩 된 메소드 코드보다 오버라이딩 된 메소드 코드를 우선적으로 수행

instanceof 연산자

  • 현재 참조형 변수가 어떤 클래스 형의 객체 주소를 참조하고 있는지 확인 할 때 사용
    클래스 타입이 맞으면 true, 맞지 않으면 false 반환

표현식

if(레퍼런스 instanceof 클래스타입) {
	//true일때 처리할 내용, 해당 클래스 타입으로 down casting
}

if(c instanceof Sonata) {
	((Sonata)c).moveSonata();
} else if (c instanceof Avante){
	((Avante)c).moveAvante();
} else if (c instanceof Grandure){
	((Grandure)c).moveGrandure();
}

예시

Car c1 = new Tesla();
		// Tesla 객체를 만들어 Car타입 참조변수 c1에 담음
		
		// Spark s1 = (Spark)c1;
		// 다운캐스팅 잘못해도 컴파일 에러 발생 안함
		// -> 실행 시 발생 (런타임 에러)
		// ClassCastException : 형변환 에러
		
		// 해결방법 : instanceof 연산자와 같이 사용하면 된다
		
		// 예외 처리
		if(c1 instanceof Spark) { // c1이 Spark이거나 상속관계인가?
			// 맞다면
			Spark s1 = (Spark)c1; // 다운캐스팅
			System.out.println("성공");
		} else { // 아니라면
			System.out.println("실패, Spark타입/상속관계 아님");
		}

추상

추상 클래스

  • 몸체 없는 메서드를 포함한 클래스 (미완성 설계도)
  • 추상 클래스일 경우 클래스 선언부에 abstract 키워드 사용
  • 객체로 만들 수 없는 클래스
[접근제한자] abstract class 클래스명 {}

여러 타입들을 관리하기 위한 상위 타입의 목적,
객체로 생성하여 사용하기 위한 목적이 아님!

추상 메서드

  • 몸체 없는 메서드
  • 추상 메소드의 선언부에 abstract 키워드 사용
  • 상속 시 반드시 구현해야 하는, 오버라이딩이 강제화되는 메소드
[접근제한자] abstract 반환형 메소드명(자료형 변수명);
public abstract void ex2();

특징

  1. 미완성 클래스(abstract 키워드 사용)
    자체적으로 객체 생성 불가반드시 상속하여 객체 생성
  2. abstract 메소드가 포함된 클래스는 반드시 abstract 클래스
    abstract 메소드가 없어도 abstract 클래스 선언 가능
  3. 클래스 내에 일반 변수, 메소드 포함 가능
  4. 객체 생성은 안되지만 참조형 변수 타입으로는 사용 가능

장점

  • 상속 받은 자식에게 공통된 멤버 제공.
  • 일부 기능의 구현을 강제화(공통적이나 자식 클래스에 따라 재정의 되어야 하는 기능).

인터페이스

  • 상수형 필드와 추상 메소드만을 작성할 수 있는 추상 클래스의 변형체
    메소드의 통일성을 부여하기 위해 추상 메소드만 따로 모아놓은 것으로
    상속 시 인터페이스 내에 정의된 모든 추상메소드 구현해야 함
  • 자바에서 인터페이스 : 클래스간의 접점 -> 클래스가 공통적으로 가져야하는 필드, 메서드를
    모아두고 상속
[접근제한자] interface 인터페이스명 {
	//상수도 멤버로 포함할 수 있음
	public static final 자료형 변수명 = 초기값;

	//추상 메소드만 선언 가능
	[public abstract] 반환자료형 메소드명([자료형 매개변수]);
	//public abstract가 생략되기 때문에
	//오버라이딩 시 반드시 public 표기해야 함
}

특징

  1. 모든 인터페이스의 메소드는 묵시적으로 public abstract
  2. 변수는 묵시적으로 public static final
  3. 객체 생성은 안되나 참조형 변수로는 가능(다형성)

장점

  • 다형성을 이용하여 상위 타입 역할(자식 객체 연결)
  • 인터페이스 구현 객체에 공통된 기능 구현 강제화 (== 구현 객체간의 일관성 제공)
  • 공동 작업을 위한 인터페이스 제공
  • 인터페이스 == 미완성 설계도 == 객체 생성 불가능 => 참조변수로는 사용 가능
  • 코드의 큰 수정 없이 객체 생성 코드만 바꾸면 새로운 클래스 코드를 수행할 수 있다.
  • 인터페이스를 부모 참조변수로 사용하면 다형성 중 업캐스팅이 적용돼서,
    상속받은 모든 클래스를 자식객체로 참조할 수 있다.
    -> 이를 이용하여 중요한 메인코드의 수정을 최소화 할 수 있다!
  • 자식클래스에 공통된 메서드를 강제 구현하라고 하기 때문에,
    모든 자식클래스가 동일한 형태를 띄게 된다.
    -> 이를 이용하여 공동작업(팀 프로젝트)에 필요한 개발환경 조성이 용이하다.

추상클래스와 인터페이스

extends : 확장하다	implements : 구현하다

()클래스		-  ()클래스	: extends 사용 
()인터페이스	-  ()인터페이스	: extends 사용
()인터페이스	-  ()클래스	: implements 사용
()클래스		-  ()인터페이스	: 상속불가!!

정리

profile
인생은 변수

0개의 댓글