LostCatBox

Java 배우기 CH06

Word count: 2.1kReading time: 13 min
2022/12/23 19 Share

객체 지향 언어 (6장~7장)

객체 지향언어 특성

  • 코드 재사용성이 높고, 유지보수가용이, 중복 코드 제거
  • 객체지향 언어 = 프로그래밍 언어 + 객체지향개념(규칙)

객체 지향언어 핵심 개념(일단 외우기 !!!)

  1. 캡슐화
  2. 상속
  3. 추상화
  4. 다형성

객체지향개념 1

클래스와 객체

  • 클래스의 정의: 클래스란 객체를 정의해 놓은것 (객체를 찍어내기위한 설계도면!)

  • 클래스의 용도: 클래스는 객체를 생성하는데 사용

  • 객체의 정의: 실제로 존재하는것, 사물 또는 개념 (제품)

  • 객체의 용도: 객체가 가지고 있는 기능과 속성에 따라 다름

Untitled

  • 클래스를 만든후 객체를 만들수있음

객체의 구성요소 - 속성과 기능

  • 하드웨어 개념이 소프트화 하여, 컴퓨터안으로 집어넣을때 객체지향 사용
  • 객체 = 속성(변수) + 기능(메서드)
    TV = 크기,길이, 채널, 볼륨 ⇒ 변수/ 켜기 끄기, 볼륨 높이기, 채널 변경⇒메서드
  • 따라서 TV 클래스(설계도)

Untitled

객체와 인스턴스

  • 객체: 모든 인스턴스를 대표하는 일반적인 용어
  • 인스턴스: 특정 클래스로부터 생성된 객체(예: TV인스턴스)
  • 클래스 → 인스턴스화 → 인스턴스(객체)

Untitled

  • 클래스: 객체를 생성하기 위해
  • 객체: 사용하기 위해
  • 객체 사용: 객체가 가진 속성(변수)과 기능(메서드)을 사용

하나의 소스파일에 여러 클래스 작성

  • 원래는 소스파일 하나에 클래스 하나가 원칙이다
  • 무조건 하나의 소스파일에는 public파일 반드시 하나가 규칙이다.
  • 여러 클래스 작성시에는 public class의 이름을 따서 소스파일 이름 지정
  • public없다면, 둘중 하나 class 이름 따서 소스파일 이름 지정
  • 소문자, 대문자 모두 맞추기

Untitled

  • 소스파일 이름과 main메서드 있는 클래스이름 일치 반드시 확인해야함 (틀리면다른것 실행됨)

객체의 생성과 사용

1. 클래스 작성

  • 설계도 작성

2. 객체의 생성

Untitled

  • TV t; 참조변수(리모콘) 선언 (객체를 다루기위한)
  • new Tv()가 객체 생성부분 (특히, Tv()는 생성자 호출부분)
  • t = new Tv()를 통해 참조변수와 객체를 연결
  • Tv t = new Tv() 와 같다

3. 객체의 사용(변수, 메서드 사용)

  • 객체의 변수 사용
  • 객체의 메서드 사용

Untitled

  • 리모콘 t가 가르키는 객체의 변수 번경이나 메서드 호출

객체의 생성과 사용

  • 타입 기본형 아니면 모두 참조형
  • 참조변수 t의 타입이 TV이고 이는 생성되는 TV객체와 일치하므로 사용가능
  • new연산자는 객체를 만들고 객체 주소를 반환됨
  • 대입연산자에의해 t 참조변수에 해당 객체 주소 대입
  • 참조변수가 없다면, 객체를 다룰수없다.

Untitled

  • TV클래스는 6개의 맴버(변수3개+메서드3개) 이며, TV객체도 6개 맴버가짐
  • 객체마다 별도 저장공간생김
  • 아래처럼 t2=t1을 할경우, t2는 t1과 같은 객체주소를 가르킴
  • 기존 0x200에 있던 객체는 GC에 의해 제거됨

Untitled

  • 하나의 인스턴스를 여러 개의 참조변수가 가르키는 경우 (가능)
  • 여러 인스턴스를 하나의 참조변수가 가르키는 경우..여러개 가르킬수없음(불가능)

객체 배열(!!!)

  • 객체 배열 == 참조변수 배열
  • 참조변수로 구성된 배열임!!
  • 이는 참조변수 배열 >>반드시 객체 생성해서 대입해줘야함
1
2
3
4
5
6
Tv tv1, tv2, tv3;
Tv[] tvArr = new Tv[3]; // 이는 참조변수 배열임! 반드시 객체 생성해서 대입해줘야함

tvArr[0] = new Tv() //각 참조변수에 객체 주소 대입됨
tvArr[1] = new Tv()
tvArr[2] = new Tv()

클래스의 정의(1)

  • 클래스
    • 설계도
    • 데이터 + 함수
    • 사용자 정의 타입

스크린샷 2022-05-13 오후 5.35.37.png

  • 클래스는 결국 변수(데이터)와 관련 함수(메서드) 명령문 묶음

클래스의 정의(2)

  • 사용자 정의 타입 - 원하는 타입을 직접 만들수있다.
  • 시간을 다루기 위한 클래스 직접 짤수있음
1
2
3
4
5
6
7
8
int hour1, hour2, hour3
int minute1, minute2, minute3

int hour;
int minute ;

int[] hour = new int[2]
int[] minute = new int[2]

위와 같은 한계를 클래스로 극복가능

1
2
3
4
5
6
7
8
9
10
11
class Time {
int hour;
int minute;
}

Time t1 = new Time()
Time t2 = new Time()

Time[] t = new Time[2];
t[0]= new Time()
t[1]= new Time()
  • 저장 공간 관리에서도 객체지향적
    (서로 관련된 데이터묶음, 유지보수, 코드 간결)

스크린샷 2022-05-13 오후 5.44.12.png

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

  • 영역 2가지 (클래스, 메서드)
    • 클래스 영역 - iv (intance valiable)
    • 클래스 영역 - cv (static + iv)
    • 메서드 영역 - lv( local valiable)

스크린샷 2022-05-13 오후 6.22.47.png

  • 클래스 영역: 선언문만 가능 (메서드 선언, 변수선언)(순서상관없음)

스크린샷 2022-05-13 오후 6.30.00.png

  • lv 스코프는 변수 선언문이 수행되었을때까지만 유효함.. (매서드 종료시 자동제거)
  • iv, cv는 클래스 영역 전체에서 사용가능
  • iv는 인스턴스가 생성되었을때 생성됨!!! (객체 생성 필요> 그후 사용가능)
    ex) new Tv()
  • cv는 클래스가 메모리에 올라갈때 생성(객체 생성필요없음)(아무떄나 사용가능)
  • 객체 = iv들 묶은 것

클래스 변수(cv)와 인스턴스 변수(iv)

  • 선언위치에 따라 클래스영역(iv, cv), 메서드 영역 (lv)로 나뉨
  • iv = 개별 변수 성격
  • cv = 공유성격

스크린샷 2022-05-13 오후 7.05.36.png

1
2
3
4
5
6
7
8
9
10
11
12
13
Card c = new Card();

//(참조변수.iv)
c.kind = "HEART"; //iv = 개별 변수 성격
c.number = 5; //iv = 개별 변수 성격

//(참조변수.cv) - 비권장
c.width = 200; //cv = 공유성격 static의 비권장 사용법
c.height = 300; //cv = 공유성격 static의 비권장 사용법

//(클래스이름.cv)
Card.width = 200; //cv = static의 권장 사용법(클래스이름.cv)
Card.height = 300; //cv = static의 권장 사용법
  • 아래와 같이 할당된다

스크린샷 2022-05-13 오후 7.17.24.png

  • iv는 객체당 맴버수만큼있지만
  • cv는 객체당 없다. 다른공간에 하나만 유지함.
  • 따라서 참조변수.cv를 바껴도 다른 객체도 바뀜… (비권장)
    항상 클래스.cv로만 변경하자(권장)

메서드란?

  • 메서드란 클래스 안에 있는 함수!
  • 함수는 독립존재도 가능

메서드의 선언부와 구현부

  • 작업단위로 문장들을 묶어서 이름 붙임(중복피함)
  • 값(입력)을 받아서 처리하고, 결과를 반환(출력)

스크린샷 2022-05-13 오후 7.50.30.png

메서드의 장점

  • 코드의 중복 제거(간결화 가능)
  • 코드의 관리
  • 코드를 재사용

메서드의 작성

  • 반복적으로 수행되는 여러 문장을 메서드로 작성
  • 하나의 메서드는 한 가지 기능만 수행하도록 작성(최소단위로)

메서드 구성

  • 메서드 = 선언부 + 구현부
  • 선언부에는 작업결과 타입 + 메서드 이름+ (매개변수(타입 변수명)들 목록)
    {구현부}
  • 입력값(0개~n개)
  • 출력값(0개~1개) >>여러개 필요시 배열 또는 객체로 반환
    • 반환이 없다면 반환타입에 void라고 적기

스크린샷 2022-05-13 오후 7.56.00.png

지역 변수(lv)

  • 메서드 내에 선언된 변수

  • 메서드가 끝나면 모두 제거됨

  • 매개변수 또한 지역변수.. 따라서 함수마다 같은 이름 매개변수 써도상관없음

스크린샷 2022-05-13 오후 8.04.42.png

메서드의 호출

  • 함수는 호출시 각 매개변수와 지역변수, 명령어 수행후 다시 호출했던곳으로 돌아옴(리턴유무상관없음)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MyMath mm = new MyMath(); // 객체 생성
long result1 = mm.add(5L, 3L); // 타입맞춰서 넣어줌(범위더작은경우 자동으로 행변환됨
long result2 = mm.subtract(5L, 3L);
long result3 = mm.multiply(5L, 3L);
double result4 = mm.divide(5L, 3L);

//클래스 정의
class MyMath {
long max(long a, long b) {
long result = a>b ?a:b;
return result;
}
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;
}

return문, 반환값

  • 실행 중인 메서드를 종료하고 호출한 곳으로 돌아간다.
  • void 함수명 (매개변수) {함수명} >>메서드에 return 없어도됨
  • 반환 타입이 void가 아닌 경우, 반드시 return 문 필요
1
2
3
4
5
6
//반환 타입 void아닌경우, 반드시 return 문 필요
int max(int a, int b) {
if(a>b)
return a; //조건식이 참일때
//조건식이 거짓일때는 return 없으므로 오류
}

스크린샷 2022-05-13 오후 11.47.59.png

  • 반드시 반환타입과 return되는 값이 타입일치 또는 자동형변환되는 값을 해야함
  • 또한 반환되어 새로운 값을 저장할 변수도 타입을 일치하는지확인필요!

호출 스택

  • 스택: 밑에 막힌 상자, 위에 차곡차곡 쌓인다

  • FILO

  • 메서드 수행에 필요한 메모리가 제공되는공간

  • 메서드가 호출되면 호출스택에 메모리 할당, 종료되면 해제

  • 아래있는 메서드가 위의 메서드를 호출하고 반환할때까지 대기함

    스크린샷 2022-05-13 오후 11.58.17.png

  • 기본적으로 쓰레드는 스택 하나씩 가짐. 여러개 가능

  • 하나의 스택에 하나의 메서드만 실행중

기본형 매개변수(!!!중요)(매개변수만해당)

  • 기본형 매개변수 - 변수의 값을 읽기만 할수있다(read only)

  • 참조형 매개변수 - 변수의 값을 읽고 변경할수있다(read &write)

  • 메모리 구조와 같이 보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Data { int x; }

class Ex6_6 {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("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) { // 기본형 매개변수, read only임, 기존main메서드의 x와 다름
x = 1000; //지역변수 이므로 함수종료시 사라지며, 기존main메서드의 x와 다름
System.out.println("change() : x = " + x);
}
}
  • 아래 메모리와 그림 그릴줄알기

스크린샷 2022-05-14 오전 12.18.47.png

  • main메서드의 객체 상성시 int x의 메모리 주소가 부여되며, 이를 d 참조변수가 가르킴
  • change(d.x)시 d.x의 값으로 기본형 매개변수(지역변수) int x의 값으로 지정됨.(read only)(값 복사만읽어남)
  • 하지만 x=1000;일어나는 순간 지역변수 int x의 값이 변경됨.(원본과상관없는 지역변수)
  • 기본형 매개변수가 아닌 참조형을 변경한다면, 원본 int x를 변경할수있음

참조형 변수

  • 기본형 매개변수 - 변수의 값을 읽기만 할수있다(read only)
  • 참조형 매개변수 - 변수의 값을 일고 변경할수있다(read &write)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Data2 { int x; }

class Ex6_7 {
public static void main(String[] args) {
Data2 d = new Data2();
d.x = 10;
System.out.println("main() : x = " + d.x);

change(d);
System.out.println("After change(d)");
System.out.println("main() : x = " + d.x);
}

static void change(Data2 d) { // 참조형 매개변수
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}

스크린샷 2022-05-14 오전 12.33.21.png

  • main메서드의 객체 상성시 int x의 메모리 주소가 부여되며, 이를 d 참조변수가 가르킴
  • change(d)시 d의 가르키는 메모리 값를 참조형 매개변수(지역변수)도 가르키는것으로 지정됨.(read &write)(값 주소를 가르킴)
  • x=1000;일어나는 순간 참조형 매개변수(지역변수)가 가르키는 int x의 값이 변경됨.(원본인 메모리 int x의 값이 변경됨)
  • 참조형사용시 원본 int x를 변경할수있음
  • 즉 리모콘을 전달해서 객체를 다룰수있게됨 (read&write)

참조형 반환타입(!!!)

  • 반환하는것이 객체를 반환(객체의주소를 반환함!!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Data3 { int x; }

class Ex6_8 {
public static void main(String[] args) {
Data3 d = new Data3();
d.x = 10;

Data3 d2 = copy(d);
System.out.println("d.x ="+d.x);
System.out.println("d2.x="+d2.x);
}

static Data3 copy(Data3 d) {
Data3 tmp = new Data3(); // 새로운 객체 tmp를 생성한다.

tmp.x = d.x; // d.x의 값을 tmp.x에 복사한다.

return tmp; // 복사한 객체의 주소를 반환한다.
}
}

스크린샷 2022-05-14 오전 12.52.42.png

  • d2가 main에 만들어지고, copy영역이 스택에 올라가고, copy영역의 d는 결국 원본 객체 int x의 주소를 가르킴

  • copy영역에 tmp가 만들어지고 new Data3()해당하는 메모리 주소를 가르킴

  • d.x의 값이 tmp.x값으로 저장됨 (값 10)

  • return tmp로 참조형이므로 객체 메모리 주소가 반환됨. copy영역종료

  • main영역의 d2에 바로위 객체 메모리 주소를 가르킴

  • 즉 객체를 반환(객체주소를 반환하는것임)

  • 참고로 static 메서드는 객체 생성없이 호출가능 + 같은 클래스에 있으므로 참조변수.메서드로 안써도됨

static메서드와 인스턴스 메서드(iv사용여부구별)

  • 인스턴스 메서드
    • 인스턴스 생성후, 참조변수.메서드이름() 으로 호출
    • 인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드
    • 메서드 내에서 인스턴스 변수(iv) 사용가능
  • static메서드
    • 클래스 메서드앞에 static 붙은것!
    • 객체 생성없이 ‘클래스이름.메서드이름()’ 으로 호출
      ex) Math.random()
    • 인스턴스 멤버(iv, im)와 관련없는 작업을 하는 메서드
    • 메서드 내에서 인스턴스 변수(iv) 사용불가

스크린샷 2022-05-14 오후 1.34.58.png

스크린샷 2022-05-14 오후 1.36.09.png

static은 언제 붙여야 할까?

스크린샷 2022-05-14 오후 1.44.45.png

  • 특히 속성은 객체마다 다르고, 공통속성은 객체마다 같다
  • 하지만 인스턴스 메서드와 static메서드는 객체마다 모두 같다.
    단지 iv 사용여부의 차이

메서드 간의 호출과 참조

  • static메서드는 인스턴스 변수(iv), 인스턴스 메서드(im)호출을 사용할수없다
  • 즉, static메서드 호출시 객체(iv묶음)이없을수도있으므로 인스턴스 멤버를 쓸수없다.
  • 당연히..iv는 객체생성후 사용가능임.
  • cv는 언제나 사용가능

스크린샷 2022-05-14 오후 1.51.42.png

스크린샷 2022-05-14 오후 2.35.00.png

오버로딩(overloading)

  • 한 클래스 안에 같은 이름의 메서드 여러 개 정의하는 것

스크린샷 2022-05-14 오후 2.42.12.png

오버로딩이 성립하기 위한 조건

  1. 메서드 이름이 같아야 한다.
  2. 매개변수의 개수 또는 타입이 달라야한다.
  3. 반환 타입은 영향없다(반환타입 다름여부 상관없이안됨)
  • 보기 1,2번 틀림, 보기 3번 오버로딩 맞음

스크린샷 2022-05-14 오후 2.48.09.png

  • 보기 3번 클래스의 메서드를 add(3,3) 이라면 에러남 (ambiguous모호함)
  • 메서드는 보통 동사이며, 이름이 같다면 같은 작업을 하는것이다

생성자(constructor)

1
Card c = new Card();// Card()부분이 생성자호출임... 정의한적없다면, 기본생성자호출
  • 인스턴스가 생성될 떄마다 호출되는 인스턴스 초기화 메서드
    (iv초기화해주는 메서드)
  • 인스턴스 생성시 수행할 작업(iv 초기화)에 사용
  • 모든 클래스는 반드시 한개이상의 생성자를 가져야함

생성자 생성방법

  • 이름이 클래스 이름과 같아야한다
  • 항상 리턴값이 없다(void 안붙임)(메서드와 다른부분)
    초기화는 대입문이므로 반환할것없음
  • 정의한적없다면, 기본생성자호출

스크린샷 2022-05-14 오후 3.10.29.png

기본 생성자(default constructor)

  • 매개변수가 없는 생성자
  • 생성자가 하나도 없을 떄만, 컴파일러가 자동 추가
  • 반드시 기본생성자 넣는 습관들이기(!!!)
1
클래스이름() {}
  • 컴파일러 자동 기본 생성자 호출 의지할때 문제점은 컴파일러가 하나라도잇으면 추가해주지만, 한개라도있으면, 내가 넣어줘야함

스크린샷 2022-05-14 오후 3.21.54.png

매개변수가 있는 생성자

  • 생성자 직접 만들어주면 확실히 단순해지고 편해짐

스크린샷 2022-05-14 오후 3.29.36.png

  • 순서 중요

스크린샷 2022-05-14 오후 3.32.39.png

  1. 참조변수 생성
  2. new가 객체 생성
  3. 생성자호출하여 객체 초기화
  4. 객체 주소 참조변수에 대입

생성자 this()

  • 같은클래스안에 생성자에서 다른 생성자 호출할때 사용(클래스이름안쓰고, this씀)
  • 다른 생성자 호출시 첫 줄에서만 사용가능.
    ( door=5; this(color, “auto”, 4);오류
  • 코드 중복을 피하기 위해 사용

스크린샷 2022-05-14 오후 3.37.30.png

스크린샷 2022-05-14 오후 3.38.48.png

참조변수 this ≠ 생성자 this()

  • 인스턴스 자신을 가리키는 참조변수
  • 인스턴스 메서드(생성자 포함)에서 사용가능(인스턴스에서만 가능 static불가)
  • 지역변수(lv)와 인스턴스 변수(iv)를 구별할 떄 사용
  • 아래 표 다시확인

스크린샷 2022-05-13 오후 6.30.00.png

  • 같은 클래스안에서 iv는 this생략가능, 하지만 lv와 iv의 이름이 같다면, this.iv로 해줘야함. (안해주면 lv가 가까우므로 둘다 lv로 취급당해버림)
  • 아래 lv 와 iv가 이름이 같으면 this.iv반드시 해야함

스크린샷 2022-05-14 오후 3.48.35.png

참조변수 this와 생성자 this()

스크린샷 2022-05-14 오후 3.57.35.png

변수의 초기화 & 멤버변수의 초기화

  • 지역변수(lv)는 수동 초기화 해야함(!!!)
  • 멤버변수(iv, cv)는 자동 초기화된다.
  • 메서드는 재사용이 빈번, 지역변수 또한 주기가 짧음에 따라 수동으로 초기화해야함
    (나머지 인스턴스 변수, 클래스 변수 등등은 자동으로 초기화됨, 객체는 여러변수가 많기 때문에, 자동으로함)

스크린샷 2022-05-14 오후 4.18.28.png

멤버변수의 초기화

  • 자동초기화(cv, iv가 됨), 간단초기화(=), 복잡초기화(iv,cv, 생성자)
  • 기본형 변수는 타입에 따라 초기화되는것 다름
  • 참조형 변수는 null 또는 객체 주소만 가질수있음.

스크린샷 2022-05-14 오후 4.19.47.png

1. 명시적 초기화(간단초기화)

  • 대입연산자 선언시

스크린샷 2022-05-14 오후 4.21.12.png

  • 기본형 변수는 자료형에따라 다르다.
  • 참조형 변수는 null 또는 객체 주소만 가질수있음.>> 객체생성후 초기화~~하자

2. 초기화 블럭(복잡한 초기화)(여러문장)

  • 인스턴스(iv) 초기화 블럭 : {}
  • 클래스(cv) 초기화 블럭 : static {}

3. 생성자(iv초기화에 사용)(복잡한 초기화)

스크린샷 2022-05-14 오후 4.27.04.png

멤버변수의 초기화의 초기화 - static{ }

스크린샷 2022-05-14 오후 4.32.05.png

멤버변수의 초기화의 초기화 시점

  • 클래스 변수 초기화 시점: 클래스가 처음 로딩될때 단 한번(메모리에 올라갈때)
  • 인스턴스 변수 초기화 시점: 인스턴스가 생성될 때마다

스크린샷 2022-05-14 오후 4.37.03.png

  • 순서 중요(!!!)
  • cv→iv
  • 자동→간단→복잡(static{}, 생성자)
  • 객체를 여기에서 새로 또 만들면 인스턴스 변수 초기화들(4,5,6,7)순으로 일어남
CATALOG
  1. 1. 객체 지향 언어 (6장~7장)
  2. 2. 객체지향개념 1