열심히 끝까지
Java2 day11 본문
JAVA2 day03
[11일차 수업 내용]
1. Object 클래스
2. String 클래스
3. Math 클래스
4. Wrapper 클래스
============================================================================
1. Object 클래스
- Object 클래스는 모든 클래스의 최고 조상이기 때문에
Object 클래스의 멤버들은 모든 클래스에서 바로 사용이 가능
- Object 클래스는 멤버변수를 가지고 있지 않고, 오직 11개의 메소드만 가지고 있음
① .equals(Object obj)
- 매개변수로 객체의 참조변수를 받아서 그 결과를 boolean 값으로 알려주는 역할을 함.
- Object 클래스로부터 상속받은 equals()메소드는 결국 두 개의 참조변수가 같은 객체를 참조하고 있는지
즉, 두 참조변수에 저장된 값(주소값)이 같은지를 판단하는 기능밖에 할 수 없음.
- 주소값이 아니라 인스턴스 내부의 값을 비교하고 싶으면 equals()메소드를 오버라이딩해야 함
② .hashCode()
- 이 메소드는 해싱(hashing)기법에 사용되는 해쉬함수를 구현한 것
- 클래스의 인스턴스 변수 값으로 객체의 같고 다름을 판단하는 경우라면
equals()메소드 뿐만 아니라 hashCode()메소드도 적절히 오버라이딩 해야 함.
- 같은 객체라면 hashCode()메소드를 호출했을 때의 결과값인 해쉬코드도 같아야 하기 때문.
③ .toString()
- 이 메소드는 인스턴스에 대한 정보를 문자열로 제공한 목적으로 정의한 것
- 인스턴스의 정보를 제공한다는 것은 대부분의 경우 인스턴스 변수에 저장된 값들을
문자열로 표현한다는 뜻.
④ .clone()
- 이 메소드는 자신을 복제하여 새로운 인스턴스를 생성하는 일을 함.
- 원래 인스턴스는 보존하고 clone() 메소드를 이용해서 새로운 인스턴스를 생성하여
작업을 하면 작업 이전의 값이 보존되므로 작업에 실패해서 원래의 상태로 되돌리거나
변경되기 전의 값을 참고하는데 도움이 될 것.
- clone() 메소드를 사용하기 위해서는 Cloneable 인터페이스를 구현해야만 함.
- Object 클래스에 정의된 clone() 메소드는 단순히 인스턴스 변수의 값만 복사하기 때문에
참조타입의 인스턴스 변수가 있는 클래스는 완전히 인스턴스 복제가 이루어지지 않음.
* 얕은 복사(shallow copy)와 깊은 복사(deep copy)
복제하는 경우 원본과 복제본이 같은 객체를 공유하는 경우
==> 얕은 복사
원본이 참고하고 있는 객체까지 복사하는 것
==> 깊은 복사
깊은 복사에서는 원본과 복사본이 서로 다른 객체를 참조하기 때문에 원본의 변경이
복사본에 영향을 미치지 않음
--------------------------------------------------------------------------------------------------------------------
Package objectMethodEx;
public class EqualsEx01{
public static void main(String[] args) {
Value v1 = new Value(10);
Value v2 = new Value(10);
if(v1.equals(v2)) { //false
System.out.println("v1과 v2는 같은 인스턴스를 가리키고 있습니다.");
} else {
System.out.println("v1과 v2는 다른 인스턴스를 가리키고 있습니다.");
}
System.out.println("v1 : " + v1);
System.out.println("v2 : " + v2);
v2 = v1;
if(v1.equals(v2)) { // true
System.out.println("v1과 v2는 같은 인스턴스를 가리키고 있습니다.");
} else {
System.out.println("v1과 v2는 다른 인스턴스를 가리키고 있습니다.");
}
System.out.println("v1 : " + v1);
System.out.println("v2 : " + v2);
}
}
class Value /* extends Object */ {
int value;
public Value(int value){
this.value = value;
}
}
----------------------------------------------------------------------------------
package objectMethodEx;
public class EqualsEx02 {
public static void main(String[] args) {
Person p1 = new Person(1234);
Person p2 = new Person(1234);
if(p1.equals(p2)) {
System.out.println("p1과 p2는 같은 사람입니다.");
} else {
System.out.println("p1과 p2는 다른 사람입니다.");
}
System.out.println(p1 == p2); // false
}
}
class Person{
int id; // 신원확인용, 즉 주민등록번호라고 생각
public Person(int id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(obj instanceif Person) {
// 1번째 방법
/*Person p1 = (Person) obj;
return this.id == p1.id;*/
// 2번째 방법
return this.id == ((Person)obj).id;
}
return false;
}
}
---------------------------------------------------------------------
package objectMethodEx;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class HashCodeEx {
public static void main(String[] args) {
A a1 = new A(10);
A a2 = new A(10);
System.out.println(a1.equals(a2)); // true
System.out.println(a1 == a2); // false
System.out.println("a1.hashCode() : " + a1.hashCode());
System.out.println("a2.hashCode() : " + a2.hashCode());
Set nums = new HashSet(); // 중복 허용 안함
nums.add(1);
nums.add(1);
System.out.println(nums);
nums.add(a1);
nums.add(a2);
System.out.println(nums);
}
}
class A{
int num;
public A(int num) {
this.num = num;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof A) {
return this.num == ((A)obj).num;
}
return false;
}
@Override
public int hashCode() {
// return Object.hash(num); // 1번째 방법
return ("" + num).hashCode(); // 2번째 방법
}
}
-----------------------------------------------------------------------------
package objectMethodEx;
public class ToStringEx{
public static void main(String[] args) {
Card c1 = new Card("CLOVER", 4);
Card c2 = new Card("HEART", 7);
System.out.println("c1 : " + c1);
System.out.println("c2 : " + c2);
System.out.println();
System.out.println("c1.toString() : " + c1.toString());
System.out.println("c2.toString() : " + c2.toString());
}
}
class Card{
String kind;
int number;
public Card(String kind, int number) {
this.kind = kind;
this.number = number;
}
@Override
public String toString() {
return "[Kind : " + this.kind + ", number : " + this.number + "]";
}
}
-----------------------------------------------------------------------
package objectMethodEx;
import java.util.Arrays;
class Cloned implements Cloneable{
int name;
int[] arr;
public Cloned(int name, int[] arr) {
this.name = name;
this.arr = arr;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class ShallowCopy {
public static void main(String[] args) throws Exception {
Cloned c = new Cloned(10, new int[4]);
Cloned c1 = (Cloned)c.clone();
System.out.println("c : " + c);
System.out.println("c1 : " + c1);
System.out.println("c.name : " + c.name);
System.out.println("c1.name : " + c1.name);
System.out.println():
System.out.println(Arrays.toString(c.arr));
System.out.println(Arrays.toString(c1.arr));
System.out.println();
System.out.println("c.arr : " + c.arr);
System.out.println("c1.arr : " + c1.arr);
c.arr[0] = 100;
c1.arr[0] = 20;
System.out.println(Arrays.toString(c.arr));
System.out.println(Arrays.toString(c1.arr));
}
}
-------------------------------------------------------------------------------
package objectMethodEx;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
class Point{
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Circle implements Cloneable {
// 복사가 되는 대상이라는 관계로 묶어준다.
Point p;
double r;
public Circle(Point p, double r) {
this.p = p;
this.r = r;
}
// 얕은 복사
public Circle shallowCopy() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) { }
return (Circle)obj;
}
// 깊은 복사
public Circle deepCopy() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) { }
Circle c = (Circle)obj;
// 강제형변환
c.p = new Point(this.p.x, this.p.y);
return c;
}
}
public class DeepCopyEx {
public static void main(String[] args) {
Circle c1 = new Circle(new Point(1,2), 2.0);
Circle c2 = c1.shallowCopy();
Circle c3 = c1.deepCopy();
System.out.println("c1 : " + c1);
System.out.println("c2 : " + c2);
System.out.println("c3 : " + c3);
System.out.println();
System.out.println("c1.p : " + c1.p);
System.out.println("c2.p : " + c2.p);
System.out.println("c3.p : " + c3.p);
System.out.println();
c2.p.x = 100;
System.out.println("c1.p.x : " + c1.p.x);
System.out.println("c2.p.x : " + c2.p.x);
System.out.println("c3.p.x : " + c3.p.x);
}
}
========================================================================
2. String 클래스
- 기존의 다른 언어에서는 문자열을 char 배열로 다루었으나
자바에서는 문자열을 위한 클래스를 제공
- 이것이 바로 String 클래스인데 String 클래스는 문자열을 저장하고
이를 다루는데 필요한 메소드를 함께 제공
① 변경불가능한 ( immutable ) 클래스
- String 클래스에서는 문자열을 저장하기 위해서 문자배열 참조변수를
인스턴스 변수로 정의해놓고 있음
- 한번 생성된 String 인스턴스가 갖고 있는 문자열은 읽어올 수만 있고 변경할 수 없음
② 문자열의 비교
- 문자열을 만들 때는 2가지 방법,
문자열 리터럴을 저장하는 방법과
String클래스의 생성자를 이용하는 방법이 있음
String str1 = "abc"; // 100번지
String str2 = "abc"; // 100번지
// str1 == str2
String str3 = new String("abc"); // 200번지
String str4 = new String("abc"); // 300번지
// str3 != str4
// str3 != str2
str1.equals(str2); // true
str3.equals(str4); // true
str1.equals(str3); // true
str3 == str4 // false
str1 == str2 // true
③ 문자열 리터럴
- 자바 소스파일에 포함된 모든 문자열 리터럴은 컴파일 시에 클래스 파일에 저장됨
.java -> .class
StringEx.java -> StringEx.class
- 이 때 같은 내용의 문자열 리터럴은 단 한번만 저장됨
- 문자열 리터럴도 String인스턴스이고 한 번 생성하면 내용을 변경할 수 없으니
하나의 인스턴스를 공유하면 되기 때문
===============================================================
3. Math 클래스
- Math클래스는 기본적인 수학계산에 유용한 메소드로 구성
- 임의의 수를 얻을 수 있는 random()과 반올림에 사용되는 round() 등이
이 클래스에 속해있는 메소드
- Math 클래스의 생성자는 접근제어자가 private
==> 다른 클래스에서 Math인스턴스를 생성할 수 없도록 되어있음
==> 클래스 내에 인스턴스 변수가 단 하나도 없어서 인스턴스를
정의할 필요가 없기 때문
- Math클래스는 제어자 final이 붙어있음
==> Math클래스를 상속받을 수 없음(오버라이딩 불가)
=================================================================
package stringEx;
public class StringEx01 {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(str1 == str2); // true
System.out.println(str1.equals(str2)); // true
System.out.println(str3 == str4); // false
System.out.println(str3.equals(str4)); // true
System.out.println(str2 == str4); // false
System.out.println(str2.equals(str3)); // true
}
}
--------------------------------------------------------
package stringEx;
import java.util.Arrays;
public class StringEx02 {
public static void main(String[] args) {
String animals = "dog,cat,bear";
// .split() : 주어진 구분자를 기준으로 문자열을 자름.
// 좀 더 많이 쓰임
String[] names = animals.split(",");
System.out.println("[split()]");
System.out.println("names : " + Arrays.toString(names));
System.out.println("animals : " + animals);
System.out.println();
// .join() : 여러 문자열 사이에 구분자를 넣어서 결합한다.
String animal = String.join("-", names);
System.out.println("[join()]");
System.out.println("animal : " + animal);
System.out.println();
// .indexOf() : 주어진 매개변수가 위치한 index를 반환, 못찾으면 -1반환.
System.out.println("[indexOf()]");
String fullName = "Hello.java";
// H e l l o . j a v a
// 0 1 2 3 4 5 6 7 8 9
int index = fullName.indexOf(".");
System.out.println(".의 index : " + index); // 5
int index2 = fullName.indexOf("java");
System.out.println("java의 index : " + index2); // 6
int index3 = fullName.indexOf(",");
System.out.println(",의 index : " + index3); // -1
System.out.println();
// .charAt() : 해당 위치 index의 문자 1개를 반환
System.out.println("[charAt()]");
char letter = fullName.charAt(1);
System.out.println("letter : " + letter);
System.out.println();
// .toUpperCase() : 문자열을 대문자로
System.out.println("[toUpperCase()]");
System.out.println(fullName.toUpperCase());
System.out.println();
// .toLowerCase() : 문자열을 소문자로
System.out.println("[toLowerCase()]");
System.out.println(fullName.toLowerCase());
System.out.println();
// .subString() : 문자열을 주어진 인덱스만큼 잘라서 반환한다.
// 많이 쓰인다!!!!
// H e l l o . j a v a
// 0 1 2 3 4 5 6 7 8 9
System.out.println("[subString()]");
int dotIndex = fullName.indexOf(".");
String fileName = fullName.substring(0, dotIndex-1);
System.out.println("fileName : " + fileName);
// subString은 마지막 인덱스를 포함하지 않는다.
fileName = fullName.substring(0, dotIndex);
System.out.println("fileName : " + fileName);
// 마지막 인덱스를 매개변수로 넘겨주지 않으면 범위는 문자열의 마지막까지이다.
String ext = fullName.substring(dotIndex+1);
System.out.println("ext : " + ext);
System.out.println();
// .valueOf() : 문자열로의 변환, 숫자로만 이루어진 경우 가능
// 중간에 알파벳 하나라도 섞이면 불가능
System.out.println("[valueOf()]");
int iVal = 100;
String strVal = String.valueOf(iVal);
System.out.println("strVal : " + strVal);
System.out.println(strVal instanceof String);
// String ==> double, string ==> int
String strVal2 = "200.1";
double dNum = Double.parseDouble(strVal2);
System.out.println("dNum : " + dNum);
String strVal3 = "100";
int iNum = Integer.parseInt(strVal3);
System.out.println("iNum : " + iNum);
}
}
=================================================================
4. Wrapper 클래스
- 객체지향 개념에서 모든 것은 객체로 다루어져야 함
- 허나, 자바에서는 8개의 기본형을 객체로 다루지 않는데 이것이 바로 자바가
완전한 객체지향 언어가 아니라는 얘기를 듣는 이유
- 때로는 기본형 변수도 어쩔 수 없이 객체로 다뤄야 하는 경우가 있음
- 이 때 사용되는 것이 래퍼 클래스
- 8개의 기본형을 대표하는 8개의 래퍼클래스가 있는데,
이 클래스들을 이용하면 기본형 값을 객체로 다룰 수 있음
( 기본형 -> 참조형 )
Object[ ] = { 1, 2, 3, 4, 1.0 };
= { new Integer(1), new Integer(2), new Double(1.0) }
- 이 래퍼클래스들은 모두 equals()가 오버라이딩되어 있어서
주소값이 아닌 객체가 가지고 있는 값을 비교
- 그리고 toString()도 오버라이딩 되어 있어서
객체가 가지고 있는 값을 문자열로 변환하여 반환
- 이 외에도 래퍼클래스들은 MAX_VALUE, MIN_VALUE, SIZE, BYTES, TYPE 등의
static 상수를 공통적으로 가지고 있음
① Number 클래스
- 이 클래스는 추상클래스로서 숫자를 멤버변수로 갖는 래퍼클래스들의 조상
② 문자열을 숫자로 변환하기
문자열 -> 기본형(정수)
int i = Integer.parseInt("100");
int i = Integer.valueOf("100");
문자열 -> 래퍼클래스(정수)
Integer i = Integer.parseInt("100");
Integer i = Integer.valueOf("100");
// 아래 사항 불가능
int[] arr = new int[4];
arr + 10;
arr + 3.14;
③ 오토박싱 & 오토언박싱 ( auto boxing & auto unboxing)
- JDK 1.5버전부터 기본형과 참조형간의 덧셈이 가능해짐
new Integer(100) + 100; ( O )
- 자바언어의 규칙이 바뀌었다는 것이 아니라
컴파일러가 자동으로 변환하는 코드를 넣어주었기 때문
- 기본형 값을 래퍼클래스의 객체로 자동변환 해주는 것을 오토박싱(auto boxing)
반대로 변환하는 것을 오토 언박싱(auto unboxing)이라고 함
----------------------------------------------------------------------------------
package wrapperEx;
public class WrapperEx01 {
public static void main(String[] args) {
Integer i = new Integer(100);
Integer i1 = Integer.valueOf(100);
Integer i2 = Integer.valueOf(100);
System.out.println("i1 == i2 : " + (i1 == i2)); // true
System.out.println("i1.equals(i2) : " + i1.equals(i2)); // true
System.out.println("i1.toString() : " + i1.toString()); //100
System.out.println("i1 : " + i1); // 100
System.out.println("i == i1 : " + (i == i1)); // false
System.out.println();
System.out.println("MAX_VALUE : " + Integer.MAX_VALUE);
System.out.println("MIN_VALUE : " + Integer.MIN_VALUE);
System.out.println("SIZE : " + Integer.SIZE + "bits");
System.out.println("BYTES : " + Integer.BYTES + "bytes");
System.out.println("TYPE : " + Integer.TYPE);
}
}
'Java2(주말)' 카테고리의 다른 글
Java2 day13 (0) | 2022.05.21 |
---|---|
Java2 day12 (0) | 2022.05.15 |
Java2 day11 보충 (0) | 2022.05.15 |
Java2 day10 (0) | 2022.05.09 |
Java2 day09 (0) | 2022.05.07 |