자바 객체지향 용어 이해

jadive study·2022년 12월 14일
0

지식 개념창고

목록 보기
1/2

클래스와 객체

클래스의 정의- 클래스란 객체를 정의해 놓은 것이다.
클래스의 용도- 큘래스는 객체를 생성하는데 사용된다.

객체와 인스턴스

클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화(instantiate)라고 하며, 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스(instance)라고한다

속성(property)- 멤버변수(member variable), 특성(attribute》, 필드(field), 상태(state)
기능(function)- 메서드(method), 함수(function), 행위(behavior)

클래스명 변수명;//클래스의 객체를 참조하기 위한 참조변수 선언
변수명 = new 클래스명(); //클래스의 객체 생성, 주소를 참조변수에 저장
Tv t;//TV 클래스타입의 참조변수t를 선언
t = new Tv();//TV인스턴스 생성, 생성된 TV인스턴스의 주소를 t에 저장

  1. Tv t;
    Tv클래스 타입의 참조변수 t를 선언한다. 메모리에 참조변수 t를 위한 공간이 마련
  2. t = new Tv();
    연산자 new에 의해 Tv클래스의 인스턴스가 메모리의 빈 공간에 생성된다.
  • 같은 클래스로부터 생성되었을지라도 각 인스턴스의 속성(멤버변수)은 서로 다른 값을 유지할 수 있으며,메서드의 내용은 모든 인스턴스에 대해 동일하다.

Tv[] tvArr = new Tv[3]; // 참조변수 배열 (객체 배열)을 생성
// 객체를 생성해서 배열의 각 요소에 저장

2.5 객체 배열

Tv[] tvArr = new Tv[3]; // 참조변수 배열 (객체 배열)을 생성
// 객체를 생성해서 배열의 각 요소에 저장

tvArr[0] = new Tv();
tvArr [1] = new Tv();
tvArr [2] = new Tv();

배열의 초기화 블럭을 사용

Tv [ ] tvArr = ( new Tv (), new Tv (), new Tv() };

다뤄야할 객체의 수가 많을 때는 for문을 사용하면 된다.

Tv[] tvArr = new Tv[100];
for(int i=O;i<tvArr.length;i++) {
tvArr[i] = new Tv();
}

2.6 클래스의 또 다른 정의

  • 클래스는
    •객체를 생성하기 위한 틀’이며 ‘클래스는 속성과 기능으로 정의되어있다.
  1. 클래스 - 데이터와 함수의 결합

자바와 같은 객체지향언어에서는 변수(데이터)와 함수를 하나의 클래스에 정의하여 서로 관개 가 깊은 변수와 함수들을 함께 다룰 수 있게 했다.

public final String implements java.io.Serializable, Comparable{
private char[] value;  // 문자열을저장하기위한 공간
public String replace (char oldChar, char newChar) {
char[] val = value; // 같은 클래스 내의 변수를 사용해서 작업을 한다.
}

클래스 一 사용자정의 타입 (user-defined type)
자료형(primitive type),사용자정의 타입(user-defined type) 이라고 한다.

int[]  hour   = new int[3];
int[]  minute = new int[3];
float [] second = new float[3];

->데이터 개수가 많으면?

class Time {
int hour;
int minute;
float second;
}
//비객체지향 코드
int  hourl, hour2, hour3;
int  minutel, minute2, minute3;
float secondl, second2, second3;

객체지향적 코드

Time tl = new Time( );
Time t2 = new Time( );
Time t3 = new Time( );
Time [ ] t = new Time [3];
t[0] = new Time);
t[1] = new Time( );
t[2] = new Time( );
//제어자와 메서드를 이용하여 코드를 쉽게 반영
public class Time {
private int hour;
private int minute;
private float second;
public int getHour()	{return hour;	}
public int getMinute()	{return minute;}
public float getSecond() {return second;}
public void setHour(int h) {
if (h < 0 || h > 23) return;
hour = h;
}
public void setMinute(int m) {
if (m < 0 || m > 59) return;
minute =m;
}
public void setSecond(float s) {
	if(s < 0.0f || s >59.99f) return;
    second =s;
    }
 }
class Variables
{
	int iv; //인스턴스 변수
    static int cv;//클래스변수(static변수, 공유변수)-> 클래스 영역

    void method()
    {
    	int lv = 0; //지역변수 -> 메서드 영역
    }
}

3.1 선언위치에 따른 변수의 종류

class Variables
{
	int iv; //인스턴스 변수
    static int cv;//클래스변수(static변수, 공유변수)-> 클래스 영역

    void method()
    {
    	int lv = 0; //지역변수 -> 메서드 영역
    }
}

3.2 클래스변수와 인스턴스변수

Card클래스의 클래스변수(static변수)인 width, height는 Card클래스의 인스턴스블 생성하지 않고도
•클래스이름.클래스변수’와 같은 방식으로 사용 할 수 있다.

3.3 메서드

특정 작업을 수행하는 일련의 문장들을 하나로묶은 것이다.
메서드에넣을 값(입력)과 반환하는 결과(출력)만 알면 되는 것이다. 그래서 메서드를 내부가 보이지 않는 ‘블랙박스(black box)’라고도 한다.

메서드를 사용하는 이유

1.높은 재사용성

  • 중복된 코드의 제거
static void printArr(int[] numArr) {
for(int i=0;i<10;i++)
System.out.printf(n%d", numArr[i]);
System.out.printin();
}// 여기만 변경
public static void main《String args[]) {
for (int i = 0;i<10;i++)
numArr[i] = (int)(Math.random()*10);
printArr (numArr); // 배열을 출력 —
...중간생략...
printArr (numArr); // 배열을 출력 —
}

2.반복되는 코드대신 메서드호출

3. 프로그램의 구조화

규모의 프로그램에 서는 문장들을 작업단위로 나눠서 여러 개의 메서드에 담아 프로그램의 구조를 단순화시키는 것이 필수적이다.

public static void main(String args[]) {
int [ ] numArr = new int [10];


initArr (numArr); //배열을초기화
printArr(numArr); //배열을 출력
sortArr(numArr); //배열을 정렬
printArr(numArr);//배열을 출력
static int showMenu()
static void inputRecord()
static void changeRecord()
static void deleteRecord()//나중에 내용을 완성한다

public static void main(String args[]) (
switch(showMenu()) {
case    1:    inputRecordf);    break;    //데이터 입력
case    2:    changeRecordO;    break;    //데이터 변경
case    3:    deleteRecordO;    break;    //데이터 삭제
case 4: searchRecordO; break; //데이터 검색
default: showRecordList (); // 데이터의 목록

3.4 메서드의 선언과 구현

선언부(header,머리), 구현부의 body

반환타입메서드이름《타입변수명, 타입변수명,
{
// 메서드 호출시수행될코드
}

int add(int a,int b)
{int result = a + b;
return result; // 호출한 메서드로 결과를 반환한다.
}

메서드 선언부(method declaration, method header)

선언부는 '메서드의 이름’과 ‘매개변수 선언’, 그리고 ‘반환타입’으로 구성

int add (int x, int y) {
int result = x + y;
return result; // 결과를 반환
}

매개변수 선언(parameter declaration)

메서드가 작업을 수행하는데 민요한 값들(입력)을 제공받기 위한 것이며,필요한 값의 개수만큼 변수를 선언하며 각 변수 간의 구분은 쉼표‘,’를 사용

메서드의 이름

메서드는 특정 작업을수행하므로 메서드의 이름은 ‘add’처럼 동사인 경우가 많으며. 이름만으로도 메서드의 기능을 쉽게 알 수 있도록 함축적이면서도 의미있는 이름을 짓도록 노력해야 한다.

반환타입(return type)

작업수행 결과(출력)인 ‘반환값(return value/의 타입을 적는다. 반환값이 없는 경우 반환타입으로 ‘void’를 적어야한다.
아래에 정의된 메서드 ‘print99danAir은 구구단 전체를 출력하는데,작업을 수행하는데 필요한 값도,작업수행의 결과인 반환값도 없다. 그래서 반환타입이 ‘void’이다.

 void print99danAll () {
for(int i=l;i<=9;i++) {
for(int j = 2;j< = 9;j++) {
System.out.printin(j+"*"+i+"="+(j*i)+"");
}
System.out.println();
  }}  
  

메서드의 구현부(method body, 메서드 몸통)

메서드의 선언부 다음에 오는 괄호를 ‘메서드의 구현부’라고 하는데,여기에 메서드를
호출했을 때 수행될 문장들을 넣는다.

return 문

‘void’가 아닌 경우,구현부{}안에 return 반환값;’이 반드시 포함되어 있어야 힌다. 이 문장은 작업을 수행한 결과인 반환값을 호출한 메서드로 전달하는데, 이 값의 타입은 반환타입과 일치하거나 적어도 자동 형변환이 가능한 것
변수를 선언한 수 있는 매개변수와 달리 return문은 단 하나의 값만 반환한
수 있는데, 에서드로의 입력(매개변수)은 여러 개인 수 있어도 출력(반환값)은 최대 하나만 허용

  • 타입이 일치해야한다

지역변수(local variable)

서로 다른 메서드 라면 같은 이름의 변수를 선언해도 된다. 이처럼 메서드 내에 선언된 변수를 ‘지역변수 (local variable)’라고 한다.

int add(int x, int y) {
int result = x + y;
return result;
}
int multiply(int x, int y) {
int result = x * y;
return result;
}

3.5 메서드의 호출

메서드를 호출해야만 구현부{}의 문장들이 수행된다. 메서드를 호출하는 방법은 다음과 같다.

print99danAll (); // void print99danAll(void)를 호출
int result = add (3, 5); // int add (int x, int y)를 호출하고, 걸과 result에저장

인자와 매개변수(parameter)

메서드를 호출할 때 괄호()안에 지정해준 값들을 '인자 (argument)’ 또는 '인수’라고 하는 데, 인자의 개수와 순서는 호출된 메서드에 선인된 매개변수와 일치해야 한다.

메서드의 실행흐름

서로 호출이 가능하지만 static메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없다.

① main메서드에서 메서드 add를 호출한다. 호출시 지정한 1L과 2L이 메서드 add의 매개변 수 a. b에 각각 복사(대입)된다.
② 메서드 add의 괄호{}안에 있는 문장들이 순서대로 수행된다.
③ 메서드 add의 모든 문장이 실행되거나 return문을 만나면,호출한 메서드(main메서드)로 되돌아와서 이후의 문장들을 실행한다.

class MyMathTest {
long add(long a, long b) {
long result = a+b;
return result;
// return a + b; // 위의 두 줄을 이와 같이 한 줄로 간단히 할 수 있다.
}
long subtract (long a, long b) { return a - b; }
long multiply (long a, long b) { return a * b; }
double divide(double a, double b) {
  return a/b;
 }
}
4개 의 메서드가 정의되어 있는 MyMath클래스를 이용한 예제이다
divide(double a, double b)를 호출하는 부분이다. divide메
서드에 선언된 매개변수 타입은 double형인데, 이와 다른 long형의 값인 5L3L을 사용 해서 호줄하는 것이 가능하다.
double result4 = mm.divide ( 5L , 3L );
double divide(double a, double b) {
return a / b;
}

3.6 return문

반환타입이 void가 아닌 경우. 즉 반환값이 있는 경우,반드시 return문이 있어야 한다. return문이 없으면 컴파일 에러(error: missing return statement)가 발생한다.

int multiply (int x, int y) {
int result = x * y;
return result;      // 반환 타입이 void가 아니므로 생략불가
}
int max (int a, int b) {
if (a > b)
return a; // 조건식이 참일 때 실행된다.
else
return b; // 조건식이 거짓일 때 실행된다.
  }
float divide(int x, int y) {
// 작업을 하기전에나누는 수 (y)가 0인지확인한다.
if(y==0) {
System.out.println (0으로 나눌 수 없습니다.);
return 0; // 매개변수가 유효하지 않으므로 메서드를 종료한다.
}return x / (float)y;

}```

---
  여기까지는 이해하기 아주 쉬운데 
 
  
 3.7 JVM 메모리 구조 
 -> cs 지식이 없어서 솔직히 이해하기 힘들다...
  다른 포스팅에 더 자세히 적어보도록 하겠다..
  
 3.8 기본형 매개변수와 참조형 매개변수
  
자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서넘겨준다. 매개변수의 타입이 기본형(primitive type)일 때는 기본형 값이 복사되겠지만,참조형 (reference type)이면 인스턴스의 주소가 복사된다.

기본형 매개변수- 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수- 변수의 값을 읽고 변경할 수 있다. (read & write)
  
```java
class Data { int x; }
class PrimitiveParamEx {
public static void main(String[】 args) {
Data d = new Data();
d.x = 10;
System.out.printin("main() : x =+ d.x);
change(d.x);
System.out.println("After change(d.x)");
System.out.println("main() : x = " + d.x);
}
  static void change (int x) {             // 기본형 매개변수
x = 1000;
System.out.println("change() : x = " + x);
class Data { int x; }
class ReferenceParamEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.printIn("main() : x = " + d.x);
change(d);
System.out .printin (''After change (d)");
System.out.printin(umain() : x = n + d.x);
 }
static void change (Data d) { //참조형 매개변수
 d.x = 1000;
 System.out.println("change():x = " + d.x);
 }}

change메서드의 매개변수를 참조형으로 선언했기 때문에,x의 값이아닌 주소가 매개변수 d에 복사되었다.
이제 main메서드의 참조변수 d와 change메서드의 참조변수 d는 같은 객체를 가리키게 된다. 그래서 매개변수 d로 표의 값을 읽는 것과 변경하는 것이 모두 가능한 것이다. 이 두 예제를 잘 비교해서 차이를 완전히 이해해야한다.

class ReferenceParamEx2 {
public static void main(String[] args)
int[] x = {10};        // 크기가 1 인배열. x[0] = 10;
System.out.printin("main() : x = " + x[0]);
change(x);
System.out.printin("After change(x)n);
System.out.printIn("main()  :  x  =  "  +  x[0]);
  }
static void change (int [] x) ( // 참조형 매개변수
x[0] = 1000;
System.out.printin("change() : x = " + x[0]);
  }}

참조형 매개변수 예제를 Data클래스의 인스턴스 대신 길이가 1인 배열 x를 사용 하도록 변경한 것이다. 배열도 객체와 같이 참조변수를 통해 데이터가 저장된 공간에 접근한다는 것을 이미 배웠다. 이전 에제의 Data클래스 타입의 참조변수 선와 같이 변수 x도 int배열타입의 참조변수이기 때문에 같은 결과를 얻는다.
->예제 6-12

메서드로 배열을 다루는 여러 가지 방법을 보여주는 예제이다. 매개변수의 타입이 배열이니까, 참조형 매개변수이다. 그래서 sortArr메서드에서 정렬한 것이 원래의 배열에 영향을 미친다. 그 외에는 따로 설명하지 않아도 충분히 이해가 될 것이다.
->예제 6-13


이부분 역시도 이해가 잘안되기 때문에, (정말 바보 ㅜㅜ)
다시 스크랩 해봐야겠다

class ReturnTest {
public static void main(String[] args) (
ReturnTest r = new ReturnTest ();
int result = r.add(3,5);
System.out.printIn(result);

int [] result2 = (0); // 배열올 생성하고 result2[0]의 값을 0으로 초기화
r.add(3,5,rewult2);//배열을 add메서드의 메게변수로 전달
  system.out.println(result2[0]);
  }
  int add(int a, int b)

3.9 참조형 반환타입

매개변수뿐만 아니라 반환타입도 참조형이 될 수 있다. 반환타입 이 참조형 이라는 것은 반 환하는 값의 타입이 참조형이라는 얘긴데,모든 참조형 타입의 값은 ‘객체의 주소’이므로 그저 정수값이 반환되는 것일 뿐 특별할 것이 없다.

class Data { int x; }
class ReferenceReturnEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
Data d2 = copy(d);
Sys tern, out .print In ("d.x ="+d.x);
System.out.printin("d2.x="+d2,x);
}
static Data copy(Data d) {
Data tmp = new Data();
tmp.x = d.x;
return tmp}};

copy메서드는 새로운 객체를 생성한 다음에, 매개변수로 넘겨받은 객체에 저장된 값을 복사해서 반환한다. 반환하는 값이 Data객체의 주소이므로 반환 타입이 ‘Data'인 것이다.

3.10 재귀호출(recursive call)

void method() {
method (); // 재귀호출. 메서드 자신을 호출
}

'메서드 호출’이라는 것이 그저 특정 위치에 저장되어 있는 명령들을 수행하는 것일 뿐이기 때문이다.
호출된 메서드는 ‘값에 의한 호출(call by value)’을 통해, 원래의 값이 아닌 복사된 값으 로 작업하기 때문에 호출한 메서드와 관계없이 독립적인 작업수행이 가능하다.

void method(int n) {
if (n = = 0)
return; // n의 값이 0일 때, 메서드를 종료한다.
System.out.printIn(n);
method (--n);        // 재귀호출. method (int n) 을 호출
}

이번엔 ‘factorial(2)’를 호출했을 때의 실행과정을 살펴보자. 매개변수의 값이 1이 아니므 로 조건식이 거짓이 되어 그 다음 문장인 return 2 factorial(l);’이 수행되고,이 식을 계산하는 과정에서 다시 factorial(l)이 호출된다.
① factorial⑵를 호출하면서 매개변수 n에 2가 복사된다.
② ‘return 2
factorial(1);을 계산하려면 factorial(1)을 호출한 결과가 필요하다.
그래서 factorial⑴이 호출되고 매개변수 n에 10| 복사된다.
③ if문의 조건식이 참이므로 1을 반환하면서 메서드는 종료된다. 그리고 factorial(1)을 호출한곳으로 되돌아간다.
④ 이제 factorial(l)의 결과값인 1을 얻었으므로. ret니이문이 다음의 과정으로 계산된다.
return 2 ★ factorial(1);
—>return 2*1;
—> return 2;

3.11 클래스 메서드(static메서드)와 인스턴스 메서드

메서드 앞에 static이 붙어 있으면 클래스메서드이고 붙어 있지 않으면 인스턴스 메서드이다.
클래스 메서드도 클래스변수처럼,객체를 생성하지 않고도 ‘클래스이름.메서드이름(매개변수)’와 같은 식으로 호출이 가능하다. 반면에 인스턴스 메서드는 반드시 객체를 생성해야만 호출할 수 있다.

인스턴스 메서드는 인스턴스 변수와 관련된 작업을 하는, 즉 메서드의 작업을 수행하는 데 인스턴스 변수를 필요로 하는 메서드이다. 그런데 인스턴스 변수는 인스턴스(객체)를 생성해야만 만들어지므로 인스턴스 메서드 역시 인스턴스를 생성해야만 호출할 수 있는 것이다.
반면에 메서드 중에서 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드를 클래스 메서드(static메서드)로 정의한다

  1. 클래스를 설계할 때,멤버변수중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
  2. 클래스 변수(static변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
  3. 클래스 메서드《static메서드》는 인스턴스 변수를 사용할 수 없다.
  4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면,static을 붙이는 것을 고려한다.
  • 메서드의 작업내용 중에서 인스턴스변수를 필요로 한다면,static을 붙일 수 없다. 반대로 인 스턴스변수를 필요로 하지 않는다면 static을 붙이자. 메서드 호출시간이 짧아지므로 성능이향상된다.
  • 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴 보고 있으면, static을 붙여준다.
  • 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 static을 붙일 것을 고려한다.

3.12 클래스 멤버와 인스턴스 멤버간의 참조와 호출

 class Testclass {
  void instanceMethodO {}
static void staticMethod()
void instanceMethod2() {
instanceMethod();
sstatic void staticMethod2()
instanceMethod();
staticMethod();
  } // end of class

같은 클래스 내의 인스턴스 메서드와 static메서드 간의 호출에 대해서 설명
하고 있다. 같은 클래스 내의 메서드는 서로 객체의 생성이나 참조변수 없이 직접 호출이 가능하지만 static메서드는 인스턴스 메서드를 호출할 수 없다.

profile
개발 메모창고

0개의 댓글