서노썬
sun noes sun
서노썬
전체 방문자
오늘
어제
  • 카테고리 (142)
    • Java (89)
      • Day1 (20)
      • Day2 (16)
      • Day3 (4)
      • Day4 (5)
      • Day5 (2)
      • Day6 (2)
      • Day7 (4)
      • Day8 (6)
      • Day9 (3)
      • Day10 (0)
      • Day11 (0)
      • Day12 (0)
      • Day13 (3)
      • Day14 (0)
      • Day15 (0)
      • Day16 (0)
      • Day19 (0)
      • Day20 (0)
      • Day21 (2)
      • Day22 (4)
      • Day23 (2)
      • Day24 (5)
      • Day25 (4)
      • Day27 (2)
      • Day28 (3)
      • Day29 (1)
      • Day30 (1)
      • Day31 (0)
      • Day32 (0)
      • Dat33 (0)
      • Day34 (0)
      • Day35 (0)
      • Day36 (0)
    • HTML (37)
      • Day36 (20)
      • Day37 (3)
      • Day38 (2)
      • Day39 (8)
      • Day40 (3)
    • SQL (4)
      • Day40 (4)
      • Day41 (0)
      • Day42 (0)
      • Day43 (0)
      • Day44 (0)
      • Day45 (0)
    • JSP (0)
      • Day46 (0)
      • Day75 (0)
    • PYTHON (0)
      • Day75 (0)
      • Day76 (0)
    • Photo (12)

블로그 메뉴

  • 홈
  • 방명록

인기 글

최근 글

태그

  • 자바continue
  • 자바break
  • 논리연산자
  • java자료형
  • 자바자료형
  • java데이터타입
  • java메뉴입력
  • 자바연산자
  • 자바
  • Java

티스토리

hELLO · Designed By 정상우.
서노썬

sun noes sun

Java/Day25

[Java] Clone 문제 (깊은 복사, 얕은 복사, 공변반환)

2021. 12. 7. 10:36

1. 깊은복사 & 공변반환 문제

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);
	}
	public void changePos(int x, int y)
	{
		xPos=x;
		yPos=y;
	}
	public Object clone() throws CloneNotSupportedException
	{
		return super.clone();
	}
}

class Rectangle implements Cloneable
{
	Point upperLeft, lowerRight;
	
	public Rectangle(int x1, int y1, int x2, int y2)
	{
		upperLeft=new Point(x1, y1);
		lowerRight=new Point(x2, y2);
	}
	public void showPosition()
	{
		System.out.println("직사각형 위치정보...");
		System.out.print("좌 상단: ");
		upperLeft.showPosition();
		System.out.println("");	
		System.out.print("우 하단: ");
		lowerRight.showPosition();	
		System.out.println("\n");
	}
	public void changePos(int x1, int y1, int x2, int y2)
	{
		upperLeft.changePos(x1, y1);
		lowerRight.changePos(x2, y2);
	}
	public Object clone() throws CloneNotSupportedException
	{
		return super.clone();
	}
}

class ShallowCopy
{	
	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();
		}
	}
}

 

얕은 복사가 된 소스이다. 이것을 깊은 복사가 된 소스로 변경하시오.

org.showPosition() 하면
직사각형 위치정보...
좌 상단: [2, 2] 
우 하단:[7, 7]
cpy.showPosition() 하면
직사각형 위치정보...
좌 상단: [2, 2] 
우 하단:[7, 7] 

이라고 출력된다.

이것을 다음의 형태로 출력되게 바꾸자.
직사각형 위치정보...
좌 상단: [2, 2] 
우 하단:[7, 7]
직사각형 위치정보...
좌 상단: [1, 1] 
우 하단:[9, 9]


[ 풀이 1 - 깊은 복사 ]

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);
	}
	public void changePos(int x, int y)
	{
		xPos=x;
		yPos=y;
	}
	public Object clone() throws CloneNotSupportedException
	{
		return super.clone();
	}
}

class Rectangle implements Cloneable
{
	Point upperLeft, lowerRight;
	
	public Rectangle(int x1, int y1, int x2, int y2)
	{
		upperLeft=new Point(x1, y1);
		lowerRight=new Point(x2, y2);
	}
	public void showPosition()
	{
		System.out.println("직사각형 위치정보...");
		System.out.print("좌 상단: ");
		upperLeft.showPosition();
		System.out.println("");	
		System.out.print("우 하단: ");
		lowerRight.showPosition();	
		System.out.println("\n");
	}
	public void changePos(int x1, int y1, int x2, int y2)
	{
		upperLeft.changePos(x1, y1);
		lowerRight.changePos(x2, y2);
	}
	public Object clone() throws CloneNotSupportedException
	{
		Rectangle cpy = (Rectangle)super.clone();
		cpy.upperLeft = (Point)upperLeft.clone();
		cpy.lowerRight = (Point)lowerRight.clone();
		return cpy;
	}
}

class ShallowCopy
{	
	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();
		}
	}
}

[ 풀이 2 - 공변반환 ]

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);
	}
	public void changePos(int x, int y)
	{
		xPos=x;
		yPos=y;
	}
	public Point clone() throws CloneNotSupportedException
	{
		return (Point)super.clone();
	}
}

class Rectangle implements Cloneable
{
	Point upperLeft, lowerRight;
	
	public Rectangle(int x1, int y1, int x2, int y2)
	{
		upperLeft=new Point(x1, y1);
		lowerRight=new Point(x2, y2);
	}
	public void showPosition()
	{
		System.out.println("직사각형 위치정보...");
		System.out.print("좌 상단: ");
		upperLeft.showPosition();
		System.out.println("");	
		System.out.print("우 하단: ");
		lowerRight.showPosition();	
		System.out.println("\n");
	}
	public void changePos(int x1, int y1, int x2, int y2)
	{
		upperLeft.changePos(x1, y1);
		lowerRight.changePos(x2, y2);
	}
	public Rectangle clone() throws CloneNotSupportedException
	{
		Rectangle cpy = (Rectangle)super.clone();
		cpy.upperLeft = this.upperLeft.clone();
		cpy.lowerRight = this.lowerRight.clone();
		return cpy;
	}
}

class ShallowCopy
{	
	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();
		}
	}
}

2. Clone 문제

class Point implements Cloneable
{
	public int x;

	public Point(int x) {
		this.x = x;
	}

	@Override
	public Point clone() throws CloneNotSupportedException {
		return (Point)super.clone();
	}
	
	public void showInfo()
	{
		System.out.println("x = " + x);
	}
}

class Circle implements Cloneable
{
	public Point center;
	public int radius;
	public Circle(int x, int radius) {
		this.center = new Point(x);
		this.radius = radius;
	}
	@Override
	public Circle clone() throws CloneNotSupportedException {
		Circle cpy = (Circle)super.clone();
		cpy.center = center.clone();
		return cpy;
	}
	public void showInfo()
	{
		center.showInfo();
		System.out.println("radius : " + radius);
	}
}

public class CloneTest {
	public static void main(String[] args) {
		Circle c1 = new Circle(10, 20);
		try {
			Circle cpy = c1.clone();
			cpy.center.x = 100;
			cpy.radius = 200;
			c1.showInfo();
			cpy.showInfo();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
}

3. Clone 문제

 

복사 메소드 호출 시, PersonalInfo 클래스가 깊은 복사를 수행하도록 코드를 변경하시오.

class Business
{
	private String company;
	private String work;

	public Business(String company, String work)
	{
		this.company = company;
		this.work = work;
	}
	public void showBusinessInfo()
	{
		System.out.println("회사 : " + company);
		System.out.println("업무 : " + work);
	}
	public void changeWork(String work)
	{
		this.work=work;
	}
}

class PersonalInfo
{
	private String name;
	private int age;
	private Business bness;

	public PersonalInfo(String name, int age, String company, String work)
	{
		this.name = name;
		this.age = age;
		bness = new Business(company, work);
	}
	public void showPersonalInfo()
	{
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
		bness.showBusinessInfo();
		System.out.println("");
	}
	public void changeWork(String work)
	{
		bness.changeWork(work);
	}
}

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

			PersonalInfo pInfo = new PersonalInfo("James", 22, "HiMedia", "encoding");
			PersonalInfo pCopy = (PersonalInfo)pInfo.clone();
			pCopy.changeWork("decoding");

			pInfo.showPersonalInfo();
			pCopy.showPersonalInfo();
	}
}

 

[ 풀이 ]

/*
오버라이딩의 조건

자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.

[참고] JDK1.5부터 '공변 반환타입(covariant return type)'이 추가되어, 반환타입을 자손 클래스의 타입으로 변경하는 것은 가능하도록 조건이 완화되었다.
*/
class Business implements Cloneable
{
	private String company;
	private String work;

	public Business(String company, String work)
	{
		this.company = company;
		this.work = work;
	}
	public void showBusinessInfo()
	{
		System.out.println("회사 : " + company);
		System.out.println("업무 : " + work);
	}
	public void changeWork(String work)
	{
		this.work=work;
	}
	/*
	public Object clone() throws CloneNotSupportedException
	{
		Business copy = (Business)super.clone();
		return copy;
	}
	*/
	public Business clone() throws CloneNotSupportedException
	{
		Business copy = (Business)super.clone();
		return copy;
	}
}

class PersonalInfo implements Cloneable
{
	private String name;
	private int age;
	private Business bness;

	public PersonalInfo(String name, int age, String company, String work)
	{
		this.name = name;
		this.age = age;
		bness = new Business(company, work);
	}
	public void showPersonalInfo()
	{
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
		bness.showBusinessInfo();
		System.out.println("");
	}
	public void changeWork(String work)
	{
		bness.changeWork(work);
	}
	/*
	public Object clone() throws CloneNotSupportedException
	{
		PersonalInfo copy = (PersonalInfo)super.clone();
		copy.bness = (Business)bness.clone();
		return copy;
	}
	*/
	public PersonalInfo clone() throws CloneNotSupportedException
	{
		PersonalInfo copy = (PersonalInfo)super.clone();
		//copy.bness = (Business)bness.clone();
		copy.bness = bness.clone();
		return copy;
	}
}

class DeepCopyImpl
{
	public static void main(String[] args)
	{
		try
		{
			PersonalInfo pInfo = new PersonalInfo("James", 22, "HiMedia", "encoding");
			// PersonalInfo pCopy = (PersonalInfo)pInfo.clone();
			PersonalInfo pCopy = pInfo.clone();
			pCopy.changeWork("decoding");

			pInfo.showPersonalInfo();
			pCopy.showPersonalInfo();
		}
		catch(CloneNotSupportedException e)
		{
			e.printStackTrace();
		}
	}
}

'Java > Day25' 카테고리의 다른 글

[Java] Wrapper 클래스  (0) 2021.12.07
[Java] 인스턴스 복사 clone 메소드  (0) 2021.12.06
[Java] isEquals  (0) 2021.12.06
    'Java/Day25' 카테고리의 다른 글
    • [Java] Wrapper 클래스
    • [Java] 인스턴스 복사 clone 메소드
    • [Java] isEquals

    티스토리툴바