[Java] 다형성, 오버라이드, String
![[Java] 다형성, 오버라이드, String](https://cdn.hashnode.com/res/hashnode/image/upload/v1706102985047/9028b318-3017-478c-8338-0f2adc897fb4.png)
병원 입퇴원 관리 시스템 (1)
- 환자 정보를 저장하는 Patient
public class Patient {
private int patient_id; // 환자 등록번호
private double temperature; // 환자 체온
private int blood_pressure_high; // 환자 혈압 (위)
private int blood_pressure_low; // 환자 혈압 (아래)
// 생성자
public Patient(int patient_id, double temperature, int blood_pressure_high, int blood_pressure_low) {
super();
this.patient_id = patient_id;
this.temperature = temperature;
this.blood_pressure_high = blood_pressure_high;
this.blood_pressure_low = blood_pressure_low;
}
public int getID() {
return patient_id;
}
public double getTemp() {
return temperature;
}
public int getBPHigh() {
return blood_pressure_high;
}
public int getBPLow() {
return blood_pressure_low;
}
} // class
병원 입퇴원 관리 시스템 (2)
- 병원 입퇴원 관리 Hospital
public class Hospital {
private Patient[] rooms; // 입원실 배열
private int occupied; // 환자가 입실중인 입원실의 개수
// 병원 객체 생성 초기화 메소드, n = 병원이 보유한 입원실의 개수
public Hospital(int n) {
rooms = new Patient[n];
occupied = 0;
}
// 입원실 배열을 리턴한다.
public Patient[] getRoomsInfo() {
return rooms;
}
// 비어있는 입원실이 있는지 여부를 리턴한다.
public boolean roomAvailable() {
if(occupied < rooms.length){
return true;
}
return false;
}
//환자 등록번호 id로 입원 중인 환자를 찾는다.
public Patient findPatient(int id) {
for(int i = 0 ; i < rooms.length ; i++){
if(rooms[i] != null && rooms[i].getID() == id){
return rooms[i];
}
}
return null;
}
// 환자 p를 입실시킨다.
//빈 입원실이 있어서 입실 성공하면 true, 없어서 실패하면 false
public boolean admit(Patient p) {
if(roomAvailable()){
for(int i = 0 ; i < rooms.length ; i++) {
if (rooms[i] == null) {
rooms[i] = p;
occupied++;
return true;
}
}
}
return false;
}
// 환자 p를 퇴실시킨다.
// 환자를 찾아서 퇴실 성공하면 true, 실패하면 false
public boolean discharge(Patient p) {
for(int i = 0 ; i < rooms.length ; i++){
if(rooms[i] == p && rooms[i] != null){
rooms[i] = null;
occupied--;
return true;
}
}
return false;
}
} // class end
병원 입퇴원 관리 시스템 (3)
- 사용자 입력을 처리하는 HospitalController
- 또는 -를 Console에서 입력 받는다.
- 이면 입원 관리
if
- 이면 입원 관리
빈 입원실이 있으면 → if , roomAvailable() 체온, 혈압(상), 혈압(하)를 차례로 입력 대화창에서 입력받아 환자 객체를 만들고 입실시킨다. Patient p = new Patient(); , admit(Patient p) 빈 입원실이 없으면, → else 출력 메시지 창을 띄워 "병실이 없습니다."를 보여준다.
이면 퇴원 관리
else if퇴실할 환자의 등록번호 id로 환자의 입원실을 찾는다.findPatient(int id)→ 환자존재여부해당 환자가 입원실에 있으면,
if환자를 퇴원시키고,discharge(Patient p)출력 메시지 창을 띄워 "id 환자 퇴원 합니다."를 보여준다. 해당 환자가 입원실에 없으면, 출력 메시지 창을 띄워 "id 환자를 찾을 수 없습니다."를 보여준다.
import java.util.Scanner;
public class HospitalController {
private Hospital hospital; // 병원 객체(참조변수)
private int new_id = 1001; // 신규 환자 등록번호, 1001 : 첫 환자의 등록번호
public HospitalController(Hospital h) {
hospital = h;
}
// 입원실 관리 서비스 (무한 루프)
public void manageRooms() {
while (true) {
Scanner sc = new Scanner(System.in);
double temperature;
int bp_high, bp_low, id;
Patient p; // 객체를 참고하고 있지않은 참조변수 p
System.out.print("(+)입원, (-)퇴원 =>");
String input = sc.next();
if(input.equals("+")){ // if(input.equals("+") == true){
if(hospital.roomAvailable()){ // if(hospital.roomAvailable() == true) {
System.out.println("--입원환자(" + new_id + ")정보 등록--");
System.out.print("입원환자 체온?");
temperature = sc.nextDouble();
System.out.print("입원환자 혈압(상)?");
bp_high = sc.nextInt();
System.out.print("입원환자 혈압(하)?");
bp_low = sc.nextInt();
// 환자입원 : 환자 객체 생성 후, 병실등록 처리
p = new Patient(new_id++, temperature, bp_high, bp_low);
hospital.admit(p);
//new_id++;
}
else{
System.out.println("병실이 없습니다.");
}
}
else if(input.equals("-")){
System.out.print("퇴원환자 번호?");
id = sc.nextInt();
if( hospital.discharge( hospital.findPatient(id) ) ) {
System.out.println(id + " 환자 퇴원 합니다.");
}
else {
System.out.println(id + " 환자를 찾을 수 없습니다.");
}
}
else {
System.out.println("병원 병실 관리 프로그램 종료합니다.");
break;
}
} // while end
} // manageRooms() end
} // class end
병원 입퇴원 관리 시스템 (4)
- 실행
public class HospitalRoomManager {
public static void main(String[] args) {
Hospital h = new Hospital(3); //병원의 병실 수 : 3개
System.out.println("===[SIST 병원 입퇴원 관리 시스템]===");
new HospitalController(h).manageRooms();
// 위 코드와 동일 하다.
//HospitalController hc = new HospitalController(h);
//hc.manageRooms();
}
}
String (1)
String 클래스 : 문자열을 저장하고 이를 다루는데 필요한 메서드를 함께 제공
String 클래스 : 불변
StringBuilder 클래스 : 가변
문자열 길이 :
str.length()n번째 문자 추출 :
str.charAt(n)문자의 위치(인덱스) :
str.indexOf()문자 공백 찾기 :
str.isEmpty()→ false/true소문자로 변환 :
str.toLowerCase()대문자로 변환 :
str.toUpperCase()문자열 바꾸기(ex. n을 N으로) :
str.replace('n', 'N')문자열 추출(n번째 ~ 마지막) :
str.substring(n)문자열 추출(ex.6번째 이상 ~ 11번째 미만)
str.substring(6, 11)문자열 분리(ex.
,을 기준으로 분리하기 :String[] word = str.split(",")- 분리해서 배열에 저장
문자열 비교 (동일한지) :
str1.equals(str2)→ true(일치) / false (불일치)str1.compareTo(str2)→ 0 (일치) / 음수 , 양수 (불일치)compareTo()는 사전순서로 비교한다.
예를 들어, "apple"과 "banana"를 compareTo() 메서드로 비교하면:
"apple".compareTo("banana")는 음수를 반환. 왜냐하면 "apple"은 "banana"보다 알파벳 순서상으로 더 앞에 위치하기 때문
"banana".compareTo("apple")는 양수를 반환. 왜냐하면 "banana"은 "apple"보다 알파벳 순서상으로 더 뒤에 위치하기 때문.
import java.lang.String;
public class StringTest1 {
public static void main(String[] args) {
// "문자열상수", 불변의 데이터(값)
String str1 = new String("하이");
System.out.println(str1);
String str2 = "Hi";
System.out.println(str2);
str2 = "Ho";
System.out.println(str2);
//System.out.println(str1.length); // 에러, 배열 참조변수와 구분
System.out.println(str1.length()); // 2, 문자 개수
// String 클래스 : 불변
// StringBuffer 클래스, StringBuilder 클래스 : 가변(mutable)
// StringBuffer str3 = "SIST"; // 에러
// StringBuilder str4 = "SIST"; // 에러
StringBuffer str3 = new StringBuffer("SIST");
StringBuilder str4 = new StringBuilder("JAVA");
System.out.println(str3);
System.out.println(str4);
System.out.println(str3.length());
System.out.println(str4.length());
str1 = str1 + "java"; // "하이java"
System.out.println(str1);
//str3 = str3 + "자바"; // 에러
//str4 = str4 + "자바"; // 에러
String str = "Gone With The Wind";
// 0번째 문자 추출
System.out.println(str.length()); // 18개
System.out.println(str.charAt(0)); // 'G'
// 마지막번째 문자 추출
System.out.println(str.charAt(17)); // 'd'
System.out.println(str.charAt(str.length()-1));
// 'G'문자의 위치(인덱스)
System.out.println(str.indexOf('G')); // 0번째 문자
// "G"문자의 위치(인덱스), "문자열"로 활용을 권장
System.out.println(str.indexOf("G")); // 0번째 문자
// String str = "Gone With The Wind";
// "G"문자의 위치(인덱스)
System.out.println(str.indexOf("G")); // 0번째 (있음)
// "R"문자/없는 문자열
System.out.println(str.indexOf("R")); // -1 (없음)
// "W"문자/중목 문자열
System.out.println(str.indexOf("W")); // 5번째 (맨처음)
// String str = "Gone With The Wind";
// 문자 찾기
boolean a = false;
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i) == 'G') {
a = true;
System.out.println(i);
break;
}
}
System.out.println(a);
System.out.println(a ? "있음" : "없음");
// 메소드명이...
// set..(설정) get..(참조) to..(변환) is..(~이니?)
System.out.println(str.isEmpty()); // 공백이니? false/true
//str = "";
//System.out.println(str.isEmpty());
System.out.println(str.toLowerCase()); // 소문자로 변환
System.out.println(str);
System.out.println(str.toUpperCase()); // 대문자로 변환
// String str = "Gone With The Wind";
str = str.replace('n', 'N');
System.out.println(str);
System.out.println("================");
// 문자열 추출(자르기)
System.out.println(str.substring(6)); // 6번째~마지막
System.out.println(str.substring(6, 11)); // 6번째이상~11번째미만
// 마지막 글자(한문자) 출력 : 'd'
System.out.println(str.charAt(str.length()-1));
System.out.println(str.substring(17, 18));
System.out.println(str.substring(str.length()-1, str.length()));
// 첫글자
System.out.println(str.charAt(0));
System.out.println(str.substring(0,1));
// 문자열 분리
str = "Gone, With, The, Wind";
String[] word = str.split(", ");
// word[0] : "Gone"
// word[1] : "With"
// word[2] : "The"
// word[3] : "Wind"
for(int i = 0; i < word.length; i++) {
System.out.println(word[i]);
}
for(String s : word)
System.out.println(s);
str1 = new String("Hi");
str2 = "Hi";
System.out.println(str1.equals(str2)); // true (일치) / false (불일치)
System.out.println(str1.compareTo(str2)); // 0 (일치) / 음수, 양수 (불일치)
}
} // class end
String (2)
(문제) 주민번호를 이용해서 아래와 같이 출력
[출력결과] 생년월일 : 2000년11월30일 성별 : 남자 나이 : 21
import java.util.Calendar;
public class StringTest2 {
public static void main(String[] args) {
String jumin1 = "001130";
String jumin2 = "3234567";
String jumin = jumin1 + jumin2;
//String jumin = "0011303234567";
// 생년월일
int myYear = Integer.parseInt(jumin.substring(0, 2)) ; // "00" --> 0
int myMonth = Integer.parseInt(jumin.substring(2, 4));
int myDate = Integer.parseInt(jumin.substring(4, 6));
// 성별(코드) --> 성별 문자열
// int code = 3; // String gender = "남자";
int code = Integer.parseInt(jumin.substring(6, 7));
String gender = "";
switch (code) {
case 1: case 3: gender = "남자"; break;
case 2: case 4: gender = "여자"; break;
}
/*
* switch (code%2) {
* case 0: gender = "여자"; break;
* case 1: gender = "남자"; break;
* }
*/
// 현재년도 --> 나이
Calendar now = Calendar.getInstance();
int cYear = now.get(Calendar.YEAR); // 2023
switch (code) {
case 1: case 2: // 2000년 이전(미만)
myYear = 1900 + myYear;
break;
case 3: case 4: // 2000년 이후(이하)
myYear = 2000 + myYear;
break;
}
int myAge = cYear - myYear;
// 출력
System.out.println("생년월일 : "+myYear+"년"+myMonth+"월"+myDate+"일");
System.out.println("성별 : " + gender);
System.out.println("나이 : " + myAge);
}
}
String (3)
(문제) 10명의 친구 문자열 String[]에서
abc 순서로 sorting(정렬)하는 프로그램 - 선택정렬(오름차순)
compareTo()는 사전순서로 비교if(friends[i].compareTo(friends[j]) > 1이 뜻하는 바는 friends[i]가 friends[j]보다 앞순서면 음수가 나올것. 그 반대면 양수
public class StringTest3 {
public static void main(String[] args) {
String[] friends = {"Jack","John","Aman","Brute","Hank","Canny","Lee","Louis","June","Frank"};
for(int i = 0; i < friends.length-1; i++) {
for(int j = i; j < friends.length; j++) {
if(friends[i].compareTo(friends[j]) > 1) {
String temp;
temp = friends[i];
friends[i] = friends[j];
friends[j] = temp;
}
}
}
for(String s : friends)
System.out.println(s);
// System.out.println("Jack".length()); // 4 ("문자열" 길이)
// System.out.println(friends.length); // 10 (1차원 배열의 크기)
/*
* for(int i = 0; i < friends.length; i++)
* System.out.println(friends[i]);
*/
String (4) - StringTokenizer 클ㄹ
StringTokenizer : 긴 문자열을 지정된 구분자(delimiter)를 기준으로 토큰(token)이라는 여러 개의 문자열로 잘라내는데 사용.
- 구분자로 단 하나의 문자만 사용 가능.
String의
split(), Scanner의useDelimiter()- 정규식 표현을 사용하여 문자열 잘라내기.
| StringTokenizer(String str, String delim) | str을 지정된 delim으로 나눔. 구분자는 토큰 X |
| StringTokenizer(String str, String delim, boolean returnDelims) | str을 delim으로 나눔. |
| returnDelims의 값을 true로 하면 구분자도 토큰 O | |
| int countTokens() | 전체 토큰의 수를 반환 |
| boolean hasMoreTokens() | 토큰이 남아있는지 알려줌 |
| String nextToken() | 다음 토큰을 반환 |
import java.util.StringTokenizer;
// (Ctrl + Shift) + O : 패키지 추가
public class StringTest4 {
public static void main(String[] args) {
String txt = "홍길동/김철수/이영희"; // 불변
StringTokenizer st = new StringTokenizer(txt, "/");
int countTokens = st.countTokens();
System.out.println(countTokens); // 3개
for(int i = 0; i < countTokens; i++) {
String token = st.nextToken(); // (가변) 하나씩 읽고나서, heap memory 에서 제거
System.out.println(token);
}
// System.out.println(st.nextToken()); **(에러) java.util.NoSuchElementException**
// st에는 아무 요소도 남아있지 않음
System.out.println(txt);
// hasMore & nextToken : 대중적인 방식 표현
st = new StringTokenizer(txt, "/");
// hasMoreTokens()과 hasMoreElements() 같은 기능.
while(st.hasMoreElements()) { // hasMoreElements() : 요소가 있는지 판별(true, false)
String token = st.nextToken(); // (가변) 하나씩 읽고나서, heap memory 에서 제거
System.out.println(token);
}
}
}
final (1)
final 변수/필드 : 변수의 상수화
final 메소드 : 더이상(이후에는) override할수 없음
final 클래스 : 종단 클래스, 더이상 자식클래스 생성 할 수 없음
class Animal {
private final int value = 999;
public void one() {}
public final void two() {
System.out.println("two()~");
}
}
class Elephant extends Animal {
@Override
public void one() {
System.out.println("one() overriding!");
}
/* **에러, 부모의 final 메소드는 override할 수 없다.(상속O,재정의X)**
* public final void two() {
* System.out.println("two()~");
* }
*/
}
public class FinalTest {
public static void main(String[] args) {
int a = 3;
a = 300;
final int b = 7;
//b = 10; // 에러, final 변수는 새로운 값을 대입할 수 있다.
//b++;
final double PI = 3.14;
Elephant e = new Elephant();
e.one(); // one() overriding!
e.two(); // two()~
}
}
달력 만들기
import java.util.Calendar;
import java.util.Scanner;
public class InfinityCalendar {
// 선언
Scanner sc = new Scanner(System.in);
Calendar calendar = Calendar.getInstance();
int y, m; // 년, 월 저장
int dayNum; // 요일수 저장
// 입력
void input() {
do {
System.out.print("년도? ");
y = sc.nextInt();
} while(y<1);
do {
System.out.print("월? ");
m = sc.nextInt();
} while(m<1 || m>12);
}
// 연산
void setDate() {
// void java.util.Calendar.set(int year, int month, int date)
// 입력받은 년도와 월을 1일을 기준으로 세팅하고
calendar.set(y, m-1, 1);
// 세팅된 그달의 첫날의 요일수 얻어오기
dayNum = calendar.get(Calendar.DAY_OF_WEEK);
System.out.println("요일수 = " + dayNum);
}
// 출력
void outputTitle() {
System.out.println();
System.out.printf("%2s%2s%2s%2s%2s%2s%2s\\n", "일","월","화","수","목","금","토");
System.out.println("----------------------");
}
void output() {
setDate();
outputTitle();
// 이번달의 총일수 구하기
int daysOfMonth = calendar.getActualMaximum(Calendar.DATE);
// 요일수만큼 커서 옮기기
for(int i=1; i<dayNum; i++) {
System.out.printf("%3s", " ");
}
// 날짜 출력
for(int i=1; i<=daysOfMonth; i++) {
System.out.printf("%3d", i);
// 토요일인가? (토요일의 요일수 : 7)
if(dayNum % 7 == 0)
System.out.println(); // 그럼 한칸 내리기
dayNum++;
}
}
}
public class InfinityCalendarTest {
public static void main(String[] args) {
InfinityCalendar infinityCalendar = new InfinityCalendar();
infinityCalendar.input();
infinityCalendar.output();
}
}
(결과)
년도? 2023
월? 5
요일수 = 2
일 월 화 수 목 금 토
----------------------
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
다형성
여러 가지 형태를 가질 수 있는 능력
- 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록
조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있다.
- 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
1) 업캐스팅
자식 객체(인스턴스)를 부모 클래스 참조변수에 대입할 수 있다.
부모 타입 ← 자식 타입(Up-casting) : 자동 형변환
2) 다운캐스팅(강제형변환) : 업캐스팅된 객체를 다시 원래대로 되돌리는 형변환
자식 타입 ← 부모 타입(Down-casting) : 명시적 형변환 (형변환 생략불가)
부모 클래스를 자식 클래스에 대입할 수 있다.
- (단, 자식형으로 강제 형변환 해야만 한다.)
class School extends Object {
String name = "학교";
String address = "주소";
public School() { }
public School(String name, String address) {
this.name = name;
this.address = address;
}
public void disp() {
System.out.println(this.name);
System.out.println(this.address);
}
} // School class end
class MiddleSchool extends School {
public MiddleSchool() { }
public MiddleSchool(String name, String address) {
//super.name = name;
//super.address = address;
super(name, address);
}
@Override
public void disp() {
System.out.println("=== MiddleSchool disp() ===");
System.out.println(this.name);
System.out.println(this.address);
}
} // MiddleSchool class end
class HighScool extends School {
int friend;
public HighScool() {}
public HighScool(String name, String address) {
super(name, address);
}
}
public class PolyTest1 {
public static void main(String[] args) {
MiddleSchool ms1 = new MiddleSchool(); // 자식 객체 생성 후, 자식 클래스의 기본 생성자 자동호출
ms1.disp();
MiddleSchool ms2 = new MiddleSchool("행복중학교", "서울시"); // 자식 객체 생성 후, 자식 클래스의 매개변수 생성자(부모->자식) 자동호출
ms2.disp();
HighScool hs1 = new HighScool("사랑고등학교", "경기도");
hs1.disp();
// 1) 업캐스팅
//부모클래스 참조변수 자식 객체(인스턴스)
// School sch1 = (School)new MiddleSchool("믿음중학교", "제주도");
School sch1 = new MiddleSchool("믿음중학교", "제주도");
sch1.disp(); // 동적 바인딩(Dynamic Binding) : 오버라이딩된 자식메소드 호출
// 2) 다운캐스팅(강제형변환) : 업캐스팅된 객체를 다시 원래대로 되돌리는 형변환
// (단, 자식형으로 강제 형변환 해야만 한다.)
School sch2 = new MiddleSchool("부모중학교", "강원도");
MiddleSchool ms3;
// ms3 = sch2; // 에러
ms3 = (MiddleSchool)sch2; // 예외주의
ms3.disp();
}
}
Thumbnail :Image by Freepik
![[혼공컴운] 6주차_책 한 권을 끝내다니(Ch 14~ 15)](https://cdn.hashnode.com/res/hashnode/image/upload/v1755441066842/4d3a042e-e395-4e14-84c2-725aeabc56ed.png)
![[혼공컴운] 5주차_끝이 보인다(Ch 12 ~ 13)](https://cdn.hashnode.com/res/hashnode/image/upload/v1754833767926/85ea771d-0416-409a-82d9-bcc62b92cf17.png)
![[혼공컴운] 4주차_운영체제 시작(Ch 09 ~ 11)](https://cdn.hashnode.com/res/hashnode/image/upload/v1753626546414/943e9f66-8c81-4bac-83b6-5797bd83293c.png)
![[혼공컴운] 3주차_컴퓨터 구조 끝(Ch 06 ~ 08)](https://cdn.hashnode.com/res/hashnode/image/upload/v1753020566648/c2832934-e4d5-45c1-87c8-a1d5f27b2169.png)