조컴퓨터

200827 OOP 11 - Java 객체지향 프로그래밍(Ⅰ, Ⅱ) 본문

자바 웹개발자 과정/JAVA

200827 OOP 11 - Java 객체지향 프로그래밍(Ⅰ, Ⅱ)

챠오위 2020. 8. 27. 09:53

지난 시간 이어서 과제 진행

 

 

 

 

Calendar

날짜에 관련된 클래스이다.

일 표시를 Date로 사용한다.

GregorianCalendar를 활용할 수 있다.

 

GregorianCalendar now=new GregorianCalendar();

System.out.println(now.get(Calendar.YEAR));	//2020
System.out.println(now.get(Calendar.MONTH));	//7
System.out.println(now.get(Calendar.MONTH)+1);	//8 <- 더하기, 빼기를 활용해 날짜 조절이 가능하다
System.out.println(now.get(Calendar.DATE));	//27
		
System.out.println(now.get(Calendar.HOUR));	//0 <-오후 12시
//24시간을 기준으로
System.out.println(now.get(Calendar.HOUR_OF_DAY));	//12 <-오후 12시
System.out.println(now.get(Calendar.MINUTE));
System.out.println(now.get(Calendar.SECOND));
		
//요일(1일 2월 3화 4수 5목 6금 7토)
System.out.println(now.get(Calendar.DAY_OF_WEEK));	//5(목요일)
		
//날짜 데이터의 연산
//now날짜에 3년 더하기
now.add(Calendar.YEAR, 3);
System.out.println(now.get(Calendar.YEAR));	//2023
		
//now날짜에 2달 더하기
now.add(Calendar.MONTH, 2);
System.out.println(now.get(Calendar.MONTH));	//9
		
//now날짜에 5일 빼기
now.add(Calendar.DATE, -5);
System.out.println(now.get(Calendar.DATE));	//22

 

 

 

상속 Inheritance

 

현실에서 예를 들면 상속이란 부모가 자식에게 물려주는 행위를 말한다. 

프로그램에서도 마찬가지로 상속이 이루어 진다. 이때 물려주는 부모에 해당하는 클래스를 부모 클래스라 하고, 물림을 받는 자식에 해당하는 클래스를 자식 클래스라 칭한다. 또는 부모 클래스를 조상 클래스, super class라 하며 자식 클래스를 후손 클래스, 파생 클래스, sub class라고도 한다.

 

상속은 IT 면접의 단골 출제 시장이다. (*프로젝트 중요 소재)

 

상속은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 코드의 중복을 줄여준다. 그러나 부모 클래스의 모든 필드와 메소드들을 물려받을 수 있는 것은 아니다. 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외된다. 

 

상속에는 두 가지 종류의 상속이 있다. 이는 extendsimplements이다.

extends를 현실에서 예로 들자면 확장의 형태, 즉 부모님이 인테리어를 싹 해놓은 집을 물려받는 경우를 들 수 있고, implements를 예로 들자면 구현의 형태 즉, 부모님이 빈집을 자식에게 물려주는 경우를 예로 들 수 있다. 

 

클래스의 상속에서는 다중 상속이 불가능하다. 예를 들면,

 

 

 

 

상속의 형식

class 자식 클래스 extends 부모 클래스

예시) class BB extends AA

 

class AA{
private void zero() {}//private 메소드 상속되지 않는다
public void one() {
	System.out.println("AA.one()...");
}
public void two() {
	System.out.println("AA.two()...");
}
}//class end

class BB extends AA{ //부모클래스 AA
		     //자식클래스 BB
public void three() {
	System.out.println("BB.three()...");
}
}//class end

class CC extends BB{ //부모클래스 BB
		     //자식클래스 CC
public void four() {
	System.out.println("CC.four()...");
}
}//class end

class EE{}
/*에러
    클래스는 단일상속만 가능하다
class EE extends AA, DD {}//다중상속 에러(c에서 가능) -> 방법 구현 가능
*/



public class Test02_Sangsok {
	public static void main(String[] args) {

		AA aa=new AA();
		aa.one();
		aa.two();
		//private속성은 클래스 내부에서만 접근가능하다
		//aa.zero(); //에러
		System.out.println("--------------");
		
		BB bb=new BB();
		bb.three();
		bb.one();
		bb.two();
		//bb.zero(); //에러
		System.out.println("--------------");
		
		CC cc=new CC();
		cc.four();
		cc.three();
		cc.one();
		cc.two();
		//cc.zero(); //에러
		System.out.println("--------------");
		
		
	}//main() end
}//class end


/*결과값
AA.one()...
AA.two()...
--------------
BB.three()...
AA.one()...
AA.two()...
--------------
CC.four()...
BB.three()...
AA.one()...
AA.two()...
--------------
*/

 

위와 같이 클래스 상속은 단일 상속만 가능하고, 다중 상속은 불가능하다.

(단, C언어에서는 가능하다.)

 

 

 

Override 메소드 재정의

 

상속된 일부 메소드를 자식 클래스에서 다시 수정해서 사용할 수 있다. 자바에서 이런 기능을 제공하는데 이를 메소드 오버라이딩(overriding)이라 한다.

 

메소드를 오버라이딩할 때는 다음과 같은 규칙을 주의해서 작성해야 한다.

① 부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개변수 리스트)를 가져야 한다.

② 접근 제한을 더 강하게 오버라이딩할 수 없다.

③ 새로운 예외(Exception)를 throw할 수 없다. (단, 예외가 존재하는데, 해당 예외사항은 '예외처리'에서 학습한다.)

 

접근 제한을 더 강하게 오버라이딩할 수 없다는 것은 부모 메소드가 public 접근 제한을 가지고 있을 경우 오버라이딩하는 자식 메소드는 default나 private 접근 제한으로 수정할 수 없다는 뜻이다. 만약 부모 메소드가 default 접근 제한을 가지면 오버라이딩하는 자식 메소드는 default 또는 public 접근 제한을 가질 수 있다.

 

 

 

class Korea {
	String name="대한민국";	//package 생략된 형태
    
	final void view() {
		System.out.println("Korea.view()...");
	}//view() end
	void disp() {
		System.out.println("Korea.disp()..."+name);
	}//disp() end
    
}//class end
		
class Seoul extends Korea {}//class end

class Busan extends Korea {
	String name="부산광역시";
	@Override
	void disp() {
		System.out.println("Busan.disp()...");
	}
	/* final 메소드는 더이상 오버라이드 할 수 없다
	@Override
	void view() {}
	*/
}//class end

public class Test03_override {
	public static void main(String[] args) {
		//Method Override 함수 재정의
		//->상속관계에서 메소드를 다시 수정(리폼)
		
		//1)오버라이드 하기 전
		Seoul se=new Seoul();
		se.disp(); //Korea.disp()...대한민국
		se.view(); //Korea.view()...
		
		//2)오버라이드 한 후
		Busan bu=new Busan();
		System.out.println(bu.name); //부산광역시
		bu.disp(); //Busan.disp()...
		bu.view(); //Korea.view()...
		
		
	}//main() end
}//class end


/* 결과값
Korea.disp()...대한민국
Korea.view()...
부산광역시
Busan.disp()...
Korea.view()...
*/

 

 

extends Object

자바의 모든 클래스들은 Object 클래스를 상속받는다

클래스명 뒤에 .을 쳤을 때 Object 클래스에 포함된 여러 메소드들이 뜬다.

 

 

 

자바의 기본 패키지 java.lang

자바의 최고 조상 클래스 Object 클래스

자바의 모든 클래스는 Object 클래스를 상속받는다. 

 

 

class Jeju extends Object {
	//extends Object 생략 가능
	@Override	//고쳐쓰기 = 오버라이드
	public String toString() {
		return "제주도";
	}
}//class end

class Suwon extends Object {
	//extends Object 생략 가능
	private String id="SOLDESK";	//private 상속불가
	private String pw="1234";
	
	//getter setter
	//toString()
	
	//@Override 코딩시 멤버변수가 가지고 있는 값을 확인하기 위해서 주로 사용한다
	@Override
	public String toString() {
		return "Suwon [id=" + id +", pw=" + pw+"]";
	}
}//class end

class Incheon extends Object {
	//extends Object 생략 가능
	private String name="인천광역시";
	private String phone="5678";
	
	@Override
	public String toString() {
		return "Incheon [name=" + name + ", phone=" + phone + "]";
	}
}//class end


public class Test04_Object {
	public static void main(String[] args) {
		//Object 클래스
		/*
			자바의 최고 조상 클래스 : Object 클래스
			자바의 기본패키지(java.lang)에 선언되어 있음
			자바의 모든 클래스는 무조건 Object 클래스를 상속받는다
            	//public class Test04_Object extends Object
			자바의 모든 클래스는 Object 클래스의 후손들이다(맞다)
			
		*/
		
		Jeju je=new Jeju();
		System.out.println(je.toString()); //제주도. 에러잡는 용도로 자주 사용
		//함수이름 생략가능
		System.out.println(je); //제주도
		
		Suwon su=new Suwon();
		System.out.println(su.toString()); //Suwon [id=SOLDESK, pw=1234]
		System.out.println(su);
		
		Incheon in=new Incheon();
		System.out.println(in.toString()); //Incheon [name=인천광역시, phone=5678]
		System.out.println(in);
		
	}//main() end
}//class end

 

 

 

연습문제) 주민번호 유효성 검사 후 생년월일, 성별, 나이, 띠 출력하기

 

//내 답

import java.util.Calendar;
import java.util.GregorianCalendar;

public class Jumin {
	private String jumin;
	public Jumin() {}
	public Jumin(String jumin) {
		this.jumin=jumin;
	}
	
	public boolean validate() {
		//주민번호 유효한지 검증
		boolean flag=false;
		//주민번호가 맞으면 flag 변수값을 true 대입하시오.
		
        int[] gop= {2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5};
		char[] ch=new char[jumin.length()];
		int sum=0;
		
		if(jumin.length()!=13) { //주민번호 13자리가 아닐 경우 오류
			return flag;
		}//if end
				
		for(int i=0; i<jumin.length()-1; i++) {	//영어 대,소문자 및 한글일 경우 오류
			ch[i]=jumin.charAt(i);
			if(ch[i]>='a'&& ch[i]<='z') {
				System.out.println("영문이 입력되었습니다. 숫자를 입력하세요.");
				return flag;
				
			}else if(ch[i]>='A' && ch[i]<='Z') {
				System.out.println("영문이 입력되었습니다. 숫자를 입력하세요.");
				return flag;
				
			}else if(ch[i]>='가' && ch[i]<='힣') {
				System.out.println("한글이 입력되었습니다. 숫자를 입력하세요.");
				return flag;
				
			}//if end
		}//for end
		
		for(int i=0; i<jumin.length()-1; i++) {
			sum=sum+(Character.getNumericValue(ch[i])*gop[i]);
		}//for end
	
		int M=(11-(sum%11))%10;	//주민번호 유효성 공식

		if(M==Character.getNumericValue(jumin.charAt(12))) {
			flag=true;
		}//if end
		
		return flag;
		
	}//validate() end
	
    
	public void disp() {
		//생년월일, 성별, 나이, 띠 출력
		//띠   : 
		//->태어난 년도%12 
		//->0이면 원숭이, 1이면 닭, 2면 개 ~ 11이면 양
		
		String a1=jumin.substring(0, 2); //89
		String a2=jumin.substring(2, 4); //12
		String a3=jumin.substring(4, 6); //30
		String a4=jumin.substring(6, 7); //1
		int a5=1900+Integer.parseInt(a1); //1989
		int a6=2000+Integer.parseInt(a1); 
		
		GregorianCalendar now=new GregorianCalendar();
		
		//생년월일 구하기
		if(a4.equals("1") || a4.equals("2")) {
			System.out.println("생년월일: 19"+ a1 +"년 "+ a2 +"월 "+ a3 +"일");

		}else if(a4.equals("3") || a4.equals("4")){
			System.out.println("생년월일: 20"+ a1 +"년 "+ a2 +"월 "+ a3 +"일");
		}//if end
		
		//성별 구하기
		if(a4.equals("1") || a4.equals("3")) {
			System.out.println("성별: 남자");
		}else {
			System.out.println("성별: 여자");
		}//if end
		
		//나이 구하기
		if(a4.equals("1") || a4.equals("2")) {
			int b1=now.get(Calendar.YEAR)-1900-Integer.parseInt(a1)+1;
			System.out.println("나이: "+b1); //2020-1900-89+1=32
		}else {
			int b3=now.get(Calendar.YEAR)-2000-Integer.parseInt(a1)+1;
			System.out.println("나이: "+b3);	
		}//if end
		
		//띠 구하기
		if(a4.equals("1") || a4.equals("2")) {
			if(a5%12==0) {
				System.out.println("띠: 원숭이");
			}else if(a5%12==1) {
				System.out.println("띠: 닭");
			}else if(a5%12==2) {
				System.out.println("띠: 개");
			}else if(a5%12==3) {
				System.out.println("띠: 돼지");
			}else if(a5%12==4) {
				System.out.println("띠: 쥐");
			}else if(a5%12==5) {
				System.out.println("띠: 소");
			}else if(a5%12==6) {
				System.out.println("띠: 호랑이");
			}else if(a5%12==7) {
				System.out.println("띠: 토끼");
			}else if(a5%12==8) {
				System.out.println("띠: 용");
			}else if(a5%12==9) {
				System.out.println("띠: 뱀");
			}else if(a5%12==10) {
				System.out.println("띠: 말");
			}else {
				System.out.println("띠: 양");
			}//if end
			
		}else {
			if(a6%12==0) {
				System.out.println("띠: 원숭이");
			}else if(a6%12==1) {
				System.out.println("띠: 닭");
			}else if(a6%12==2) {
				System.out.println("띠: 개");
			}else if(a6%12==3) {
				System.out.println("띠: 돼지");
			}else if(a6%12==4) {
				System.out.println("띠: 쥐");
			}else if(a6%12==5) {
				System.out.println("띠: 소");
			}else if(a6%12==6) {
				System.out.println("띠: 호랑이");
			}else if(a6%12==7) {
				System.out.println("띠: 토끼");
			}else if(a6%12==8) {
				System.out.println("띠: 용");
			}else if(a6%12==9) {
				System.out.println("띠: 뱀");
			}else if(a6%12==10) {
				System.out.println("띠: 말");
			}else {
				System.out.println("띠: 양");
			}//if end
		}//if end
		
	}//disp() end
}//class end


public class Test05_jumin {
	public static void main(String[] args) {
		//연습문제)
		//주민번호 유효성 검사 후
		//생년월일, 성별, 나이, 띠 출력하기
		
		Jumin id=new Jumin("8912301234567");
		
		if(id.validate()) {
			System.out.println("주민번호 맞다");
			id.disp();
		}else {
			System.out.println("주민번호 틀리다");
		}//if end
		
	}//main() end
}//class end



/* 결과값
주민번호 맞다
생년월일: 1989년 12월 30일
성별: 남자
나이: 32
띠: 뱀
*/

 

//선생님 답

import java.util.Calendar;
import java.util.GregorianCalendar;

public class Jumin {
  private String jumin; //주민번호
  public Jumin() {}
  public Jumin(String jumin) {
    this.jumin=jumin;
  }
  
  public boolean validate() {
    //주민번호 유효한지 검증
    boolean flag=false;
    //주민번호가 맞으면 flag변수값을 true대입하시오
    
    Integer[] CHECKNUM = new Integer[]{2,3,4,5,6,7,8,9,2,3,4,5}; 
    Integer[] save = new Integer[12];
    int hap = 0;
    int size = save.length;
    
    for(int i=0; i<size; i++) {
      int num=Integer.parseInt(jumin.substring(i, i+1)); //jumin.substring
      save[i] = num * CHECKNUM[i];	//save에 값 대입
      hap = hap + save[i];
    }//for end
    
    int M = (11-(hap%11))%10;  
    //주민번호 검증
    if(M==Integer.parseInt(jumin.substring(12))) {
      flag = true;
    }//if end
    
    return flag;
  }//validate() end
  
  
  public void disp() {
    //생년월일, 성별, 나이, 띠 출력하기
    //생년월일 : 1989년12월30일
    //성별 : 남자
    //나이 : 32
    //->GregorianCalendar클래스 이용
    //띠 : 
    //->태어난년도%12
    //->0원숭이 1닭 2개 ~~~~ 11양
    
    //생년월일
    int myYear  = Integer.parseInt(jumin.substring(0, 2));
    int myMonth = Integer.parseInt(jumin.substring(2, 4));
    int myDate  = Integer.parseInt(jumin.substring(4, 6));
    
    //성별코드
    int code = Integer.parseInt(jumin.substring(6, 7));
    
    switch(code) {	//switch**
    case 1 :
    case 2 : myYear = myYear + 1900; break;
    case 3 :
    case 4 : myYear = myYear + 2000; break;
    }//switch end
    
    //성별
    String gender = "";
    switch(code%2) {
    case 0 : gender = "여자"; break;
    case 1 : gender = "남자"; break;
    }//switch end
    
    //오늘날짜
    GregorianCalendar today=new GregorianCalendar();  
    int cYear = today.get(Calendar.YEAR);
    
    //나이
    int myAge = cYear - myYear;
    
    //띠
    String[] animal = {"원숭이","닭","개","돼지","쥐","소","호랑이","토끼","용","뱀","말","양"};
    
    //출력
    System.out.println("주민번호 : " + jumin);
    System.out.println("태어난 년도 : " + myYear);
    System.out.println("태어난 월 : " + myMonth);
    System.out.println("태어난 일 : " + myDate);
    System.out.println("성별 : " + gender);
    System.out.println("나이 : " + myAge);
    System.out.println("띠 : " + animal[myYear%12]);	//배열**

  }//disp() end
  
}//class end


public class Test05_jumin {
  public static void main(String[] args) {
    //연습문제)
    //주민번호 유효성 검사 후
    //생년월일, 성별, 나이, 띠 출력하기
    
    Jumin id=new Jumin("8912301234567");
    if(id.validate()) {
      System.out.println("주민번호 맞다");
      id.disp();
    }else {
      System.out.println("주민번호 틀리다");
    }//if end

  }//main() end
}//class end

 

*switch 풀이. **boolean형