다형성

큰 타입 변수에 작은 타입값을 저장하면 자동으로 큰 타입으로 변환되는 데,
비슷하게 상속 관계의 클래스들 사이에서도 일어나는 변환.
 
정의 : 클래스의 상속 구조에서 부모 클래스 타입 참조 변수가 자식 클래스의 인스턴스를 가리킬 수 있는 기능
  • instanceof 연산자가 함께 사용된다
 

업캐스팅 Upcasting

부모 클래스 타입 변수 = 자식 클래스 타입 변수(or 자식 클래스 인스턴스)
Student s = new College(”홍길동”, 2, 22) ← s가 자식 클래스 인스턴스를 받을 수 있다.
업캐스팅된 상태에서 메서드 호출 시 JVM은 항상 하위 클래스의 오버라이딩된 메서드를 먼저 호출

 

 
1) 참조 변수 s1을 이용해서 Student 인스턴스의 getStudInfo() 메서드를 호출
2) JVM은 다시 자식 클래스에 오버라이딩된 getStudInfo() 메서드가 있는지 확인
3) 있으면 자식 클래스의 getStudInfo() 메서드를 호출
 
→ s가 부모 타입이므로 메서드를 호출하면 부모 클래스의 메서드가 우선 호출될거라 생각하지만
자식 클래스에 오버라이딩된 것이 우선이다

 

다운캐스팅 Downcasting

업캐스팅된 상태에서 자식 클래스의 필드나 메서드에 접근하기 위해선 다시 자식 클래스 타입으로 변환해주어야 한다.
 
자식클래스타입변수 = (자식클래스)부모클래스타입 인스턴스
 

다형성을 이용한 학생 시험 점수 구하기

Person
 
Student
Middle
 
College
 
실행클래스

 

 

 

 


 

추상 클래스

 

abstract

정의  : ‘기능은 없고, 선언만 되어 있다’
  • 클래스와 메서드를 추상으로 사용
 
  • 구현 메서드 : 구현부 블록({})이 있으면 구현 메서드
  • 추상 메서드 : abstract 지정자에, 구현부 블록이 없으면 추상 메서드

 

추상 메서드는 단독으로 사용되는 일은 없고, 추상 클래스 내에서 사용된다.
 

추상 클래스

: 클래스 선언 시 abstract로 지정한 클래스
  • 더 이상 (new) 인스턴스 생성이 불가능
  • 추상 메서드가 없어도 추상 클래스로 선언 가능
  • 추상 메서드가 있으면 그 클래스는 반드시 추상클래스로 선언해야한다.
  • 일반적으로 부모 클래스가 추상 클래스로 선언되어 업캐스팅으로 자주 사용됨
 
용도
  • 자식 클래스에서 구현해야할 기능을 부모 클래스의 추상 메서드의 형식을 빌려와서 일관성 있게 구현
  • 프로그램 소스 코드 구조를 일정하게 유지할 수 있으므로 표준화 가능
 
프로그램은 개발자가 각 기능을 알아서 구현하기보다는 프로젝트의 규모가 점점 커질 것을 고려하여 유지보수나 확장성을 위해 누구나 쉽고 빠르게 소스 내용을 이해하고 관리할 수 있도록 소스의 구조를 일정하게 유지해야 한다.
 
 
강조!
추상 클래스는 직접 인스턴스 생성은 불가능하지만, 상속받는 자식 클래스의 인스턴스를 생성하면 정상적으로 추상 클래스의 인스턴스가 메모리에 생성된다.
 
예)
 
1. Student라는 부모 클래스에
public abstract getTeacher(); 선언

 

2. Middle이라는 자식 클래스에서 기능 구현

@Override
public String getTeacher() {
 return “담임 선생님:  “ + teacher;
}

 

3. College 자식 클래스에서 기능 구현

@Override
public String getTeacher() {
 return “지도 교수님:  “ + teacher;
}
 

4. 실행 클래스

  • Student 인스턴스 생성 불가능
  • Middle과 College의 오버라이딩한 getTeacher 메서드 호출
 

 

 

동적 로딩

: 특정 객체(인스턴스)가 컴파일 시에 실행 파일에 포함되지 않고, 프로그램 실행 중 JVM에 의해 동적으로 메모리에 적재되는 방법
 
용도: 작은 메모리 용량으로도 큰 프로그램을 실행시킬 수 있음.
 
JVM은 시작과 동시에 모든 클래스 인스턴스를 메모리에 생성하는 것이 아니라 해당 인스턴스를 생성하는 코드에서 동적으로 메모리에 생성
그리고 더 이상 사용되지 않으면 JVM에서 자동으로 삭제가비지 컬렉터(Garbage Collector)
 
동적 로딩의 반대 개념 : 정적 로딩 (대표언어: C)

 

C언어로 만든 프로그램을 실행하면 모든 실행 파일의 기능이 메모리에 로드되어 항상 존재

 

 → 빠름
반면, 동적로딩은 자주 하면 실행이 느려질 수 있다.
이 문제점을 개선한 static!
 

Static 정적 지정자

: 인스턴스 생성과 상관없이 프로그램 실행 시 메모리에 필드나 메서드를 생성
  • static으로 지정된 멤버들은 프로그램 실행 시 자동으로 메모리에 생성
  • 종료 시 메모리에서 소멸
  • 인스턴스 생성과 무관
 
지정 대상
  • 필드: 인스턴스 간의 데이터 공유 시 사용 (상수)
  • 메서드 : 인스턴스 생성 없이 메서드 사용
  • 클래스 : 내부 클래스로 사용 시
 
static을 사용하는 대표적인 경우가 main() 메서드
다른 클래스에서 static으로 지정된 멤버에 접근하려면 클래스명과 도트 연산자로 접근
클래스명.필드;
클래스명.메서드;
 
+) 정적 메서드에선 같은 정적 필드에는 접근할 수 있으나, 아직 메모리에 생성되지 않은 인스턴스 필드를 사용하면 에러 발생
 
정적 메서드로 대표적인 것이 자바 API에서 제공하는 Math 클래스의 메서드들
 

싱글톤 Singleton

프로그램에서 한 개의 객체만 존재해야 할 경우 싱글톤 패턴을 이용
작성 규칙
  • 인스턴스를 생성할 클래스의 생성자와 필드는 private으로 선언
  • 인스턴스에 접근할 메서드는 public으로 선언
  • 외부 클래스에서는 new를 통한 인스턴스 생성은 불가능
  • 생성된 인스턴스는 getInstance() 메서드를 통해 접근
 
Earth 예제
package sec02.ex03;

public class Earth {
	private static Earth ourEarth = null;	//싱글톤 객체의 필드는 private
	public static int EARTH_RADIUS = 6371;
	
	private Earth() {
		System.out.println("지구 객체 생성");
	}
	
	public static Earth getInstance() {	//getInstance() 메서드 호출 시 객체가 없으면 생성, 이미 존재하면 객체 위치 리턴
		if(ourEarth == null) {
			ourEarth = new Earth();
		}
		
		return ourEarth;
	}

}
 
실행 클래스
package sec02.ex03;

public class SingletonTest {
	public static void main(String[] args) {
		//Earth myEarth = new Earth(); 싱글톤 객체는 외부에서 생성할 수 없다
		System.out.println("첫 번째 getInstance() 호출");
		Earth myEarth = Earth.getInstance();
		
		System.out.println("두 번째 getInstance() 호출");
		Earth yourEarth = Earth.getInstance();
		
		if(myEarth == yourEarth) {	//두 변수의 위치값 비교
			System.out.println("두 지구 객체는 같은 객체입니다.");
		} else {
			System.out.println("두 지구 객체는 다른 객체입니다.");
		}
		
	System.out.println("지구 반지름: "+ Earth.EARTH_RADIUS + "km");
	}

}
 
 

final 지정자

: ‘금지’의 의미를 가지는 지정자
  • 클래스 : 상속을 금지
  • 메서드 : 오버라이딩 금지
  • 필드 : 값 변경을금지 (상수로 지정)
 
자바에서 사용되는 상수 형식
  • 상수는 모든 클래스 인스턴스에서 접근해야 하므로 public 으로 지정
  • 실행 시 메모리에 존재해야 하므로 static으로 지정
  • 값을 변경할 수 없으므로 final로 지정
public static final 타입 상수명 = 값;
  • 상수명은 대문자와 “_”를 이어서 만드는 것이 관례
 
예)
public static final int SAFE_SPEED = 60;
public static final String SERVER_IP_ADDR = “192.0.0.1”;
 
+) 참고로 자바에서 60, 3.14, “Hello”와 같이 구체적인 값은 리터럴(literal)이라고 한다.
 

클래스들 간에 데이터를 전달하는 클래스

VO(Value Object) 클래스
정의 : 
  • 여러 다른 타입의 데이터를 다른 클래스로 전달 시 사용
  • TO(Transfer Object) 또는 DTO(Data Transfer Object)라고도 한다.
형식
  • 필드를 private로 선언
  • 생성자를 구현
  • 각 필드에 대한 getter/setter를 구현
 
예) MemberVO 클래스
package member;

public class MemberVO {
	String id;
	String password;
	String name;
	String address;
	String phoneNum;
	


	public MemberVO (String id, String password, String name, String address, String phoneNum) {
		this.id = id;
		this.password = password;
		this.name = name;
		this.address = address;
		this.phoneNum = phoneNum;
	}
	
	//getter와 setter는 생략

}
 

'멀티캠퍼스-JAVA 풀스택 > JAVA' 카테고리의 다른 글

Java 기초(8)-필수 사용 클래스  (0) 2025.12.04
Java 기초(7) - 인터페이스  (0) 2025.11.25
Java 기초(5) - 객체 지향  (0) 2025.11.12
Java 기초(4) - 배열  (0) 2025.11.12
Java 기초(3)  (0) 2025.10.28

+ Recent posts