본문 바로가기
코딩/수업 정리

20.12.17 Thu [019]

by 6^6 2020. 12. 17.
728x90
  • clone
  • 래퍼클래스
  •  

 

19-14 인스턴스 복사: clone 메소드  --지금단계에선 clone쓰지말것 다른 더 중요한걸 먼저알고쓸것

이게 무슨말인지 알려면 예제보기

인스턴스 복사 =  객체 복사

 

 

 

 

19-15 메소드 호출의 예

//19-14 예제
package java_1217;

class Point implements Cloneable {
	private int xPos;
	private int yPos;

	public Point(int x, int y) {
		xPos = x;
		yPos = y;
	}

	public void showPosition() {
		System.out.printf("[%d, %d]", xPos, yPos);
		System.out.println();
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

class InstanceCloning {
	public static void main(String[] args) {
		Point org = new Point(3, 5);
		Point cpy;

		try {
			cpy = (Point) org.clone(); //이거 쓴 이유는 그대로 복사하려고
            						//3,5 복사하고 그대로 출력함
			org.showPosition();
			cpy.showPosition();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}

	}

}

class Point implements Cloneable{} 은 마커 인터페이스임

 

@Override 

밑에 - 오버라이딩해서 부모거 그대로 가져옴

 

cpy = (Point) org.clone(); 의 그림

복사하는 방법 지금까지 배운 여러가지(원래 3가지)

new 생성 객체

object에있는 clone함수를 활용하는 방법

 

성능상으론 new 보단 clone이 더 빠름

 

clone에서 중요한  Shallow Copy와  Deep Copy (근데 자바에서 뭍히는 경향이 있음)

 

19-16 Shallow Copy

Rectangle에 clone의 대상은 2개밖에없다.(upperLeft,lowerRight 인스턴스멤버)

생성된 객체(new)까지는 clone을 안하고 자기가 가지고있는 데이터멤버(인스턴스멤버)만 clone한다.

 

클래스안에 객체형이있다할때 clone형을 하게되면 Point그 자체만 clone하게 된다.

객체까지는 clone을 안한다.

 

 

 

19-17 Deep Copy

 

clone이어서 따로 객체생성을 해주는것임.

super.clone()을 하게되면 

package java_1216_;

class Point implements Cloneable {
    private int xPos;
    private int yPos;
    
    public Point(int x, int y) {
        xPos = x;
        yPos = y;
    }
    
    public void showPosition() {
        System.out.printf("[%d, %d]", xPos, yPos);
        System.out.println();
    }

    public void changePos(int x, int y) {
        xPos = x;
        yPos = y;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Rectangle implements Cloneable {
    private Point upperLeft;     // 좌측 상단 좌표
    private Point lowerRight;     // 우측 하단 좌표
    
    public Rectangle(int x1, int y1, int x2, int y2) {
        upperLeft = new Point(x1, y1);
        lowerRight = new Point(x2, y2);
    }

    // 좌표 정보를 수정함
    public void changePos(int x1, int y1, int x2, int y2) {
        upperLeft.changePos(x1, y1);
        lowerRight.changePos(x2, y2);
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        // Object 클래스의 clone 메소드 호출 결과를 얻음
        Rectangle copy = (Rectangle)super.clone();

        // 깊은 복사의 형태로 복사본을 수정
        copy.upperLeft = (Point)upperLeft.clone();
        copy.lowerRight = (Point)lowerRight.clone();
        
        // 완성된 복사본의 참조를 반환
        return copy;        
    }

    // 직사각형 좌표 정보 출력    
    public void showPosition() {
        System.out.print("좌측 상단: ");
        upperLeft.showPosition();
        
        System.out.print("우측 하단: ");
        lowerRight.showPosition();
        System.out.println(); 
    }
}

class DeepCopy {
    public static void main(String[] args) {
        Rectangle org = new Rectangle(1, 1, 9, 9);
        Rectangle cpy;
        
        try {
            // 인스턴스 복사
            cpy = (Rectangle)org.clone();

            // 인스턴스의 좌표 정보를 수정
            org.changePos(2, 2, 7, 7);

            org.showPosition();
            cpy.showPosition();
        }
        catch(CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

deep copy든 shallow copy든 참조형이 있을 때 문제된다.

 

 

 

19-18 String 인스턴스 대상 깊은 복사

deep copy하려면 String조차도 새로 생성을 해줘야한다.

 

 

19-19 clone 메소드의 호출과 형 변환

 

 

 

19-20 clone 메소드의 반환형 수정

Point 그대로 쓰는거처럼 clone메소드의 반환형 수정할땐 저대로 쓰기!

 

 

 

 

래퍼클래스 - 랩으로 감싸는 클래스

 

20-1,3

 

Integer iInst = new Integer(3); 객체 생성

얘를 그냥 syso(integer);하면 그냥 3나옴. - 뿌리는 원리 다형성이 적용되면서 toString을 호출.(F3)

 

 

 

20-4 래퍼 클래스의 종류와 생성자

8개를 객체로 만들어놓음

 

 

20-5 래퍼 클래스의 두 가지 기능

 

 

 

20-6 박싱과 언박싱 예

 

리터럴이기때문에 메모리에올라갈때 걍 문자형으로 

언박싱은

 

 

20-7 언박싱 메소드의 이름

 

 

 

20-8 오토 박싱과 오토 언박싱

obj객체안에 10이 들어감

기본형 , 객체형

기본형을 객체형으로 넣는것이 박싱

 

컴파일러가 찾아서 변환을 다 시켜준다(new해주고)

 

문법적으로 허용되니까 기억하기

 

 

 

 

 

 

20-9 오토 박싱, 오토 언박싱의 또 다른 예

 

//11 이들어가는데 객체를 새로 생성시켜줘야한다.

오토박싱이 진행되면서 객체가 계속 쌓인다.

밑도끝도없이 계속 객체를 생성하게된다.

 

 

 

 

 

 

 

20-10

Number클래스 반드시 기억

 

Number클래스에서는 추상메소드로 intValue(), longValue(), doubleValue()가있다.

abstract = 추상화= 자손이 구현하라

 

 

 

 

 

 

20-11 Number 클래스의 추상 메소드 호출의 예

package java_1217;

public class bbbb {
	public static void main(String[] args) {
		Integer num1 = new Integer(29);
		System.out.println(num1.intValue());
		System.out.println(num1.doubleValue());
		
		Double num2 = new Double(3.14);
		System.out.println(num2.intValue());
		System.out.println(num2.doubleValue());
	}

}//29
//29.0
//3
//3.14

(double)3 이런식으로 형변환하지않고 객체지향으로 넣게되면 함수를 사용할 수 있게된다.

 

 

 

 

 

 

20-12 래퍼 클래스의 다양한 static 메소드들

Integer n1 = Integer.valueOf(5); - 많이씀!!

 

얘는 다형성이 아니다. 

 

함수 오버로딩이다. 

 

~~.valueOf(숫자); 

 

//20-12 오토 언박싱의 예제
package java_1217;

public class eeee {
	public static void main(String[] args) {
		Integer n1 = Integer.valueOf(5);
		Integer n2 = Integer.valueOf("1024");

		System.out.println("큰 수 : " + Integer.max(n1, n2));
		System.out.println("작은 수: " + Integer.min(n1, n2));
		System.out.println("합: " + Integer.sum(n1, n2));
		System.out.println();

		System.out.println(Integer.toHexString(12));
		System.out.println("12의 2진 표현: " + Integer.toOctalString(12));
		System.out.println("12의 16진 표현: " + Integer.toHexString(12));

	}
}//큰 수 : 1024
//작은 수: 5
//합: 1029

//c
//12의 2진 표현: 14
//12의 16진 표현: c

그렇다면 오토박싱(Autoboxing)의 반대말인 언박싱(Unboxing)이란 무엇일까?
Float, Integer, Boolean 같은 박스된 참조타입을 원시타입인 float, int, boolean 타입으로 변경하는 것을 말한다.

 

unboxing이란 래퍼 유형의 객체를 해당 기본 값으로 변환하는 것을 말합니다.

예를들면 Integer가 int로 변환되는것을 말합니다.

Integer a = new Integer(100);
int test = a; //unboxing

래퍼클래스인 Integer a값을 primitivie 변수인 int test에 대입하면 알아서 언박싱되면서 값을 처리해줍니다.

 

 

 

메모리를 좀더 효율적으로 아껴쓸려고 데이터타입을 8개로 나눈것임.

속도도 빨라짐

 

 

 

오늘의 문제

1.String 클래스 에서 문자열 비교시 equal을 쓰는 이유는?

String으로 주소값이 아닌 문자열을 비교하고 싶을때 equals를 쓴다.

equals 는 함수오버라이딩해서 자기목적에 맞게끔 만들었기 때문에 문자열이 같으면 true값을 반환한다.

 


2.shallow copy, deep copy 의 차이는?

shallow copy(얕은 복사)는

원본 참조변수의 참조값만 복사하는 것이다.

deep copy(깊은 복사)는 

자기자신이 참조형변수를 가지고있으면 해당 객체를 생성시켜서 넣어줘야한다.(클론이든 new든. 클론없으면 new라도 생성해서 넣어야함.)  원본 참조변수의 참조값이 가르키는 객체를 메모리 공간에 복사생성 후 복사본 참조변수가 가르키는 것이다.

 


3.금일 배운 Rectangle의 shallow copy 와 deep copy 일때의 그림을 그리시오.(중요)

 

 


4.다음 main()이 실행되면 아래 예시와 같이 출력되도록 MyPoint 클래스를 작성하라.

public static void main(String [] args) {
	MyPoint p = new MyPoint(3, 50);
	MyPoint q = new MyPoint(4, 50);
	System.out.println(p);
	if(p.equals(q)) System.out.println("같은 점");
	else System.out.println("다른 점");			
}

Point(3,50)
다른점
package java_1217_;

class MyPoint {
	private int x;
	private int y;

	MyPoint() {

	}

	MyPoint(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public String toString() {
		return "Point(" + x + "," + y + ")";
	}
}

@Override
	public boolean equals(Object obj){
		if((this.x)obj).x) && ((this.y)obj).y){
				return true;
		} else {
				return false;
		}
}

public class PointMain {
	public static void main(String[] args) {
		MyPoint p = new MyPoint(3, 50);
		MyPoint q = new MyPoint(4, 50);
		System.out.println(p);
		if (p.equals(q))
			System.out.println("같은 점");
		else
			System.out.println("다른 점");
	}
}//Point(3,50)
//다른 점

 

 

5.중심을 나타내는 정수 x, y와 반지름 radius 필드를 가지는 Circle 클래스를 작성하고자 한다. 생성자는 3개의 인자(x, y, raidus)를 받아 해당 필드를 초기화하고, equals() 메소드는 두 개의 Circle 객체의 중심이 같으면 같은 것으로 판별하도록 한다.

public static void main(String[] args) {
	Circle a = new Circle(2, 3, 5); // 중심 (2, 3)에 반지름 5인 원
	Circle b = new Circle(2, 3, 30); // 중심 (2, 3)에 반지름 30인 원
	System.out.println("원 a : " + a);
	System.out.println("원 b : " + b);
	if(a.equals(b))
		System.out.println("같은 원");
	else 
		System.out.println("서로 다른 원");
}
원 a : Circle(2,3)반지름5 
원 b : Circle(2,3)반지름30 
같은 원 
package java_1217_;

class Circle {
	private int x, y, r;

	Circle(int x, int y, int r) {
		this.x = x;
		this.y = y;
		this.r = r;

	}
	
	public String toString() {
		
		return "Circle("+x+","+y+")반지름"+r;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this.x==((Circle)obj).x)
			return true;
		else 
			return false;
	}

}

public class PointMain {
	public static void main(String[] args) {
		Circle a = new Circle(2, 3, 5); // 중심 (2, 3)에 반지름 5인 원
		Circle b = new Circle(2, 3, 30); // 중심 (2, 3)에 반지름 30인 원
		System.out.println("원 a : " + a);
		System.out.println("원 b : " + b);
		if (a.equals(b))
			System.out.println("같은 원");
		else
			System.out.println("서로 다른 원");
	}
//		원 a : Circle(2,3)반지름5 
//		원 b : Circle(2,3)반지름30 
//		같은 원 

}


6.문자열을 입력받아 한 글자씩 회전시켜 모두 출력하는 프로그램을 작성하라.(클래스로 작성할 필요없이 메인에서 직접 할것)

문자열을 입력하세요. 빈칸이나 있어도 되고 영어 한글 모두 됩니다.
I Love you
 Love youI
Love youI 
ove youI L
ve youI Lo
e youI Lov
 youI Love
youI Love 
ouI Love y
uI Love yo
I Love you
[Hint] Scanner.nextLine()을 이용하면 빈칸을 포함하여 한 번에 한 줄을 읽을 수 있다.

 

package java_1217;

import java.util.Scanner;

public class LoveMain {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		String str = sc.nextLine();

		char[] arr = str.toCharArray();
		for (int i = 0; i < arr.length; i++) {

			for (int n = 1; n <= arr.length; n++) {
				System.out.print(arr[(i + n) % (arr.length)]);
			}
			System.out.println();
		}
	}
}

 

다른 정석풀이

import java.util.Scanner;
public class arrayClass {
	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		for (int i = 1; i <= str.length(); i++) {
			System.out.print(str.substring(i));
			System.out.println(str.substring(0, i));
		}
		sc.close();
	}
}

 


7.래퍼 클래스란 무엇인가?

랩으로 감싸는 클래스. 언박싱과 박싱을 할 수 있는 기능이 들어있는 클래스이다.

 

 

8.auto unboxing 이란?

기본타입(8개)값을 랩퍼 인스턴스(포장 객체)로 만드는 과정을 박싱이라고 하고 반대로 랩퍼 인스턴스에서 기본타입 값을 얻는 과정은 언박싱이라고 한다.

여기서 기본 자료형 값이 와야 할 위치에 인스턴스가 오면 오토 언박싱이 진행된다.(컴파일러가 찾아서 변환을 다 시켜준다. 문법적으로 허용됨)


9. 다음 조건을 만족하는 클래스 Person을 구현하여 테스트하는 프로그램을 작성하시오.(필수)

- 클래스 Person은 이름을 저장하는 필드 구성

- 클래스 Person은 상위 클래스 Object의 메소드 equals()를 오버라이딩하여 이름이 같으면 true를 반환하는 메소드 구현

- 다음과 같은 소스로 클래스 Person을 점검

Person p1 = new Person("홍길동");
System.out.println(p1.equals(new Person("홍길동")));
System.out.println(p1.equals(new Person("최명태")));
package java_1217_;

class Person {
	private String name;

	public Person(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		if (this.name == ((Person) obj).name)
			return true;
		else
			return false;
	}
}

public class PersonMain {
	public static void main(String[] args) {
		Person p1 = new Person("홍길동");
		System.out.println(p1.equals(new Person("홍길동")));
		System.out.println(p1.equals(new Person("최명태")));
	}

}

 

 

 

 

 

10. 다음 조건을 만족하는 클래스 String의 객체 이용 프로그램을 작성하여 메소드 equals()와 연산자 ==의 차이를 비교 설명하시오.(필수) 

- 메소드 equals()와 비교 연산자 ==의 차이를 다음 소스로 점검

String s1 = new String("java");
String s2 = new String("java");
String s3 = s2;

 

System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
System.out.println(s2 == s3);
System.out.println(s2.equals(s3));

 

class Stringequals {

	public Stringequals(String name) {

	}
}

public class PersonMain {
	public static void main(String[] args) {
		String s1 = new String("java");
		String s2 = new String("java");
		String s3 = s2;

		System.out.println(s1 == s2); // s1과 s2의 주소값을 비교
		System.out.println(s1.equals(s2));// s1와 s2의 문자열값을 비교-다형성적용
		System.out.println(s2 == s3);// s1과 s2의 주소값을 비교
		System.out.println(s2.equals(s3)); //s2와 s3의 문자열값을 비교
	}

}

 

 

 

 

11. 다음 조건을 만족하도록 오늘의 정보를 출력하는 프로그램을 작성하시오.

- 클래스 Calendar의 객체의 다음 메소드를 사용하며

 * get(Calendar.DAY_OF_WEEK_IN_MONTH) : 달에서 요일의 횟수 반환
 * get(Calendar.DAY_OF_WEEK) : 요일을 반환, 1이 일요일
 * get(Calendar.WEEK_OF_MONTH) : 월의 주 횟수를 반환
 * get(Calendar.DAY_OF_YEAR) : 해의 날짜를 반환
 * get(Calendar.WEEK_OF_YEAR) : 해의 주 횟수를 반환

- 다음과 같이 출력되도록 한다.

오늘은 2012년 6월 17일 일요일입니다.
이 달의 3번째 일요일입니다.
이 달의 4번째 주입니다.
이 해의 169일입니다.
이 해의 25번째 주입니다. 

 

package java_1218;

import java.util.Calendar;

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

		Calendar cal = Calendar.getInstance();
		// ↑getInstance는 싱글톤(Singleton Pattern)이다. 객체를 딱! 하나만 생성가능.

		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int date = cal.get(Calendar.DATE);
		
		String d = null;
		
		switch (cal.get(Calendar.DAY_OF_WEEK)) {
		case 1:
			d = "일";
			break;
		case 2:
			d = "월";
			break;
		case 3:
			d = "화";
			break;
		case 4:
			d = "수";
			break;
		case 5:
			d = "목";
			break;
		case 6:
			d = "금";
			break;
		case 7:
			d = "토";
			break;
		}

		System.out.println(year + "" + month + "" + date + "" + d);

	}

}

 

728x90

댓글