유난스런 개발 기록

[JAVA] Day-14 _ 상속성 (Inheritance) 본문

개념정리/JAVA

[JAVA] Day-14 _ 상속성 (Inheritance)

yourhwan 2023. 1. 29. 20:45

day-14

상속성 (Inheritance)


상속성 (Inheritance) 이란? 

  • 클래스의 재사용소스코드의 중복최소화하는 목적으로 사용
  • 상속의 종류는 extends 와 implements 가 있다. 오늘은 extends 에 대해 알아볼 것이다.
  • 부모 클래스와 자식 클래스로 나뉘는데, 부모 클래스의 데이터를 물려 받는 클래스를 자식 클래스라고 한다.
  • 이 때 데이터의 이동상위 클래스에서 하위 클래스로만 가능하다 (부모 클래스 -> 자식 클래스)
  • 부모 클래스는 추상 클래스이므로 객체 생성이 불가능하며, 자식 클래스에서 객체를 생성해야한다.
  • 부모 클래스에서 상속 받은 것 이외에 다른 것이 필요하다면, 자식 클래스에서 추가적으로 생성하면 된다.
  • 이 때 부모 클래스로 부터 전달 받은 데이터 중, 메소드를 자식 클래스에서 수정하여 사용하는 것을
  • 메소드의 오버라이딩(Overriding) 이라고 한다. (오버라이딩과 오버로딩에 대해서는 다음에 정리하도록 하자.)

 

그렇다면 자바에서는 상속을 어떻게 할까?

public class 상속 받을 클래스(자식클래스) extends (상속을 할 클래스) {}

기존 클래스 이름 뒤에 extends 와 상속할 클래스 즉 상위 클래스인 부모 클래스를 넣어주면 된다.

주의할 점은 자바에서는 클래스의 다중상속이 불가능하다!

즉, 하나의 자식 클래스가 여러개의 부모 클래스로 부터 상속을 받는 것은 불가능하다.

대신에 인터페이스라는 기능이 있다. 이 부분은 차후에 정리해서 포스팅할 계획이다.

 

이제 상속을 예시코드로 통해 확인해보자.

해당 프로그램은 수업시간에 구현한 구인구직 사이트의 코드 중 일부이다.

 

부모 클래스 (상위 클래스)

public class Member {

// field 생성
private String id;            // 아이디
private String passwd;        // 비밀번호
private String name;          // 성명(개인성명, 회사명)
private String register_day;  // 가입일자

// 기본생성자
public Member() {
    System.out.println(">>> 확인용 부모클래스인 Member 클래스 생성자 호출됨.!!");

    Date now = new Date(); // 현재시각 
    SimpleDateFormat sdfmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    register_day = sdfmt.format(now);
}

// method 생성
public String getId() {
    return id;
}

public void setId(String id) {

    if(id != null && !id.trim().isEmpty()) {
        this.id = id;
    }
    else {
        System.out.println("[경고] 아이디는 공백인 아닌 글자로 입력하셔야 합니다.\n");
    }

}

public String getPasswd() {
    return passwd;
}

public void setPasswd(String passwd) {

    if( MyUtil.isCheckPasswd(passwd) ) {
        this.passwd = passwd;
    }
    else {
        System.out.println("[경고] 비밀번호는 8글자 이상 15글자 이하의 대,소문자,숫자,특수기호가 혼합되어야만 합니다.\n"); 
    }

}

public String getName() {
    return name;
}

public void setName(String name) {

    System.out.println("=======[확인용] 이 setName 메소드는 부모인 Member 클래스에서 생성한 것임.");

   // name 에는 한글만 허용하겠다.

    if(name != null) {

      // 정규표현식(Regular Expression)이란?
      // ==> 특정한 규칙을 가진 문자열의 집합을 표현하기 위해 쓰이는 형식언어 

      // == 1. 정규표현식(Regular Expression) 패턴을 작성한다. == //
        Pattern p = Pattern.compile("^[가-힣]{2,5}$");
      // ^ 은 시작을 의미한다.
      // $ 는 끝을 의미한다.
      // [] 는 글자 1개가 들어오는 것을 의미한다.
      // {2,5} 은 반복되어지는 회수를 말하는데 2번 또는 3번 또는 4번 또는 5번 까지를 허용한다는 말이다.

      // == 2. 검사할 문자열이 주어진 정규식 패턴과 일치하는지 아닌지를 판별하는 객체를 생성한다. == //
        Matcher m = p.matcher(name);

      // == 3. 검사할 문자열을 판별하도록 한다. == //
      // 입력받은 jubun 이 주어진 정규식 패턴과 일치하면 true, 일치하지 않으면 false 를 리턴시켜준다.  
        boolean bool = m.matches();

        if(bool) 
            this.name = name;	

        else 
            System.out.println(">> 성명은 공백없이 한글로만 2글자 부터 5글자 이내로만 가능합니다. <<\n"); 

    }
    else {
        System.out.println("[경고] 성명은 필수로 공백이 아닌 것으로 입력하셔야 합니다.");
    }

}

public String getRegister_day() {
    return register_day;
}


public void input_name(String name) {
    this.name = name;
}


}

 

 

자식 클래스 (하위 클래스)

public class Gujikja extends Member {
// Member  ==> 부모클래스 
// Gujikja ==> 자식클래스

    // field(속성) 생성
    private String jubun;     // 주민번호 앞의 7자리 까지만
                              // 예: "9512201" 남자  "0112203" 남자
                              // 예: "9512202" 여자  "0112204" 여자

    private int hope_money;   // 희망연봉

    static int count; // Gujikja 객체(인스턴스)의 개수를 알아오려는 용도 

    // 기본생성자
    public Gujikja() {
        System.out.println("### 확인용 자식클래스인 Gujikja 클래스 생성자 호출됨.!! ###\n");
    }

    // method 생성 
    public void setJubun(String jubun) {

        if( MyUtil.isCheckJubun(jubun) ) 
            this.jubun = jubun;

        else 
            System.out.println("[경고] 주민번호를 올바르게 입력하세요!!\n 예>9501182 \n");

    }// end of public void setJubun(String jubun)------------------


    public String getJubun() {
        return jubun;
    } // end of public String getJubun()-----------------


    public int getHope_money() {
        return hope_money;
    }

    public void setHope_money(int hope_money) {

        if(hope_money > 0) {
           this.hope_money = hope_money;
        }
        else {
            System.out.println("[경고] 희망연봉은 0 보다 커야 합니다.\n");
        }
    }

    ///////////////////////////////////////////////////////////////////

    // == 구직자의 성별을 알려주는 메소드 생성하기 == 
    String getGender() {

        String gender = "";

        switch (jubun.substring(6)) {
            case "1":
            case "3":	
                gender = "남";
                break;

            default:
                gender = "여";
                break;
        }// end of switch()--------------

        return gender;
    }// end of String getGender()-------------------------


    // == 구직자의 현재나이를 알려주는 메소드 생성하기 ==  
    int getAge() {

        // 현재나이 = 현재년도 - 태어난년도 + 1;

        Calendar currentDate = Calendar.getInstance();    // 현재날짜와 시간을 얻어온다. 
        int currentYear = currentDate.get(Calendar.YEAR); // 2023

        int centry = ( "1".equals(jubun.substring(6)) || "2".equals(jubun.substring(6)) )?1900:2000; 

        int birthYear = Integer.parseInt(jubun.substring(0,2)) + centry; 
        // 태어난 년도 

        return currentYear - birthYear + 1;

    }// end of int getAge()------------------------ 


    // == 구직자의 정보를 한줄로 리턴시켜주는 메소드 생성하기 == 
    String getInfo() {

        // eomjh   qwer******    엄정화   여      29   2023-01-17 15:30:20   5,000만원

        StringBuilder sb = new StringBuilder();

        sb.append(getId()+"\t");

        String star = "";
        for(int i=0; i<super.getPasswd().length()-4; i++) {
            star += "*";
        }
        sb.append(super.getPasswd().substring(0, 4) + star +"\t");

        sb.append(this.getName()+"\t");
        sb.append(getGender()+"\t");
        sb.append(getAge()+"\t");
        sb.append(super.getRegister_day()+"\t");

        DecimalFormat df = new DecimalFormat("#,###"); // 3자리 마다 콤마를 찍어주는 것이다.
        sb.append(df.format(hope_money)+"만원");

        return sb.toString();

    }// end of String getInfo()----------------------------

    //////////////////////////////////////////////////////////

    @Override
    public String toString() {

        DecimalFormat df = new DecimalFormat("#,###"); // 3자리 마다 콤마를 찍어주는 것이다.

        return "1.아이디 : " + super.getId() + "\n"
             + "2.비밀번호 : " + this.getPasswd() + "\n"
             + "3.성명 : " + getName() + "\n"
             + "4.주민번호 : " + jubun + "\n"
             + "5.희망연봉 : " + df.format(hope_money) + "만원\n";

    }// end of public String toString()----------------------------


    }

 

자식 클래스(하위 클래스)인 Gujiukja는 Member 클래스에게 상속을 받았고,

Gujiukja 클래스에서만 추가로 필요한 필드를 따로 생성해주었다. (jubun, hope_money, count)

그리고 추가적으로 생성한 필드에 대한 get/set 메소드를 생성해준 것과

getId, getName, getPasswd 등을 부모 클래스로 부터 호출하여 사용 중인 것을 확인할 수 있다.

코드 마지막 부분에서는

java.lang.Object 에서 제공하는 toString 메소드를 상속 받아 세자리 마다

콤마를 찍어주는 코드를 추가하여 재정의한 메소드의 오버라이딩을 확인할 수 있다.

 

수업 시간에 개념 설명을 들을 때는 무난하게 이해했지만,

이렇게 실습을 통해,

특히나 많은 코드를 치며 수업을 따라가다보면 핵심을 잊는 경우가 있었다.

(내가 실습 코드의 흐름을 따라가기 전에 휙휙 넘어가는 경우가 많기 때문)

 

블로그 업로드를 하고, 따로 복습도 다시 해보니 수업시간에 작성했던 코드들의 흐름과 내용이 보인다!

 

앞으로도 꾸준히 공부하자