Day 15 - JAVA(달력..Calendar API, Obeject, this / super, Override, Overload.....)
34. 달력 이어서
Method | API | |
월1일 dayOfWeek |
ex) 2021.3.1 (1~2020.12.31까지 일수 + 2021.1.1 ~2021.2.28일수 + 2021.3.1 일수)%7 마지막주의 채워진 날짜갯수 + 1년 1월 1을 월요일부터 시작 +1 |
객체를 선언 객체의 날짜를 세팅 원하는 1일의 요일을 구하고 Calendar cal = Calendar.getInstance(); 이전달의 마지막 요일 -1 |
선택월의 최대일수 | int dayOfMonth = dayOfMonth(year, month); | int dayOfMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH); |
전달의 최대일수 | int beforeDay = beforeDay(year,month); | cal.set(year,month-1-1,1) cal.getActualMaximum(Calendar.DAY_OF_MONTH); |
/**
* 이전 달력의 최대 일수를 구하는 메소드
* 전년도 12월
* @param year
* @param month
*/
public int beforeDay(int year, int month) {
int maxDay = 0;
if (month == 1) {
maxDay = dayOfMonth(year-1, 12);
} else {
maxDay = dayOfMonth(year, month-1);
}
return maxDay;
}
달력 이어서...
달력 출력 후에 이전 달력의 날짜와 이후 달력의 날짜를 출력하자
현재 만들어놓은 상태로는 1월에서이 index 0번이므로 -1을 한다면 음수로 12월이 나오지 않는다.
그렇기 때문에 1월일 경우 12월을 사용하고 나머지는 원래대로 입력월의 -1을하여 index를 찾도록 함
이후의 날짜 출력 3월 기준
- 전체(시작 일(1), 마지막 일(31))를 7로 나누면 마지막줄에 입력된 나머지 칸의 갯수를 알 수 있음
- int afterDay = (dayOfWeek + dayOfmonth)%7 = > 4가 나옴(마지막 주 4칸이 채워져있음을 의미)
- 1주일은 7일이기 때문에 빈공간은 7-4 = 3 => 3칸이 빈공간이다
- for(int i = 1; i <= afterDay; i++){}
이전의 날짜 출력 3월 기준
- 2021년 3월 => 2021년 2월 / 2021년 1월 => 2021년 0월이 됨(월은 index를 맞춰서 마이너스됨)
이 오류는 indexOutOfBoundaryException
34. 달력만들기 이어서 ( API를 이용하여 Calendar 만들기 )
import java.util.Calendar;
public class APICalender {
public void calenderMethod(int year, int month) { //일은 고정이기 때문에 필요가 없다?
System.out.printf("\t\t%s년\t\t%s월\n",year,month);
System.out.printf("일\t월\t화\t수\t목\t금\t토\n");
Calendar cal = Calendar.getInstance();
cal.set(year, month-1, 1);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)-1; //해당달의 1일의 요일을 구하고 거기서 -1을 하면 저번달 마지막 요일이 구해짐
int dayOfMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(year, month-1-1, 1);
int beforeDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
// System.out.println(beforeDay);
for (int i = beforeDay-dayOfWeek+1; i <= beforeDay; i++) {
System.out.printf("%d\t",i);
}
for (int i = 1; i <= dayOfMonth; i++) { // 전체일수 찍어야하기 때문에 <=
System.out.printf("%d\t",i);
if((dayOfWeek+i)%7==0) {
System.out.println();
}
}
//달력 출력 후 뒷 부분의 빈 공간에 다음달 달력을 출력
int afterDay = (7- (dayOfWeek + dayOfMonth)%7)%7; // 7%7 = 0
// System.out.println(afterDay);
for (int i = 1; i <= afterDay; i++) {
System.out.printf("%d\t",i);
}
System.out.println();
}
}
Calender API는 new를 통해서 사용하려면 abstract멤버를 모두 구현해야 사용할 수 있다.
그래서 static 메소드인 getInstance를 사용하여 cal 객체로 만들어 사용(한번 만들어서 사용)
cal.get(Calendar.멤버필드)를 사용하여 요일과 최대일수를 구하여 사용
이 결과 요일은 int로 반환이 되는데 일요일은 1 월요일은 2 ... 토요일은 7로 반환
39. Java.lang.Obejct
1) java의 모든 클래스의 최상위 클래스(super class)
2) 모든 클래스의 최상위 부모가 됨
3) 모든 클래스는 Object의 메소드를 가지고 있음
4) 자식 클래스에 관련된 모든 메소드를 가지고 있음 : 위치, 고유값, 출력, 깨움, 잠재움, 복제 등...
**여기서의 객체는 메모리의 heap 영역에 할당된 상태
**Object 4대 메소드
- *.toString(); => getClass().getName+"@"+16진수hashcode
- *.equals(); => 부모를 통해서 hashcode를 통한 객체의 비교
- *.getClass(); => 객체의 생성된 package.ClassName
- *.hashCode => 객체는 고유한 값이 아닌 사용되는 hashcode를 출력해줌
(처음 부여받은 고유한 hashCode를 출력하기 위해서는 System.IdentifyHashCode를 통하여 출력)
//모든 클래스는 java.lang.Object extends
//object는 기본적으로 java Class의 상위 클래스이기 때문에 명시적으로 작성하지 않음
public class ObjectExplain {
public static void main(String[] args) {
String str1 = new String("홍길동"); //heap
String str2 = "홍길동"; //sp
Dto str3 = new Dto("홍길동"); // heap
System.out.println("equals 객체를 비교할때 사용하는 메소드");//부모한테 요청해서 같은 객체인지 확인
boolean isc1 = str1.equals(str2);
System.out.println(isc1);
boolean isc2 = str1.equals(str3);
System.out.println(isc2); // false hashcode는 같은데 거기다 타입까지 같아야 한다
Dto str4 = new Dto("홍길동");
boolean isc3 = str3.equals(str4);
System.out.println(isc3);
System.out.println("hashcode()");
System.out.println("str1/" + str1.hashCode());
System.out.println("str2/" + str2.hashCode());
System.out.println("str3/" + str3.hashCode());
//비교의 대상
System.out.println("getClass()"); // invocation, reflection
System.out.println(str1.getClass()); // invocation, reflection
System.out.println(str2.getClass()); // invocation, reflection
System.out.println(str3.getClass()); // invocation, reflection
System.out.println("toString()"); //출력을 해주는 것이 아니라 메모리에 있는 객체를 표현해줌
System.out.printf("%s : %s : %s\n",str1.toString(),str2.toString(),str3.toString());
boolean isc12 = (str1.toString() == str2.toString());
boolean isc23 = (str2.toString() == str3.toString());
boolean isc13 = (str1.toString() == str3.toString());
System.out.println(isc12);
System.out.println(isc23); //new로 만든 String객체는 toString을 통해서 new로 만들어짐
//하지만 user 객체는 toString 했을 경우 값을 반환 (SP반환)
//생성된 원래의 형태에 따라서 toString은 반환되는 객체가 다르다
System.out.println(isc13);
}
}
getClass()를 통하여 어떤 클래스에서 왔는지 알 수 있음 (str1 str2 : String / str3 : DTO)
hashcode() 한번 비교해보자
( str1 str2 : 응 같은 hashcode임 SP에 "홍길동" 있어 우리 그 값에 의해서 hashcode 재정의 됐음 / str3 : ? 난 아닌데 나는 오브젝트가 만들어준 hashcode 갖고 있는데? 근데 hashcode를 멤버필드인 name("홍길동")으로 Override 하니까 나도 "홍길동"에 의해서 hashcode 재정의됐어 너네랑 똑같음)
toString() 출력해볼게
(str1 str2 : 응 나 String 타입인데 이미 toString Override 했거든 그래서 우리는 값을 출력했어 "홍길동"
str3 : ? 난 아닌데 나는 패키지명.클래스명 16진수 hashcode나옴... 그래서 나도 너네처럼 toString Override했어 그랬더니 값 출력 가능해짐 "홍길동"
euqals()를 통해서 hashcode를 갖고 객체가 같은지 비교하자
(str1 str2 : 응 우린 sp에 "홍길동" 값을 통해서 hashcode 재정의 했어 hashcode 똑같음 true(사실 우린 타입도 같음)
str1 str3 : ?? 우리는 왜 false니 hashcode 똑같잖아... 알고봤더니 타입도 같아야된대..
40. this / super
- extends / implements의 상황에서 자신의 member를 호출하는 것을 this
- extends / implements의 상황에서 부모의 member를 호출하는 것을 super
- 자신의 생성자를 호출 this(), 부모의 생성자를 호출 suepr()
**Override가 되지 않는 상황
1) 메소드가 fianl로 선언되어 있을 때
2) 메소드가 private로 선언되어 있을 때
3) 부모의 생성자
멤버필드는 생성된 class의 특징이 된다 Override 안됨 (메소드는 가능하다)
public class Parents {
public String name;
public void make() {
System.out.println("Parents 메소드");
}
}
위 아래 같이 보면 멤버필드 String 타입 name 있는데 Override 대상이 아니야
public class Child extends Parents {
public String name;
public Child() {
// super();
this("홍길동");
}
public Child(String name) {
//생성자는 반드시 부모부터 초기화 해야함
super(); // 부모생성후 자식 바로 생성 주석처리되어있어도 디폴트로 자동으로 생성이됨
new Parents(); // 현재 클래스의 부모가 아닌 단독으로 생성된 객체 이것이 super보다 위에 위치하면 안됨
this.name = name;
}
@Override
public void make() {
System.out.println("Child 메소드");
super.make();
}
}
그리고 extends 관계에서 자식 클래스 생성자 Overloading하려면 부모 클래스의 생성자부터 super()로 초기화 해야돼
안 그러면 자식 생성자 Overloading 못해 생성자 Overloading 할때 새로운 부모 객체 만드는 것 new Parents() 포함하려면 그거보다 super()가 먼저 실행되야함
Override하면 이렇게 위에 덮어쓴 것처럼 재정의 된다
그래서 부모 메소드 호출해도 자식 메소드 호출된다.
public class ThisSuperMain {
public static void main(String[] args) {
Child c = new Child();
c.make();
Parents p = c;
p.make(); // child 실행됨
// System.out.println(c.name);
// System.out.println(p.name);
}
}
@Override
public void make() {
System.out.println("Child 메소드");
// super.make();
<멤버메소드의 경우>
Override할때 부모 메소드 호출하는 기능 넣지 않으면 Override한 후에는 절대 부모 메소드 따로 호출할 방법 없어
그리고 자식타입의 c를 부모타입의 p에 참조해서 make() 실행해도 이미 Override 됐기 때문에 자식의 make()가 실행됨
<멤버필드의 경우>
자식타입의 c를 부모타입으로 변경하여 다시 p에 참조하고 멤버필드를 호출하면 p의 멤버필드가 호출됨(메소드와는 다르다 Override 안된다)