Skip to main content

[Java] 다형성, 오버라이드, String

Published 11 min readMarkdown
Part of seriesTIL
[Java] 다형성, 오버라이드, String

병원 입퇴원 관리 시스템 (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

No comments yet. Be the first to comment.

More from this blog