본문 바로가기
Java 배우기

자바 쉬운 예제

by 노화방지 Anti-aging Hairstyle 2016. 1. 4.
반응형

How do you reference a data member/function?   

데이터 멤버/함수를 참조하는 방법은?


This is accomplished by stating the name of the object reference, followed by a period (dot), followed by the name of the member inside the object.  

객체 참조의 이름을 적고, 그 뒤에 .(점)을 찍은 다음, 그 뒤에 객체의 안에 있는 멤버의 이름을 적어서 데이터터 멤버와 함수를 참조 합니다.


( objectReference.member ).


You call a method for an object by naming the object followed by a period (dot), followed by the name of the method and its argument list, like this:  

객체 참조의 이름 뒤에 .(점)을 찍고, 그 뒤에 메소드의 이름과 아규먼트 목록을 적어서 객체의 메소드를 call 합니다.


objectName.methodName(arg1, arg2, arg3).


예제:


cubeObject.length = 4;
cubeObject.breadth = 4;
cubeObject.height = 4;
cubeObject.getvolume()


A typical Java program creates many objects, which interact by invoking methods.

전형적인 자바 프로그램은 많은 객체들을 만드는데, 이들 객체는 메소드들을 invoke 함으로써 

상호작용합니다.


Here's a small program, called CreateObjectDemo, that creates three objects:

3개의 객체들을 생성시키는 CreateObjectDemo 라는 작은 프로그램이 있습니다:


one Point object and two Rectangle objects.

1개의 객체 Point와 2개의 객체 Rectangle 이 있습니다.


You will need all three source files to compile this program.

이 프로그램을 컴파일 하려면 모두 3개의 소스 파일이 필요합니다.


public class CreateObjectDemo {


   public static void main(String[] args) {

       // 1개의 point 객체와 2개의 rectangle 객체를 선언해서 생성시킨다.

       Point originOne = new Point(23, 94);

       Rectangle rectOne = new Rectangle(originOne, 100, 200);

       Rectangle rectTwo = new Rectangle(50, 100);

       // 객체 rectOne의 width, height, area를 디스플레이한다.

       System.out.println("Width of rectOne: " + rectOne.width);

       System.out.println("Height of rectOne: " + rectOne.height);

       System.out.println("Area of rectOne: " + rectOne.getArea());

       // 객체 rectTwo의 position을 정한다.

       rectTwo.origin = originOne;

       // 객체 rectTwo의 position을 디스플레이한다.

       System.out.println("X Position of rectTwo: " + rectTwo.origin.x);

       System.out.println("Y Position of rectTwo: " + rectTwo.origin.y);

       // 객체 rectTwo를 이동시켜서 새로운 position을 디스플레이스한다.

       rectTwo.move(40, 72);

       System.out.println("X Position of rectTwo: " + rectTwo.origin.x);

       System.out.println("Y Position of rectTwo: " + rectTwo.origin.y);

   }

}


This program creates, manipulates, and displays information about various objects.

이 프로그램은 다양한 객체들에 대한 정보를 생성하고, 조작하고, 디스플레이스 합니다.

Here's the output: 여기 output이 있습니다:

Width of rectOne: 100

Height of rectOne: 200

Area of rectOne: 20000

X Position of rectTwo: 23

Y Position of rectTwo: 94

X Position of rectTwo: 40

Y Position of rectTwo: 72



The following three sections use the above example to describe the life cycle of an object within a program.

다음 3개의 섹션은 한 프로그램 내에서 객체의 라이프사이클을 서술하기 위하여 위의 예제를 사용합니다.


From them, you will learn how to write code that creates and uses objects in your own programs.

그들로부터, 프로그램 내에서 객체들을 생성하고 사용하는, 코드 작성 방법을 배울 것입니다.


You will also learn how the system cleans up after an object when its life has ended.

객체가 그 생애를 마친 후 시스템이 객체를 청소하는 방법도 배울 것입니다.


Creating Objects 객체 생성시키기


As you know, a class provides the blueprint for objects;

잘 알다시피, 클래스는 객체들을 위한 청사진을 제공합니다;


you create an object from a class. 클래스로부터 객체를 생성시킵니다.

Each of the following statements taken from the CreateObjectDemo program creates an object and assigns it to a variable:

CreateObjectDemo 프로그램으로부터 취해진 각각의 다음 명령이 객체를 생성시키고 그 객체를 변수(originOne, rectOne, rectTwo)에 할당합니다:


Point originOne = new Point(23, 94);

Rectangle rectOne = new Rectangle(originOne, 100, 200);

Rectangle rectTwo = new Rectangle(50, 100);


The first line creates an object of the Point class, and the second and third lines each create an object of the Rectangle class.

첫째 줄은 Point 클래스의 객체를 생성시키고, 둘째와 셋째 줄은 각각 Rectangle 클래스의 객체를 생성시킵니다.


Each of these statements has three parts (discussed in detail below):

이들 명령문들의 각각은 3개의 부분을 갖고 있습니다(아래에서 상세히 논의):

  1. Declaration(선언): All variable declarations that associate a variable name with an object type. 변수이름을 객체타입과 연계하는 모든 변수 선언

  2. Instantiation(인스턴스화): The new keyword is a Java operator that creates the object. 키워드 new는 객체를 생성하는 자바 연산자입니다.

  3. Initialization(초기화): The new operator is followed by a call to a constructor, which initializes the new object. 연산자 new의 뒤에 생성자 호출이 있는데, 이 생성자가 새 객체를 초기화시킵니다.


Declaring a Variable to Refer to an Object 객체를 참조하기 위한 변수를 선언하기


Previously, you learned that to declare a variable, you write: 앞서, 변수 선언하는 것을 배웠는데:

type name;


This notifies the compiler that you will use name to refer to data whose type is type.

이것은 그 타입이 type인 데이터를 참조하는데 name을 사용할 것임을 컴파일러에게 알려줍니다.

With a primitive variable, this declaration also reserves the proper amount of memory for the variable.

primitive 변수를 가진 이 선언은 또한 변수를 위한 적절한 메모리의 양을 예약합니다.


You can also declare a reference variable on its own line. For example: 자신의 라인에 참조 변수를 선언할 수도 있습니다. 예를 들면:


Point originOne;


If you declare originOne like this, its value will be undetermined until an object is actually created and assigned to it.

위와 같이 originOne를 선언하면, 객체가 실제로 생성되어 그 객체가 originOne에 할당되기 전까지 객체의

값은 결정되지 않을 것입니다.

Simply declaring a reference variable does not create an object.

단순히 참조변수를 선언한다고 해서 객체가 생성되지는 않습니다.


For that, you need to use the new operator, as described in the next section.

객체를 생성하려면 new 연산자를 사용해야 합니다.


You must assign an object to originOne before you use it in your code. 

객체를 코드에 사용하려면 사용하기 전에 객체를 originOne에게 할당해야 합니다.


Otherwise, you will get a compiler error. 그렇게 하지 않으면 컴파일러에 오류가 생깁니다.


A variable in this state, which currently references no object, can be illustrated as follows (the variable name, originOne, plus a reference pointing to nothing):

현재 아무런 객체를 참조하지 않는 이 명령문 안의 변수는 다음과 같이 예시될 수 있습니다.

(변수이름 originOne, 아무 것도 가리키지 않는 참조):




Instantiating a Class 클래스를 인스턴스화 하기


The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. 

새 객체에 메모리를 할당함으로써 그리고 그 메모리에 대한 참조를 리턴함으로써, new 연산자가 클래스를

인스턴스로 만듭니다.


The new operator also invokes the object constructor.
new 연산자는 또한 객체 생성자(constructor)를 invoke 합니다.


Note: The phrase "instantiating a class" means the same thing as "creating an object."

참고: "클래스를 인스턴스화한다"는 "객체를 생성한다"는 같은 말입니다.


When you create an object, you are creating an "instance" of a class, therefore "instantiating" a class.

객체를 생성하는 것은, 클래스의 "인스턴스"를 만드는 것이기 때문에 클래스를 "instantiating" 하는 것

입니다.


The new operator requires a single, postfix argument: new 연산자는 1개의 postfix 아규먼트를 요구합니다:


a call to a constructor.  생성자에 대한 호출(call)


The name of the constructor provides the name of the class to instantiate.

인스턴스화 하기 위하여, 생성자의 이름은 클래스의 이름을 제공합니다.


The new operator returns a reference to the object it created.

new 연산자는 new 연산자가 생성시킨 객체에 대한 참조를 리턴합니다.


This reference is usually assigned to a variable of the appropriate type, like:

이 참조는 일반적으로 적절한 타입의 변수에 대하여 다음과 같이 할당됩니다:


Point originOne = new Point(23, 94);


The reference returned by the new operator does not have to be assigned to a variable.

new 연산자가 리턴하는 참조는 변수에 할당될 필요가 없습니다.

It can also be used directly in an expression. 이것은 expression에 직접 사용될 수 있습니다.


예를 들면:


int height = new Rectangle().height;




Initializing an Object 객체 초기화


Here's the code for the Point class: 아래는 클래스 Point의 코드입니다:


public class Point {

   public int x = 0;

   public int y = 0;

   // 생성자(constructor)

   public Point(int a, int b) {

       x = a;

       y = b;

   }

}


This class contains a single constructor. 이 클래스에는 1개의 생성자가 들어있습니다.

You can recognize a constructor because its declaration uses the same name as the class and it has no return type. 

생성자 선언이 클래스 이름과 같은 이름을 사용하고 리턴 타입이 없기 때문에 생성자임을 알 수 있습니다.

The constructor in the Point class takes two integer arguments, as declared by the code (int a, int b).

클래스 Point의 생성자는, 코드의 선언 대로, 2개의 integer 아규먼트(int a, int b)를 취합니다.


The following statement provides 23 and 94 as values for those arguments:

다음 명령문은 아규먼트로 23과 94의 값을 제공합니다:


Point originOne = new Point(23, 94);


The result of executing this statement can be illustrated in the next figure:

이 명령문의 실행결과는 아래 그림 처럼 예시됩니다:


Here's the code for the Rectangle class, which contains four constructors:

아래는 4개의 생성자가 포함된 클래스 Rectangle에 대한 코드입니다:


public class Rectangle {

   public int width = 0;

   public int height = 0;

   public Point origin;


   // 4개의 생성자(constructors)

   public Rectangle() {

       origin = new Point(0, 0);

   }

   public Rectangle(Point p) {

       origin = p;

   }

   public Rectangle(int w, int h) {

       origin = new Point(0, 0);

       width = w;

       height = h;

   }

   public Rectangle(Point p, int w, int h) {

       origin = p;

       width = w;

       height = h;

   }


   // rectangle을 이동시키는 메소드

   public void move(int x, int y) {

       origin.x = x;

       origin.y = y;

   }


   // rectangle의 면적을 계산하는 메소드

   public int getArea() {

       return width * height;

   }

}


Each constructor lets you provide initial values for the rectangle's size and width, using both primitive and reference types.

각 생성자는, primitive 및 reference type을 사용하여, rectangle의 size와 width에 대한 초기값을 제공할 수

있게 만듭니다.

If a class has multiple constructors, they must have different signatures.

클래스가 여러 생성자를 갖고 있는 경우, 생성자들은 서로 다른 signature를 갖고 있어야 합니다. 

The Java compiler differentiates the constructors based on the number and the type of the arguments.

자바 컴파일러는 아규먼트의 갯수와 타입에 근거하여 생성자를 구분합니다. 

When the Java compiler encounters the following code, it knows to call the constructor in the Rectangle class that requires a Point argument followed by two integer arguments:

자바 컴파일러가 다음 코드를 만나면, 컴파일러는 클래스 Rectangle 안에 있는, 2개의 integer 아규먼트가

뒤따르는 Point 아규먼트를 요구하는 생성자를 call 해야 하는 것을 압니다:

Rectangle rectOne = new Rectangle(originOne, 100, 200);


This calls one of Rectangle's constructors that initializes origin to originOne.

이것은 originOne에 대한 origin을 초기화하는 Rectangle의 생성자중 하나를 call 합니다.

Also, the constructor sets width to 100 and height to 200.

또한, 생성자는 width는 100 그리고 height는 200로 정합니다.

Now there are two references to the same Point object—an object can have multiple references to it, as shown in the next figure:

이제 동일한 객체 Point에 대한 2개의 참조가 있습니다 — 다음 그림 처럼, 1개의 객체는 그것에 대한 여러 개의 참조를 가질 수 있습니다:


The following line of code calls the Rectangle constructor that requires two integer arguments, which provide the initial values for width and height.

다름 코드 라인은, width와 height의 초기값을 제공하는, 2개의 integer 아규먼트를 요구하는, Rectangle 생성자를 call 합니다.

If you inspect the code within the constructor, you will see that it creates a new Point object whose x and y values are initialized to 0:

생성자 내부의 코드를 살펴보면, 생성자가 x와 y 값이 0으로 초기화된 새로운 객체 Point를 만드는 것을 보게 됩니다

Rectangle rectTwo = new Rectangle(50, 100);


The Rectangle constructor used in the following statement doesn't take any arguments, so it's called a no-argument constructor:

다음 명령문에 사용된 Rectangle 생성자는 어떤 arguments도 갖고 있지 않아서 이것을 no-argument constructor라고 부릅니다.


Rectangle rect = new Rectangle();


All classes have at least one constructor. 모든 클래스들은 최소한 1개의 생성자를 갖고 있습니다. 


If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor.

어떤 클래스가 어떤 생성자도 명시적으로 선언하지 않으면, 자바 컴파일러는 자동적으로 no-argument constructor를 제공하는데 이것을 default constructor.라고 합니다.


This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent.

기본 생성자는, 클래스 부모의 no-argument 생성자를 호출하거나 또는 클래스가 다른 부모를 갖고 있지 않으면 Object 생성자를 호출합니다. 


If the parent has no constructor (Object does have one), the compiler will reject the program.

부모가 생성자를 갖고 있지 않다면(Object는 1개를 갖고 있음), 컴파일러는 프로그램을 거부할 것입니다.






'그랜저'는 자동차의 공통점과 '그랜저' 만의 특징을 갖는데, 자동차의 공통점은 자동차라는 클래스로부터

상속받고 나머지는 그랜저에 구현하면 됩니다.


class Grangeur extends Car { .... // 그랜저만의 것을 구현 }


class의 기본 용도는 object를 생성하는 것이고, class에 선언된 field와 method는 object를 생성하고 나면 

생성된 object에 속하게 됩니다.

객체가 아닌 class 자체에 속하는 구성요소를 선언해야 될 때도 있는데 그런 구성요소를 class의 static 구성요소라고 합니다.





static field


일반적으로 field는 object의 고유한 데이터 값을 저장하기 위해 사용하지만 경우에 따라서는 object가 아닌class 자체에 속하는 데이터를 지정할 변수도 필요합니다.


이럴 때 사용하는 것이 static field 입니다.


이 field는 class 전체에서 사용가능하므로 class 내부 어디든 이 field에 값을 넣을 수 있지만, 일단 넣으면 그 값을 사용했던 모든 곳이 새 값으로 교체됩니다.


public class StaticExam {

int total = 0;

static int grandTotal = 0;

void staticExam(int value){

total += value;

grandTotal += value;

}

}


위 굵은 부분이 static field의 생성사용부분입니다.

total field는 object마다 따로 생기지만 grandTotal field는 특정 object에 상관없이 class 자체에 하나만 생기는 static field 입니다.


class StaticFieldExam{

public static void main(String args[]){

StaticExam se1 = new StaticExam();

StaticExam se2 = new StaticExam();

se1.staticExam(10);

se2.staticExam(20);

System.out.println("se1.total :"+se1.total);

System.out.println("se1.grandTotal :"+se1.grandTotal);

System.out.println("se2.total :"+se2.total);

System.out.println("se2.grandTotal :"+se2.grandTotal);

}

}


클래스 StaticExam을 instance화하여 2개의 object를 만들었습니다.


se1에는 staticExam method에 10을 파라미터로 넘겼습니다.


void staticExam(int value){

total += value;

       grandTotal += value;

}


이 구문이 수행되어 total과 grandTotal에 10이 들어갑니다.

그리고 다시 제자리로 돌아가 다음 줄인 se2에 20을 실어 method에 보내면 total은 instance field이기 때문에 20이란 새로운 field가 만들어졌고,

grandTotal은 class 자체에 속하는 static field기 때문에 아까 10과 지금의 20을 더하여 갖게 됩니다.


se1.total :10

se1.grandTotal :30

se2.total :20

se2.grandTotal :30


위와 같은 결과가 나옵니다.

total은 se1과 se2의 field에 각각 들어가 있는 반면 grandTotal field에는 값이 누적됩니다.


static field는 class 자체에 속하기 때문에 앞에 object 이름 대신 class 이름을 붙여서 사용할 수도 있습니다.  


StaticExam.grandTotal;



상수(변하지 않는 값)의 선언


static field에 final keyword 까지 붙이면 그 field는 소스 코드에서 주어진 초기값을 프로그램 실행중에 절대 바꿀 수 없게 됩니다.

그래서 상수를 사용하고 싶을 때는 final과 static을 모두 붙여 field를 만들고 이를 상수 변수(constant variable) 라고 부릅니다.


public class static final {

final static int LIMIT = 1000;

int value;

void setValue(int value){

if(value < LIMIT)

this.value = value;

else

this.value = LIMIT;

}

}


이런 식으로 상수 변수를 만들었다.


class static final Exam2{

public static void main(String args[]){

static final sf = new static final();

sf.setValue(1010);

System.out.println("sf.value :"+sf.value);

System.out.println("상한값  :"+static final.LIMIT);

}

}


이런식으로 1010을 파라미터로 넘기면 위 소스에서 1010 < 1000 이기 때문에 else로 빠지고 this.value엔 1000이 들어간다.


결과값은


sf.value :1000

상한값  :1000


이렇다.


static method


static을 붙여 만든 method를 static method라고 합니다.


public class static Method {

int total = 0;

static int grandTotal = 0;

void Method(int value){

total += value;

grandTotal += value;

}

static int getGrandTotal(){

return grandTotal;

}

}


이런 식으로 static method를 선언 할 수 있습니다.


class Static MethodExam{

public static void main(String args[]){

staticMethod sm1 = new staticMethod();

staticMethod sm2 = new staticMethod();

sm1.Method(10);

sm2.Method(20);

int grandTotal = staticMethod.getGrandTotal();  //static method 호출

System.out.println("sm1.total :"+sm1.total);

System.out.println("sm2.total :"+sm2.total);

System.out.println("총계 :"+grandTotal);

}

}



우선 staticMethodclass의 object를 각각 sm1,sm2를 만들고 Method method의 파라미터에 sm1은 10, sm2는 20을 넣었ㅅ브니다.

그럼 우선 total에는 instance field이기 때문에 sm1에는 10이 sm2에는 20이 들어 갈 것입니다.

그리고 그 값들은 차례로 static field인 grandTotal에 쌓인다.

그리고 static method getGrandTotal() 에서 grandTotal을 리턴하기 때문에 프로그램상에서 이 static method를 호출하면 grandTotal이 리턴 값으로온다.

즉 30이 리턴된다.

결과는 이렇다.


sm1.total :10

sm2.total :20

총계 :30


기능적인 method 선언에 유용한 static method


특정 object에 종속되지 않고 기능을 수행하는 method를 기능적인 method라 할 수 있다.

그런 method는 static method로 선언하는 것이 좋다.


static 초기화 블록


static field는 특정 object에 속하지 않기 떄문에, 생성자에서 초기값을 대입하면 안된다.

그렇기에 static field의 초기값을 field 선언문에서 대입할 수 없을 때에는 static 초기화 블록(static initialization 또는 static initializer)을 사용하여야 한다.


public class static Block {

static int arr[];

static{

arr = new int[100];

for(int i = 0; i < 100; i++){

arr[i] = i;

}

}

}


이런식으로 static 초기화 블록을 선언해두면 Java 가상 기계는 이 class가 사용되기전에 한 번 이 블록 안의 명령문을 실행 한다. 그렇기 때문에 위 arr을 사용하기전에 이미 0~99를 채워 놓는다.


class staticExam{

public static void main(String args[]){

System.out.println(staticBlock.arr[20]);

System.out.println(staticBlock.arr[15]);

System.out.println(staticBlock.arr[67]);

}

}


이렇게 하면 이미 채워 놓기 때문에 바로 찍혀나온다.


둘 이상의 static 초기화 블록을 갖는 class


한 class 안에 둘 이상의  static 초기화 블록을 선언 할 수도 있는데 그러면 class 내에 쓰여진 순서대로 수행을 하게 된다.


public class static int {

static int arr1[];

static{

arr1 = new int[10];

for(int i = 0; i < 10; i++){

arr1[i] = i+1;

}

}

static int arr2[];

static{

arr2 = new int[10];

for(int i = 0; i < 10; i++){

arr2[i] = (i+1) * 10000;

}

}

static int arr3[];

static{

arr3 = new int[10];

for(int i = 0; i < 10; i++){

arr3[i] = arr1[i] + arr2[i];

}

}

}


이런식으로 세가지 static 초기화 블록이 있다면


class staticExam{

public static void main(String args[]){

for(int i = 0; i < 10; i++){

System.out.println(staticinit.arr3[i]);

}

}

}

이것을 실행 시켰을 때


10001

20002

30003

40004

50005

60006

70007

80008

90009

100010


이렇게 나온다.

이유는 첫번째 arr1이 1부터 10까지를, 두번째 arr2이 1000부터 10000까지를, 세번째 arr3이 이 둘을 더한 것을 출력한다.

마지막 arr3만 찍었는데 저렇게 나왔다는 것은, 이미 arr1과 arr2 가 수행 되었을 거란 것이고, 이는 static 초기화 블록이 여러개 있다면 위에서부터 쓰여진 순서대로 계산이 된다라는 것을 알 수 있다.


static이 붙으면 class 모든 곳에서 넣는 값이 다 들어가서 뭣도 모를 때 자주 썼지만, 아마 이놈이 메모리를 많이 차지하는 것으로 알고 있다.

쉽게말해 남용하면 안되는 놈이다.

그래서 static을 한동안 안썼다.

안쓰면 좋은거니까.

하지만 일을 하다보니 static없이 하면 코드가 더러워지는 경우가 있다.

결과적으로 필요할 때 딱 써야되는데 그 '필요할 때'만 쓰기가 참 어렵다.



반응형

댓글