본문 바로가기

자바 수업 정리

수업정리 12일차.

다형성(polymorphism)

다형성 : 여러 가지 형태를 가질 수 있음을 의미.

한 타입의 참조변수로 여러 타입의 객체를 참조함으로써 다형성을 프로그램적으로 구현하였음.

참조변수 형변환 : 서로 상속관계에 있는 클래스사이에서만 가능.
기본형 변수에서의 형변환에서 작은 자료형에서자료형의 형변환은 생략이 가능하듯이. 참조형 분수의 형변환에서는 자손타입의 참조변수를 조상타입으로 형변환 하는 경우에는 형변환을 생략할 수 있다.

참조 변수간의 형변환 역시 캐스트연산자를 사용하며 괄호() 안에() 변환하고자 하는 타입의 이름(클래스명)을 적어주면 된다

 

자손타입 -> 조상타입 (Up-casting) : 형변환 생략가능. (무조건 가능)

자손타입 <- 조상타입 (Down-casting) : 형변환 생략 불가. (조건부 가능)

 

객체지향 프로그램 4가지의 특징
 - 프로그램을 독립된 단위 (객체)의 객체들을 모아서 관계를 맺어 처리하는 형태
 - 각각의 객체는 메시지를 주고받으면서 데이터를 처리
 - 메시지를 받을 경우 (매개변수를 통해) / 메시지를 주는 경우 (return) 
 - 추상화, 캡슐화(정보은닉), 상속, 다형성


 추상화(Abstraction) - 핵심적인(공통적인) 코드만 보여주기.
 - 구현된 부분과 구현되지 않은 부분으로 분리
 - 개인(자식)이 구현해야 할 부분은 분리하여 처리
   
 캡슐화(Encapsulation) - 데이터 보호(정보 은닉)
 - 멤버변수(private)를 숨기는 형태, 메서드로 접근
 - 멤버변수와 메서드를 하나로 묶어 처리하는 형태
 - 은닉화 : 객체의 내부의 정보를 숨겨 외부로 드러나지 않게 보호하는 것

 상속(Inheritance) - 코드 재사용 (확장)
 - 클래스를 상속받아서 수정하면 중복 코드를 줄일 수 있음.
 - 유지보수가 편함.
 
다형성(Polymorphism) - 객체 변환이 용이함.
 - 하나의 코드가 여러 객체의 형태로 구현되어 실행되는 것
 - 코드는 같은데 들어오는 객체에 따른 다른 실행결과를 얻을 수 있음.
 - 다형성을 잘 활용하면 유연하고, 확장성있는, 유지보수가 편리한 프로그램을 만들 수 있음.

 

다형성에서는 조상의 객체로 자식의 객체를 생성가능하지만, 조상에게 상속받은 메서드만 실행가능.

자식객체로 부모객체의 생성은 불가능.

 

참조변수의 형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조변수의 형변환은 인스턴스에 아무런 영향을 미치지 않고, 단지 참조변수 형 변환을 통해서 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 개수를 조절하는 것뿐임.

 

Instanceof 연산자 : 참조 변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용. 주로 조건문에 사용. 연산의 결과로 true를 얻었다는 것은 참조변수가 검사한 타입(클래스)으로 형변환이 가능하다는 것을 뜻한다. 

(참조변수 instanceof 타입명(클래스명))

 


 

Customer 클래스만들어서 응용해 보기

 

Silver고객 / Gold고객(할인) / VIP고객(할인)
  - Silver 고객
   => 제품을 구매할 때 0% 할인 / 보너스 포인트 1% 적립
  - Gold 고객
   => 제품을 구매할 때 10% 할인 / 보너스 포인트 2% 적립
  - VIP 고객
   => 제품을 구매할 때 10% 할인 / 보너스 포인트 5% 적립
   => 전담 상담사 
Customer / GoldCustomer / VipCustomer 클래스 생성
GoldCustomer , ViPCustomer => Customer 클래스 상속

 

public class Customer {
	
	protected String customerID;
	protected String customerName;
	protected String customerGrade = "Silver";
	protected int bonusPoint;
	protected double bonusRatio;
	
	
	public Customer() {
	}

	public Customer(String customerID, String customerName) {
		this.customerID = customerID;
		this.customerName = customerName;
	}

	public int bonus(Customer customer, int price) {
		
		if(customer instanceof GoldCustomer) {
			bonusRatio = 0.02;
		} else if (customer instanceof VIPCustomer) {
			bonusRatio = 0.05;
		} else {
			bonusRatio = 0.01;
		}
		
		bonusPoint += price*bonusRatio;
			
		return price;
			
	}
	
	public void print(Customer customer) {
		
		if(customer instanceof GoldCustomer) {
			customerGrade = "Gold";
		} else if(customer instanceof VIPCustomer) {
			customerGrade = "VIP";
		}
		
		System.out.println(customerName + "님은 " + customerGrade + "등급이며, " + "보너스 포인트는 " + bonusPoint +"점 입니다." );
	}
	
}


 

고객 아이디, 고객 이름, 고객 등급, 보너스 포인트와 할인율을 선언해 준 후,

보너스 포인트를 적립하고, 할인율을 체크해서 구매금액을 리턴하는 메서드와 출력메서드를 구현.

할인율은 Gold , VIP Customer에 따로 구현하고, 출력메서드는 VIP에 상담사 ID를 따로 선언해서 상담사 부분도 구현.

 

보너스메서드는 업캐스팅 Customer 객체와 , 구매금액을 매개변수로 받아주고, 출력메서드도 Customer 객체를 받음

두 메서드에서 Gold와 VIP의 보너스 적립율과 등급을 설정.

 

public class GoldCustomer extends Customer {
	private double discount; // 할인율
	
	

	public GoldCustomer() {
		super();
		// TODO Auto-generated constructor stub
	}

	public GoldCustomer(String customerID, String customerName) {
		super(customerID, customerName);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int bonus(Customer customer, int price) {
		
		super.bonus(customer, price);
		
		if(customer instanceof GoldCustomer) {
			discount = 0.1;
			price = price - (int)((double)price * discount);
		}
		
		return price;
		
		
	}
	
}

 

Extends로 상속해서 확장.

생성자를 만들어주고, 만들어놨던 bonus 메서드를 상속해서 할인율을 적용한 구매금액을 리턴하도록 함.

 

public class VIPCustomer extends Customer {
	private double discount;
	private String agentID;
	

	
	public VIPCustomer() {
		super();
		// TODO Auto-generated constructor stub
	}

	public VIPCustomer(String customerID, String customerName) {
		super(customerID, customerName);
		// TODO Auto-generated constructor stub
	}
	
	public VIPCustomer(String customerID, String customerName, String agentID) {
		super(customerID, customerName);
		this.agentID = agentID;
		// TODO Auto-generated constructor stub
	}
	

	@Override
	public int bonus(Customer customer, int price) {
		
		super.bonus(customer, price);
		
		if(customer instanceof VIPCustomer) {
			discount = 0.1;
			price = price - (int)((double)price * discount);
		}
		
		return price;
	}
	
	@Override
	public void print(Customer customer) {
		// TODO Auto-generated method stub
		
		super.print(customer);
		System.out.println("전담 상담사 번호는 " + agentID + "입니다.");
	}
}

 

VIP에는 Gold에서 했던 bonus 메서드뿐만 아니라 출력메서드도 상속해 주고 상담사 아이디까지 추가해서 출력할 수 있도록 구현해 줌.

 

날짜 / 시간 클래스

Date 클래스 => Deprecated ( 비권장 )

Calendar => Date 후속작. 추상클래스 => 객체를 생성할 수 없음.

new 키워드로 객체 생성이 불가능.

getInstance() 메서드를 이용하여 객체를 얻어 옴

.get으로 값을 가져와야 함.

 

Claendar로 표시할 때 매번 값을 가져와 표시하기 번거로우니

LocalDateTime을 사용

LocalDateTime today = LocalDateTime.now();

이렇게 생성해 주고

String t = today.toString(); 을 이용해서  String으로 변환시켜 줄 수 있음

변환시키면 

String date = t.substring(0, t.indexOf("T")); 처럼 잘라서 원하는 부분을 잘라서 표현하기 편해짐.

 

이 캘린더에서 받은 날짜를 패턴에 맞춰 출력해 주는 DateTimeFormatter가 존재.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
System.out.println(dtf.format(today)); 로 현재 시간을 넣어서 입력한 패턴에 맞춰 표시할 수 있고,

LocalDateTime sDate = LocalDateTime.of(1998, 10, 18, 3, 30); 처럼 본인이 시간을 입력가능.

 

Date 형식의 날짜를 패턴의 맞춰 출력해 주는 SimpleDateFormat 도 존재.

 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd (E) hh:mm:ss");

System.out.println(sdf.format(date));  << String 형식으로 변경 

 

날짜모양의 문자열을 Date로 변경가능.

String dateStr = "2024-10-7(월) 04:48:00";
Date date2 = null;
date2 = sdf.parse(dateStr);
System.out.println(date2);

 

여기서 parse를 쓸 때  throw ParseException 처리를 하거나 try catch를 활용해야 하고,

dateStr의 문자열은 입력한 패턴의 형식을 맞춰야 함.

RuntimeException : 실행 예외 클래스

 

Exception : 예외

- 개발자가 코드를 구현시 발생할 수 있는 에러를 예외

- 예외처리 : 예외를 개발자가 처리하는 구문

- 예외가 발생하면 예외 발생 시점부터 코드는 중지 => 예외문구 출력

- 예외처리 => 예외가 발생할 수 있는 값만 빼고, 나머지는 정상처리로 유지시키기 위한 기능

 

throws는 예외적으로 RuntimeException만 생략가능

 

try ~ catch

try ~ catch ~ finally

try : 예외가 발생할 가능성이 있는 구문 작성

catch : try 구문에서 발생한 예외를 처리

finally : try 구문과 상관없이 반드시 처리되어야 하는 구문을 작성

 

throws : 예외 떠넘기기 = 메인에서 넘기면 컴파일러가 알아서 처리.

단, 계속 떠넘기면 컴파일러에 부담이 갈 수 있음. 

 

자주 발생하는 예외 코드들

ArithmeticException : 0으로 나누었을 때 발생

ArrayIndexOutOfBoundsException : 배열의 index가 범위를 벗어났을 때 발생

NullPointerException : 객체의 값이 null일 경우, 혹은 객체 자체가 없을 경우

ClassCastException : 다운 캐스팅이 잘못되었을 경우

 

 

 

'자바 수업 정리' 카테고리의 다른 글

수업정리 14일차.  (0) 2024.10.10
수업정리 13일차.  (2) 2024.10.08
수업정리 11일차.  (0) 2024.10.04
수업정리 10일차.  (1) 2024.10.02
수업정리 9일차.  (1) 2024.09.30