5장. C 구문 바꾸기

5-0 오늘의 소스

CJAVA
{code:java}
// C++(객체지향)이 아닌 C(구조적)코드임을 유의하면서 코드를 봐주세요.
// EffectiveJava.cpp : Defines the entry point for the console application.
//
/*
* @author 장선웅
*/

#include "stdafx.h"

using namespace std;

#define M_PI 3.14

typedef enum {RECTANGLE, CIRCLE} shapeType_t;

typedef struct {
double length;
double width;
} rectangeDimensions_t;

typedef struct {
double radius;
} circleDimensions_t;

typedef struct {
shapeType_t tag;
union { // 공용체(union)
rectangeDimensions_t rectangle;
circleDimensions_t circle;
} dimensions;
} shape_t;

// shape의 넓이를 계산한다.
double area(shape_t *shape) { // 함수 포인터.
switch(shape->tag) {
case RECTANGLE: {
double length = shape->dimensions.rectangle.length;
double width = shape->dimensions.rectangle.width;

return length * width;
}

case CIRCLE: {
double r = shape->dimensions.circle.radius;
return M_PI * (r*r);
}

default:
return -1.0;
}
}

int _tmain(int argc, _TCHAR* argv[])
{

// 일반적인 데이터 입력
shape_t shape1; // rectangle
shape_t shape2; // circle

shape1.tag = RECTANGLE;
shape1.dimensions.rectangle.length = 20.0f;
shape1.dimensions.rectangle.width = 15.0f;

shape2.tag = CIRCLE;
shape2.dimensions.circle.radius = 10.0f;
double rs1 = area(&shape1);
double rs2 = area(&shape2);

printf("shape1 area = %f\n", rs1);
printf("shape2 area = %f\n", rs2);

// shape1의 타입만 CIRCLE로 바꾸고.
shape1.tag = CIRCLE;
rs1 = area(&shape1);
printf("shape1 area = %f\n", rs1);

int a;
cin >> a;
return 0;
}

|{code:java}
interface Shape {	
	double getArea();
}



public class ShapeRectangle implements Shape {
	
	private double length = 0.0f;
	private double width = 0.0f;
	
	public ShapeRectangle(double length, double width) {
		this.length = length;
		this.width = width;
		
	}
	
	public void setLength(double value) {
		length = value;
	}
	
	public void setWidth(double value) {
		width = value;
	}
	
	public double getLength() {
		return length;
	}
	
	public double getWidth() {
		return width;
	}

	public double getArea() {
		return length * width;
	}
	
	public String toString() {
		return "Rectangle=" + getArea();		
	}

}



public class ShapeCircle implements Shape {

	private double radius = 0.0f;
	private static final double M_PI = 3.14;
	
	ShapeCircle(double radius) {
		this.radius = radius;
	}
	
	public void setRadius(double value) {
		radius = value;	
	}
	
	public double getRadius() {
		return radius;
	}
	
	public double getArea() {
		return radius * radius * M_PI;
	}
	
	public String toString() {
		return "Circle=" + getArea();		
	}

}



public class Client {
	public static void main(String[] args) {
		Shape shape1 = new ShapeCircle(10.0f);
		Shape shape2 = new ShapeRectangle(20.0f, 15.0f);
		
		double rs1 = shape1.getArea();
		double rs2 = shape2.getArea();
		
		System.out.println("< C소스 스타일 >");
		System.out.println("shape1=" + rs1);
		System.out.println("shape2=" + rs2);
		
		System.out.println("");
		System.out.println("< toString() 오버라이딩 >");
		System.out.println(shape1);
		System.out.println(shape2);
				
	}
}

|

결과
결과

5-1 구조체는 클래스로 바꿔라.

  • C언어의 구조체를 클래스로 바꿔라.
  • 단, 퇴화된 클래스가 아닌 캡슐화된 클래스로 바꿔라.
    • 캡슐화의 장점: 유연한 코드
퇴화된 클래스캡슐화된 클래스
{code:java}

public class ShapeCircle implements Shape {

public double radius = 0.0f;
public static final double M_PI = 3.14;

ShapeCircle(double radius) {
this.radius = radius;
}

// get/set 메소드가 없습니다.

public double getArea() {
return radius * radius * M_PI;
}

public String toString() {
return "Circle=" + getArea();
}

}

|{code:java}

public class ShapeCircle implements Shape {

	private double radius = 0.0f;
	private static final double M_PI = 3.14;
	
	ShapeCircle(double radius) {
		this.radius = radius;
	}
	
	public void setRadius(double value) {
		radius = value;	
	}
	// get 메소드
	public double getRadius() {
		return radius;
	}
	// set 메소드
	public double getArea() {
		return radius * radius * M_PI;
	}
	
	public String toString() {
		return "Circle=" + getArea();		
	}

}

|

5-2 union(공용체)는 클래스 계층 구조로 바꿔라.

  • C언어에서 union(공용체)란? 메모리를 효율적으로 사용하기 위한 방법.
  • 자바에서 사용하는것 처럼 계층적-클래스로 만들어라.(위 소스 참조)
{code:java}
typedef struct { // 구조체(struct)
shapeType_t tag;
union { // 공용체(union)
rectangeDimensions_t rectangle;
circleDimensions_t circle;
} dimensions;
} shape_t;
|!union.jpg!|

h2. 5-3 enum구문은 클래스로 바꿔라.
- Java 5 에서부터는 Java의 enum(열거형, Typesafe Enums-타입안전열거)을 사용. [Java 5 enum|http://wiki.gurubee.net/display/WEBSTUDY/Typesafe+Enums]

h2. 5-4 함수 포인터를 클래스와 인터페이스로 바꿔라.
- 자바에서는 C의 포인터가 제거되고, 객체가 같은 역활을 한다.
- 객체를 사용하면 패턴(스트레티지, 싱글톤등등)을 사용하여 좀 더 효율적으로 프로그래밍 할 수 있다.
- 객체를 사용하면 직렬화도 할 수 있다.

h2. 문서에 대하여

* 최초작성자 : [장선웅|STUDY:장선웅]
* 최초작성일 : 2008년 03월 27일
* 이 문서의 내용은 [자바 유창하게 말하기 - Effective Java|http://book.naver.com/bookdb/book_detail.php?bid=130814] 교재를 스터디 하면서 정리한 내용 입니다.
* 이 문서는 [오라클클럽|http://www.gurubee.net] [자바 웹개발자 스터디|제3차 자바 웹개발자 스터디] 모임에서 작성하였습니다.
* 이 문서를 다른 블로그나 홈페이지에 퍼가실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^\^