목차 | |
1. | polymorphism |
2. | Date |
3. | Exception |
1. polymorphism
■ 이론
▣ polymorphism01
package day06;
/* 객체지향 프로그램
* - 프로그램 독립된 단위(객체)의 객체들을 모아서 관계를 맺어 처리하는 형태
* - 각각의 객체는 메시지를 주고 받으면서 데이터를 처리
* - 메시지를 받을 경우(매개변수를 통해) / 메시지를 주는 경우 (return)
* - 추상화, 캡슐화(정보은닉), 상속, 다형성
*
* - 추상화(Abstraction) - 핵심적인(공통적인) 코드만 보여주기
* - 구현된 부분과 구현되지 않은 부분으로 분리
* - 개인(자식)이 구현해야 할 부분은 분리하여 처리
*
* - 캡슐화(Encapsulation) - 데이터 보호(정보은닉)
* - 멤버변수(private)를 숨기는 형태, 메서드로 접근
* - 멤버변수와 메서드를 하나로 묶어 처리하는 형태
* - 은닉화 : 객체의 내부의 정보를 숨겨 외부로 드러나지 않게 보호하는 것
*
* - 상속(Inheritance) - 코드 재사용(확장)
* - 클래스를 상속받아 수정하면 중복 코드를 줄일 수 있음.
* - 유지보수가 편함.
*
* - 다형성(Polymorphism) - 객체 변환이 용이함.
* - 하나의 코드가 여러 객체의 형태로 구현되어 실행되는 것
* - 코드는 같은데 들어오는 객체에 따라 다른 실행결과를 얻을 수 있음.
* - 다형성을 잘 활용하면 유연하고, 확장성있는, 유지보수가 편리한 프로그램을 만들 수 있음.
*/
class Animal{
// 공통적인 속성
public void move() {
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal {
@Override
public void move() {
System.out.println("사람은 두 발로 걷습니다.");
}
public void readBook() {
System.out.println("사람이 책을 읽습니다.");
}
}
class Tiger extends Animal{
@Override
public void move() {
System.out.println("호랑이가 네 발로 어슬렁거립니다.");
}
public void hunting() {
System.out.println("호랑이가 사냥을 합니다.");
}
}
class Eagle extends Animal{
@Override
public void move() {
System.out.println("독수리가 하늘을 날아다닙니다.");
}
public void flying() {
System.out.println("독수리가 날카로운 눈으로 날아다닙니다.");
}
}
class Dog{
public void move() {
System.out.println("강아지가 아장아장 걷습니다.");
}
}
public class Polymorphism01 {
public static void main(String[] args) {
// Human, Tiger, Eagle 객체 생성
Human human = new Human();
human.move();
human.readBook();
System.out.println("----------------");
Tiger tiger = new Tiger();
tiger.move();
tiger.hunting();
System.out.println("----------------");
Eagle eagle = new Eagle();
eagle.move();
eagle.flying();
System.out.println("--조상의 객체로 자식의 객체를 생성--");
// 조상의 클래스로 자식의 객체를 생성 가능.
// 조상에게 상속받은 메서드만 실행가능.
// 자식객체로 부모객체의 생성은 불가능
// Human h = new Animal(); // 불가능
Animal hAnimal = new Human();
hAnimal.move();
// hAnimal.readBook(); // 사용불가능.
Animal tAnimal = new Tiger();
tAnimal.move();
Animal eAnimal = new Eagle();
eAnimal.move();
System.out.println();
System.out.println("--다형성 메서드 예시--");
Polymorphism01 ex01 = new Polymorphism01();
// 부모의 객체로 생성이 되었기 떄문에 당연히 가능
ex01.moveAnimal(eAnimal);
ex01.moveAnimal(tAnimal);
ex01.moveAnimal(hAnimal);
// 자신의 객체로 생성되었다 하더라도 자동 형변환이 이루어져 출력가능.
ex01.moveAnimal(eagle);
ex01.moveAnimal(tiger);
ex01.moveAnimal(human);
Dog dog = new Dog();
dog.move();
// animal 클래스를 상속받고 있지 않기 때문에 불가능.
// ex01.moveAnimal(dog);
System.out.println("-- Animal 배열 생성 예시 --");
int cnt = 0;
Animal[] aniList = new Animal[5];
aniList[cnt] = hAnimal;
cnt++;
aniList[cnt] = tAnimal;
cnt++;
aniList[cnt] = eAnimal;
cnt++;
for(int i = 0; i < cnt; i++) {
aniList[i].move();
}
System.out.println();
System.out.println("-- 다운 케스팅 예시 --");
// Human클래스 객체에 Animal을 상속받은 Human 클래스 객체를 다운 케스팅한 예시
Human h = (Human)hAnimal;
h.readBook();
// Human h1 = (Human)tAnimal;
// h1.readBook(); // casting 오류
// instanceof 연산자로 확인하여 실행
System.out.println();
System.out.println("--instanceof 연산자--");
// instanceof : 객체가 해당 클래스의 형이 맞는지 확인
System.out.println(tAnimal instanceof Human);
System.out.println(tAnimal instanceof Tiger);
System.out.println(tAnimal instanceof Eagle);
Animal downCastingTest = eAnimal;
if(downCastingTest instanceof Human) {
// ((Human) downCastingText).readBook();
Human testHuman = (Human) downCastingTest;
testHuman.readBook();
}else if(downCastingTest instanceof Tiger) {
((Tiger) downCastingTest).hunting();
}else if(downCastingTest instanceof Eagle) {
((Eagle) downCastingTest).flying();
}else {
System.out.println("error");
}
}
// 다향성 예시 메서드 (업케스팅 : 자동형변환 가능)
public void moveAnimal(Animal animal) {
animal.move();
if(animal instanceof Human) {
((Human) animal).readBook();
}else if(animal instanceof Tiger) {
((Tiger) animal).hunting();
}else if(animal instanceof Eagle) {
((Eagle) animal).flying();
}else {
System.out.println("error");
}
}
}
▷ 출력
▣ CustomerMain
package day06;
/* Silver 고객 / Gold 고객(할인) / VIP 고객(할인)
* - Silver 고객
* => 제품을 구매할 때 0% 할인 / 보너스 포인트 1% 적립
* - Gold 고객
* => 제품을 구매할 때 10% 할인 / 보너스 포인트 2% 적립
* - VIP 고객
* => 제품을 구매할 때 10% 할인 / 보너스 포인트 5% 적립
* => 전담 상담사
*
* Customer / GoldCustomer / VIPCustomer 클래스 생성
* GoldCustomer / VIPCustomer => Customer 클래스 상속
*/
public class CustomerMain {
public static void main(String[] args) {
// 업캐스팅 : 부모의 객체 배열에 자식 객체의 값을 넣을 수 있는 것은 업캐스팅이 가능하기 때문이다
// 업캐스팅은 자동 형변환
Customer[] customerList = new Customer[10];
Customer cLee = new Customer(1001, "이정혁");
Customer cHong = new Customer(1002, "홍길동");
Customer cKim = new GoldCustomer(1003, "김철수");
Customer cChoi = new GoldCustomer(1004, "최유진");
int cnt = 0;
customerList[cnt] = cLee;
cnt++;
customerList[cnt] = cHong;
cnt++;
customerList[cnt] = cKim;
cnt++;
customerList[cnt] = cChoi;
cnt++;
customerList[cnt] = new VIPCustomer(1005, "박영희", 1111);
cnt++;
customerList[cnt] = new VIPCustomer(1006, "김영수", 2222);
cnt++;
customerList[cnt] = new VIPCustomer(1007, "순이", 1111);
cnt++;
customerList[cnt] = new VIPCustomer(1008, "김영철", 2222);
cnt++;
System.out.println("-- 할인율과 포인트 계산 --");
int price = 100000;
// 모든 손님 대상
// 홍길동님의 지불금액은 100000 / 포인트는 1000입니다.
for(int i = 0; i < cnt; i++) {
// 보너스 포인트 적립 => 금액 리턴
int salePrice = customerList[i].calcPrice(price);
System.out.println(customerList[i].getCustomerName() + "님의 지불금액은 " + salePrice + " / 포인트 " + customerList[i].getBonusPoint());
System.out.println("--------------------");
}
// 다운캐스팅 : 부모의 공유되는 멤버변수나 메서드가 아닌
// 자식 고유의 멤버변수나 메서드를 호출하고자 할 경우 사용
// 다운캐스팅시 반드시 명시적으로 형변환 해야함.
// agentID = 1111 => 3333 변경
System.out.println("-------------");
for(int i = 0; i < cnt; i++) {
Customer c = customerList[i];
if(c instanceof VIPCustomer) {
VIPCustomer vip = (VIPCustomer)c;
if(vip.getAgentID() == 1111) {
vip.setAgentID(3333);
customerList[i].customerInfo();
}
}
}
// 고객 정보 출력
for(int i = 0; i < cnt; i++) {
customerList[i].customerInfo();
}
}
}
▣ Customer
package day06;
import java.util.Scanner;
/* customerID : 고객ID
* customerName : 고객이름
* customerGrade : 고객등급
* bonusPoint
* bonusRatio : 0.01 => 1%
*
* 기본 customerGrade = Silver
*
* 메서드
* 1. 보너스 적립 계산 메서드
* => 구매 금액을 주고 적립 보너스를 계산하여 bonusPoint 누적
* => 보너스 적립, 할인여부를 체크하여 구매금액을 리턴
*
* 2. 출력
* => 홍길동님은 VIP등급이며, 보너스 포인트는 5000점입니다.
* 전담 상담사 번호는 1111입니다. <- VIP만 추가 (agentID)
*/
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
protected int bonusPoint;
protected double bonusRatio;
// 생성자
public Customer() {}
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;
customerGrade = "Silver";
bonusRatio = 0.01;
}
// 메서드
// 가격 매개변수로 받아 => 포인트 적립, 할인가격 리턴
public int calcPrice(int price) {
bonusPoint += (int)(price * bonusRatio);
return price; // Silver등급은 할인이 없음.
}
// 출력메서드
/* 홍길동님은 VIP등급이며, 보너스 포인트는 5000점입니다.
* 전담 상담사 번호는 1111입니다. <- VIP만 추가 (agentID)
*/
public void customerInfo() {
System.out.println(customerName + "님은 " + customerGrade + "등급이며, 보너스 포인트는 " + bonusPoint + "점 입니다.");
}
// getter & setter
public int getCustomerID() {
return customerID;
}
public void setCustomerID(int customerID) {
this.customerID = customerID;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerGrade() {
return customerGrade;
}
public void setCustomerGrade(String customerGrade) {
this.customerGrade = customerGrade;
}
public int getBonusPoint() {
return bonusPoint;
}
public void setBonusPoint(int bonusPoint) {
this.bonusPoint = bonusPoint;
}
public double getBonusRatio() {
return bonusRatio;
}
public void setBonusRatio(double bonusRatio) {
this.bonusRatio = bonusRatio;
}
@Override
public String toString() {
return "Customer [customerID=" + customerID + ", customerName=" + customerName + ", customerGrade="
+ customerGrade + ", bonusPoint=" + bonusPoint + ", bonusRatio=" + bonusRatio + "]";
}
}
▣ GoldCustomer
package day06;
public class GoldCustomer extends Customer{
private double saleRatio; //할인율 Gold, VIP만 존재
public GoldCustomer() {}
// => 제품을 구매할 때 10% 할인 / 보너스 포인트 2% 적립
public GoldCustomer(int id, String name) {
super(id, name);
customerGrade = "Gold";
bonusRatio = 0.02;
saleRatio = 0.1;
}
// 할인금액 리턴이 필요한 calcPrice 오버라이딩
@Override
public int calcPrice(int price) {
bonusPoint += (int)(price * bonusRatio);
return price - (int)(price * saleRatio);
}
public double getSaleRatio() {
return saleRatio;
}
public void setSaleRatio(double saleRatio) {
this.saleRatio = saleRatio;
}
}
▣ VIPCustomer
package day06;
public class VIPCustomer extends Customer{
private double saleRatio; // 할인율 Gold, VIP만 존재
private int agentID; // VIP만 존재
public VIPCustomer() {}
public VIPCustomer(int id, String name, int agentid) {
super(id, name);
customerGrade = "VIP";
bonusRatio = 0.05;
saleRatio = 01.;
agentID = agentid;
}
// 할인금액 리턴이 필요한 calcPrice 오버라이딩
@Override
public int calcPrice(int price) {
bonusPoint += (int)(price * bonusRatio);
return price - (int)(price * saleRatio);
}
@Override
public void customerInfo() {
// TODO Auto-generated method stub
super.customerInfo();
System.out.println("담당 상담원 번호는 " + agentID + "입니다.");
}
public double getSaleRatio() {
return saleRatio;
}
public void setSaleRatio(double saleRatio) {
this.saleRatio = saleRatio;
}
public int getAgentID() {
return agentID;
}
public void setAgentID(int agentID) {
this.agentID = agentID;
}
}
▷ 출력
2. Date
▣ Date01
package day06;
import java.util.Calendar;
import java.util.Date;
public class Date01 {
public static void main(String[] args) {
/* 날짜 / 시간 클래스
* Date 클래스 => Deprecated(비권장)
* Calendar => Date 후속작, 추상클래스 => 객체를 생성할 수 없음.
* new 키워드로 객체 생성이 불가능
* getInstance() 메서드를 이요하여 객체를 얻어 옴
*/
Date d = new Date();
System.out.println(d);
// d.getDate();
Calendar c = Calendar.getInstance(); // 오늘 날짜
System.out.println(c);
System.out.println("---------------");
// month 0 ~ 11 +1 표현
int year = c.get(Calendar.YEAR);
System.out.println(year);
int month = c.get(Calendar.MONTH) + 1;
System.out.println(month);
int day = c.get(Calendar.DAY_OF_MONTH);
System.out.println(day);
int week = c.get(Calendar.DAY_OF_WEEK);
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int AmPm = c.get(Calendar.AM_PM);
// 일 = 1...
System.out.println(week);
System.out.println(year+"-"+month+"-"+day);
// 2024-10-7(월) 오후 3:51
int num = c.get(Calendar.DAY_OF_WEEK_IN_MONTH);
char sun = ' ';
String am_pm = AmPm == 1 ? "오후" : "오전";
switch(num) {
case 1: sun = '월'; break;
case 2: sun = '화'; break;
case 3: sun = '수'; break;
case 4: sun = '목'; break;
case 5: sun = '금'; break;
case 6: sun = '토'; break;
case 7: sun = '일'; break;
default: System.out.println("error");
}
System.out.println(year+"-"+month+"-"+day+"("+sun+") "+am_pm+" "+hour+":"+minute);
}
}
▷ 출력
▣ Date02
package day06;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Date02 {
public static void main(String[] args) {
// LocalDateTime
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
System.out.println(today.getYear());
String t = today.toString();
System.out.println(t);
String date = t.substring(0, t.indexOf("T"));
System.out.println(date);
String hms = t.substring(t.indexOf("T")+1, t.indexOf("."));
System.out.println(hms);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
System.out.println(dtf.format(today));
LocalDateTime date1 = LocalDateTime.of(2005,1,1,8,30);
System.out.println(date1.format(dtf));
}
}
▷ 출력
▣ Date03
package day06;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Date03 {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date);
// yyyy-MM-dd(E) hh:mm:ss
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd(E) hh:mm:ss");
// String 형식으로 변경
System.out.println(sdf.format(date));
// 날짜 모양의 문자열을 => Date로 변경
String dateStr = "2024-10-07(월) 04:48:00";
Date date2 = null;
try {
date2 = sdf.parse(dateStr);
System.out.println(date2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
▷ 출력
3. Exception
■ 이론
▣ Exception01
package day06;
public class Exception01 {
public static void main(String[] args) {
// RuntimeException : 실행 예외 클래스
/* Exception : 예외
* 개발자가 코드 구현시 발생할 수 있는 에러를 예외
* 예외처리 : 예외를 개발자가 처리하는 구문
* 예외가 발생하면 예외 발생 시점부터 코드는 중지 => 예외문구 출력
* 예외처리 => 예외가 발생할 수 있는 값만을 빼고, 나머지는 정상처리로 유지시키기위한 기능
* try ~ catch
* try ~ catch ~ finally
* try : 예외가 발생할 가능성이 있는 구문 작성
* catch : try 구문에서 발생한 예외를 처리
* finally : try 구문과 상관없이 반드시 처리되어야 하는 구문을 작성 (생략가능)
*/
try {
System.out.println(1);
System.out.println(2);
System.out.println(1/0); // ArithmeticException
} catch (Exception e) {
e.printStackTrace(); // 실제 예외구문을 콘솔에 출력
System.out.println("예외가 발생했습니다.~!!");
} finally {
System.out.println(4);
System.out.println(5);
System.out.println(6);
System.out.println(7);
}
}
}
▷ 출력
▣ Exception02
package day06;
public class Exception02 {
public static void main(String[] args) {
// ArithmeticException : 0으로 나누었을 때 발생하는 Exception
// 1 2 + 1 2 - 1 2 * 1 0 / 1 0 %
Exception02 ex02 = new Exception02();
System.out.println(ex02.calc(1, 0, '/'));
// try {
// //예외가 발생할 수 있는 구문 작성
// System.out.println(ex02.calc(1, 2, '+'));
// System.out.println(ex02.calc(1, 2, '-'));
// System.out.println(ex02.calc(1, 2, '*'));
// System.out.println(ex02.calc(1, 0, '/'));
// } catch (Exception e) {
// // 예외 처리 작성
// e.printStackTrace();
// System.out.println(e.getMessage());
// }
System.out.println(ex02.calc(1, 2, '-'));
}
// 두수를 입력받고, 연산자를 입력받아 4칙연산의 결과를 리턴하는 메서드
// 매개변수 : int num1, int num2, char op
// return Type : double
// 예외 발생시키기 : throw new 발생시킬 수 있음.
// 예외를 발생시키게 되면 메서드 선언부 끝에 throws를 적고, 발생시킨 예외를
// 반드시 적어줘야 함.
// throws는 예외적으로 RuntimeException만 생략가능
// throws : 예외 떠넘기기
public double calc(int num1, int num2, char op) throws RuntimeException {
double res = 0;
//연산자가 / % 인경우 num2 가 0이면 예외 발생시키기
if((op == '/' || op == '%') && num2 == 0) {
throw new RuntimeException("num2는 0이 될 수 없습니다.");
}
switch(op) {
case '+' : res = num1 + num2; break;
case '-' : res = num1 - num2; break;
case '*' : res = num1 * num2; break;
case '/' : res = num1 / num2; break;
case '%' : res = num1 % num2; break;
default :
//예외발생
throw new RuntimeException(op+"는 산술연산자가 아닙니다.");
}
return res;
}
}
▷ 출력
▣ Exception03
package day06;
public class Exception03 {
public static void main(String[] args) {
/* 자주 발생하는 예외 코드들
* ArithmeticException : 0으로 나누었을 때 발생
* ArrayIndexOutOfBoundsException : 배열의 index가 범위를 벗어났을 때 발생
* NullPointerException : 객체의 값이 null일 경우, 혹은 객체 자체가 없을 경우
* ClassCastException : 다운 캐스팅이 잘못 되었을 경우
*/
// int arr[] = null;
int arr[] = new int[5];
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
▷ 출력
'Java' 카테고리의 다른 글
Java 기초(map)- AWS 풀스택 과정 53일차 (4) | 2024.10.10 |
---|---|
Java 기초(polymorphism)- AWS 풀스택 과정 52일차 (10) | 2024.10.08 |
Java 기초(실습)- AWS 풀스택 과정 50일차 (3) | 2024.10.04 |
Java 기초(interface)- AWS 풀스택 과정 49일차 (4) | 2024.10.02 |
Java 기초(extends, abstract)- AWS 풀스택 과정 48일차 (2) | 2024.09.30 |