오늘은 모든 클래스에 기본적으로 상속되는 Object클래스와 특정 기능 처리를 위해 만들어놓은 Api클래스에 대해 공부해 보았다!
Object클래스는 일단 클래스를 만들면 자동으로 상속되어진다. 다른 클래스를 상속하지 않으면 extends Object가 생략되어있을 뿐, 들어가있는 상태라고 보면 될 것 같다.
물론 다른 클래스를 상속한다고 하더라도 상속한 부모 클래스가 어차피 Object클래스를 포함한다.
그렇기 때문에, 모든 자바의 클래스는 Object클래스를 상속하고있는 것 이다.
정리해보자면 다음과 같다.
- 자바에서는 필수적으로 상속한다.
- 아무것도 상속하지 않더라도 암묵적으로 Object클래스를 상속한다.
- 결국 모든 쿨래스는 Object클래스의 후손클래스이다.
- public class test 등 클래스를 만들어 객체를 생성하면, Object메소드를 사용가능하다.
- 작성한 적 없는 메소드들은 모두 Object클래스의 기본상속 메소드들이다.
- 클래스가 공동적으로 포함하고 있어야 하는 기능을 포함하고있다.
대표적인 Object클래스의 메소드들을 살펴보자.
toString()메소드는 객체가 가지고있는 정보나 값 등을 문자열로 리턴하라는 메소드다. 우리는 String (변수이름);으로 문자열 변수를 선언할 수 있다. 그렇지만 알고있어야할 것이 있다. 문자열 변수 String은 참조형이라는 것 이다. 참조형 자료들은 모두 객체를 생성해주어야 그 값을 받아올 수 있는데, String은 그렇지않다. 사실 이것은 String형 값을 리턴하는 toString()메소드를 기본적으로 포함하고있다는 사실이다. 그렇다면 이 toString()메소드는 어디에다 사용할까?
이 메소드는 Object클래스에 들어가있는 메소드로, 모든 클래스가 사용이 가능하다. 그렇지만, 이 메소드를 사용하기 위해선 @Override를 이용해 메소드를 재정의 해주어야한다. 예를 들면
public class TestClass{
@Override
public String toString() {
return "나는 TestClass";
}
}
와 같은 형식으로 코드를 짜는 것 이다. 타 클래스에서 객체로 만들어보자.
public class Start {
public static void main(String[] args) {
TestClass tc = new TestClass();
System.out.println(tc.toString());
}
}
위와 같은 코드를 짜게되면, 출력값은 "나는 TestClass"가 된다. 하지만 TestClass의 toString메소드를 Override하지 않으면, 생성한 tc객체의 주소값만 표시된다.
(패키지명.클래스명@인스턴스식별값)
보통 이 기능을 사용하는 이유는, 불러올 객체 클래스에서 받아오고싶은 정보를 미리 써놓는 것 이다.
내용을 일일이 출력해보기 귀찮아서 미리 보여줘야할 값을 넣어놓는 것 이다.
Clone()메소드는 들어가기 전에 한번 간단하게 정리해보겠다.
- 객체 자체를 복사하여 다른 객체에 사용할 때 사용하는 메소드이다.
배열의 깊은복사 시 clone()메소드를 사용하여 복사한다.- clone()메소드의 접근제어 지시자는 protected이므로 다른 패키지에서는 사용이 불가하다.
- 작성한 클래스에서 clone() 메소드를 사용하기 위해서는 overridng을 해야한다.
- Overriding을 위해서는 JBM에게 복제 가능한 클래스임을 알려주기 위해
Cloneable interface를 상속해서 사용한다.
이렇게 사용하면 된다.
public class TestClass implements Cloneable{
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
사실 필자도 clone을 정확하게 이해하진 못했다... 조금 더 공부하고 수정해보겠다.
그리고 사실은 clone()메소드가 Object클래스의 상속되어있는게 아니라고 구글링해보다가 알았다.
진짜진짜 쉬운거 나왔다. 그냥 객체의 값이 같은지 비교하는 메소드이다.
String str1 = new String(“Hello”);
String str2 = new String(“Hello”);
if(str1.equals(str2)){
System.out.println(“ 같습니다.”);
}else{
System.out.println(“ 다릅니다.”);
}
이 코드에서 알아보는 것은 str1이 str2의 값이랑 같은 값을 가지고있는지 보는 것 이다.
만약 입력된 값이 같다면, equals()메소드는 true를 내보낸다.
그냥 이게 끝이다. 더 할게 없다.
Object에서 많이 사용하는 메소드 3가지를 알아보았다.
API는 프로그래밍을 할 때 어떠한 특정 기능을 처리할 수 있도록 만들어 놓은
클래스나 메소드의 집합을 말한다.
JAVA API는 이 기능을 구현하는 클래스, 메소드의 집합을 자바 언어를 사용하여 만든 것 이다.
API는 정말 많은 수가 나와있으며, 자바의 버전마다 지언하는 API가 조금씩 차이가 있으니, 인터넷에서 (아마 오라클 가서 찾아보면 나올 것 이다.) 찾아보고 사용하면 좋다. 대부분 친절하게 설명이 다 되어있을 것 이다.
가장 먼저 String관련 API부터 살펴보자.
API를 보기전에 String 클래스의 특징부터 보자면
String
- 문자열 값을 수저 못하는 성질을 가지고있다.
- 수정 시 수정된 문자열이 새로 할당되어 새 주소를 저장한다.
- 그래서 문자열을 자주 수정하는 경우 메모리 낭비가 심하다.
String 클래스는 위와 같이 수정할 때 마다 새로운 주소에 문자열이 할당되어 그 주소를 참조하기 때문에, 컴퓨터 메모리의 낭비가 심하다. 그래서 사용하는게 StringBuffer클래스다.
StringBuffer
- 문자열 값을 수정 할 수 있는 가변의 성질을 가짐
- 수정 시 수정된 기존 문자열이 수정
- 문자열을 자주 수정하는 경우 String보다 유용
- Thread Safe 기능 제공(성능저하 요인)
Thread Safe기능은 객체가 여러 스레드로부터 동시에 접근하더라고 프로그램 실행에 문제가 없음을 뜻한다. StringBuilder라는 클래스도 있는데, StringBuffer클래스와 동일하지만, Thread Safe 기능이 제공되지 않는다.
StringBuffer클래스에서 사용가능한 메소드들을 살펴보자.
- capacity() : 실제 할당된 공간의 크기 확인
- length() : 실제 문자열 길이 확인
- reverse() : 저장된 문자열을 거꾸로 재배치(안녕->녕안)
- insert(3, "삽입구문") : 첫번째 매개변수의 위치가 시작되는 부분에 두번째 메소드를 추가한다. 정라히자면 문자열의 특정 위치에 문자열을 추가하는 기능 (아무 정수, 아무 문자열)
- append() : 문자열 끝에 문자열을 추가
- delete(5, 10) : 문자열의 일부분을 삭제. 지금같은 경우는 5번째 위치부터 시작해서 10번째 위치의 바로 앞 까지 삭제하는 기능으로 작용
- reaplace(0, 2, "수정구문") : 문자열의 일부분을 다른 문자열로 변경하는 메소드. 지금 작성한 코드는 0번째 부터 2번째 바로 앞 까지의 문자열을 3번째 매개변수로 바꾸는 기능
위와 같이 정리가 가능하다. 그렇다면 이 문자열을 하나의 긴 문장이 아닌, 짧은 여러개의 문자열로 관리하고 싶다면 어떡해야하는가? 그럴때 StringTokenizer클래스를 사용한다.
StringTokenizer
- 문자열을 분석하여 토큰으로 분리시켜주는 기능의 클래스
- 생성시 전달받은 문자열을 구분자로 나누어 각 토큰에 저장
- 파일에 저장된 텍스트를 처리하는 경우 유용
String str = "하나/둘/셋";
String[] arr = str.split("/");
System.out.println(arr.length);
for(int i =0;i<arr.length;i++) {
System.out.println(arr[i]);
}
위의 코드로 예시를 들어보자. str문자열에 하나/둘/셋 이라는 값을 넣어줫다. 그리고 문자열 타입의 배열 arr을 만들어 split(문자열을 자르고, 구분하는 기능)을 사용해 "/"마다 문자열을 구분시켜서 값을 넣어주었다. 이 경우, arr은 하나, 둘, 셋 이라는 문자열을 배열에 가지고있다. 그래서 arr의 길이를 출력해주면 3이라는 출력결과가 나온다. 또 for문을 이용해 확인해보면 배열 arr[0]~arr[2]까지의 값이 "하나" / "둘" / "셋" 이 출력되는 것을 확인 가능하다.
StringTokenizer클래스를 이용해 코드를 짜보자.
StringTokenizer sT = new StringTokenizer(str,"/");
while(sT.countTokens()>0) {
String str1 = sT.nextToken();
System.out.println(str1);
}
문자열 str을 "/"마다 구분짓겠다고 선언한 것 이다.문자열 str1에 나누어준 토큰의 값을 계속 넣어주어 구분지은 토큰이 남지 않을때까지 str1의 값을 계속 출력하는 형태의 코드이다.
이런 형식으로 StringTokenizer를 사용하면 되는 것 이다. 클래스의 메소드를 살펴보자.
- countTokens() : 꺼내지 않고 남아있는 토큰의 수 확인
- hasMoreTokens() : 남아 있는 토큰이 있는지 확인하여 true,false 리턴
- nextToken() : 토큰을 하나씩 꺼내옴
StringTokenizer클래스는 여기서 마무리 짓자.
이제 Math클래스를 살펴보자. Math클래스는 수학에서 자주 사용하는 상수들과 메소드들을 구현해 놓은 클래스이다. 특이한 점은, Math클래스의 메소드는 모드 static method로 객체를 생성하지 않고 바로 사용이 가능하다. 'Math m - new Math()'의 과정이 필요없다.
Math 클래스는 귀찮으니까 그냥 짜놓은 코드만 올릴거다...
public void math() {
// Math -> 객체를 생성하지않고 바로 사용
System.out.println(Math.abs(10));// 절대값
System.out.println(Math.abs(-10));
// 올림,버림,반올림
System.out.println(Math.ceil(10.1));// 소수 첫자리에서 올림 -> 11
System.out.println(Math.floor(10.9));// 소수 첫자리에서 버림 -> 10
System.out.println(Math.round(10.5));// 소추 첫자리에서 반올림 -> 11
// 1.3456 -> 1.35 으로 만들기 위해선
// 134.56 -> 반올림 -> 135 -> 1.35
System.out.println(Math.round(1.3456 * 100) / (double) 100); //의 과정
// 숫자비교
System.out.println(Math.max(50, 30)); // 두 매개변수 중 큰 수 리턴
System.out.println(Math.min(50, 30)); // 두 매개변수 중 작은 수 리턴
}
그래두 이정도면 알아보기 쉽게 정리하지 않았나..? 필자 수학 좋아한다. 근데 이거 쓰는건 너무 귀찮다.
Date클래스는 시간관련 클래스이다. 짤게 정리해보자.
Date
- 시스템으로부터 현재 날짜, 시간정보를 가져와서 다룰 수 있게 만들어진 클래스로, 생성자 2개만 사용 가능하고 나머지는 잘 사용되지 않아서 없어질 수 있는 deprecated기능이다.
- Calendar 또는 GregorianCalendar 클래스의 사용이 권장된다.
- 뭔가 안좋은 말이 많다.
Date 클래스의 생성자는
Date date1 = new Date()
//시스템으로 부터 현재 날짜, 시간 정보를 가져와 기본값으로 사용한다.
Date date2 = new Date(123456789L);
//long형 정수 값을 가지고 날짜 시간을 ms단위로 계산한다.
//1970년 1월 1일 9시 0분0초를 기중르로 기준시간에서 생성자의 매개변수로 입력한 정수값까지의 시간이 흐른 시점의 날짜와 시간 정보를 기억한다.
그러하다. 그냥 기본 생성자는 현재 날짜를 가져와주고, 매개변수를 입력하면 ms단위로 1970부터 얼마나 지났는지 계산해서 알려준다.
SimpleFormat클래스는 Date의 날짜, 시간 정보를 원하는 형식으로 출력할 수 있게 만들어준다.
Date today = new Date();
System.out.println(today);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy년MM월dd일 HH시mm분ss초 EEE요일");// 생성자에 날짜출력 패턴을 입력
//출력결과 : 2022년01월19일 xx시yy분zz초 수요일
이런식으로 말이다. 아 그냥 정리해보자.
- 년도 : yyyy
- 월 : MM
- 일 : dd
- 시간 : HH
- 분 : mm
- 초 : ss
- 요일 : EEE
이렇게 출력이 가능하다. 순서는 바뀌어도 상관없지만 대소문자는 바뀌면 안된다.
처음에는 정리하는거에 열정적이다가도 이렇게 길게 다 정리하다보면 의지가 식어간다.
귀찮다 솔직히 Calendar 클래스와 Wrapper 클래스 남아있는데, 대충 개념만 정리하고 싶다.
근데 Wrapper클래스는 중요한거니까 Calendar 클래스만 대충할거다!
대충할거다.
정리만 한다.
Calendar
- 현재 시간과 관련 있는 클래스
- Calendar클래스는 추상클래스, 생성자의 접근제어 지시자가 protected로 new() 생성자를 통해 객체를 생성할 수 없음
- getInstance() 메소드를 이용하여 객체를 생성 Calendar dDay = Calendar.getInstance();
- Calendar.getInstance() 메소드는 GregorianCalendar객체를 리턴하며, 해당 객체는 Calendar클래스를 상속하여 작성된 자식클래스로, 년,월,일,시,분,초 정보를 필드(변수)를 통해 다룰 수 있다. 이런식으로
System.out.println(today.get(Calendar.YEAR)); // 년도 System.out.println(today.get(Calendar.MONTH) + 1); // 월 - > 0~11로 리턴 System.out.println(today.get(Calendar.DATE)); // 일 System.out.println(today.get(Calendar.AM_PM)); // AM=0,PM=1 System.out.println(today.get(Calendar.HOUR)); // 시간 System.out.println(today.get(Calendar.MINUTE)); // 분 System.out.println(today.get(Calendar.SECOND)); // 초 System.out.println(today.get(Calendar.MILLISECOND)); // ms초 System.out.println(today.get(Calendar.DAY_OF_WEEK)); // 요일(1:일요일 ~ 7:토요일)
Calendar 끝이당 안할랭
근데 Wrapper클래스는 중요하다. 그래서 헤더라인 줬다 겁나크게.
일단 Wrapper클래스의 특징을 정리해보자.
Wrapper
- 기본자료형을 객체화 해주는 클래스다.
- 기본 자료형 데이터를 포장하여 표현하기 때문에 Wrapper라고 부른다.
- 객체지향 프로그래밍의 경우 기본자료형을 객체로 처리해야 하는 상황이 존재하는데, 그런 상황에서 사용되는 클래스이다.
그러하다. 8가지의 기본자료형을 Wrapper클래스를 이용해 객체로 처리가 가능한데, 이 때 타입에 맞춰 입력해야한다.
기본자료형 / Wrapper Class //객체 생성 (안에 들어간 값으 예시)
boolean / Boolean //Boolean bool = new Boolean(true);
char / Character //Character ch = new Character(‘A’);
byte / Byte //Byte bNum = new Byte((byte)1);
short / Short //Short sNum = new Short((short)2);
int / Integer //Integer iNum = new Integer(4);
long / Long //Long lNum = new Long(8);
float / Float //Float fNum = new Float(0.4f);
double / Double //Double dNum = new Double(0.8);
위와 같이 정리할 수 있겠다.
기본 자료형을 객체로 사용하려면, 객체로 만드는 작업이 필요하다.
이를 Boxing: Wrapper 클래스에 기본자료형을 넣는 것 이라고 표현한다.
위에서 정리한 객체 생성이 이것이다. 이것을 Boxing이라고 한다.
Integer num = new Integer(10);
//정수 10을 Integer클래스로 객체화
그리고, 이 객체를 사용하기 위해서는 Wrapper클래스로 만들어진 객체에서 기본자료형을 빼내야하는데, 이것을 Unboxing이라고 한다.
int n = num.intValue();
//Integer객체 num에 들어있는 정수 값을 꺼내서 정수형 변수에 저장
사실 이거 너무 귀찮아서 자바에서 알아서 Boxing Unboxing해준다.
- Auto Boxing
Integer num = 10;
//정수 10을 Integer클래스로 객체화- Auto Unboxing
int n = num;
//Integer객체 num에 들어있는 정수 값을 꺼내서 정수형 변수에 저장
마지막으로 Wrapper클래스를 이용한 문자열 처리가 있다.
- 문자열 -> 기본 자료형
String data = “999”;
int num = Integer.parseInt(data);- 기본 자료형 -> 문자열
int num = 999;
String data = Integer.valueOf(num).toString();
or
String data1 = String.valueOf(num);
근데 문자형 char는 이미 메소드가 있으므로, 사용 안한다.
문자열에서 char형으로 받아올 때는 charAt();을 사용하고,
char를 문자열로 변환할 때는 char.toString()을 사용한다.
이거 길었다... 생각보다 오래걸렸고, 새벽에 쓰다가 졸려서 다음날 아침 일찍 일어나서 마저 썼다..
오늘은 여기까지...! 근데 오늘 저녁에 또 공부하고 쓸거다...
이 글은 여기까지..?