ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [자바의 정석] 6장 객체지향 언어 1. 1~3 변수와 메서드
    개발/JAVA 2023. 3. 7. 23:43
    728x90

    아래 내용은 자바의 정석 강의&책을 보면서 정리한 내용입니다.

    들어가기 전에

    자바 공부 방식 

    공부 방식은 아래와 같습니다.

    • 객체지향 개념: 자바의 정석 6, 7장 보기 → 내가 이해한 개념을 A4용지에 2장으로 정리하여 암기하기!
    • 공부 순서: 자바 기초&자바의 정석 ⇒ jsp, spring ⇒ 설계(디자인 패턴, 객체지향)

     

    자바의 정석 6장 내용 리스트 

    이번 시간에는 아래 내용 중 객체지향언어 ~변수와 메서드 부분을 정리하겠습니다. 

     

    1. 객체 지향 언어

    객체지향은 기존에 있는 프로그래밍 언어에 객체지향 개념만 추가된 것이다.

    ⭐  객체지향언어: 프로그래밍 언어 + 객체지향 개념(규칙)[암기 필요]

     

    OOP(객체 지향 프로그래밍) 핵심 개념

    1. 캡슐화
    2. 상속
    3. 추상화
    4. ⭐️ 다형성: 가장 중요!

     

    객체지향언어 특징

    1. 코드의 재사용성
    2. 코드의 관리 용이
    3. 신뢰성이 높은 프로그래밍 : 제어자와 메서드를 이용하여 데이터를 보호

     

     

     

     

    2. 클래스와 객체

    2.1 클래스와 객체의 정의와 용도

      클래스  객체 
    의미  객체를 정의해 놓은 것
    → 객체를 생성하는데 사용
    실제로 존재하는 것
    → 객체가 가지고 있는 기능과 속성에 따라 다름
    예시  제품 설계도
    TV 설계도
    제품
    TV

     

    2.2 객체와 인스턴스

    • 간단하게 같은 의미라고 생각하자.
      객체  인스턴스
    의미  일반적으로 ‘객체’를 사용 * 클래스 -(인스턴스화)→ 인스턴스(객체)
    *   어떤 클래스로부터 만들어진 객체를 강조할 때 사용 ex) TV 인스턴스 ⇒ TV 클래스로부터 만들어진 객체

     

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

    ⭐ 객체 = 속성(멤버변수) + 기능(메서드) 집합

    아래와 같이 TV의 속성과 기능을 나눌 수 있고, 실제로 java에서 클래스 선언 시 변수와 메서드로 구성한다.

     

    2.4 인스턴스 생성과 사용

    객체를 생성하는 과정 두 가지를 살펴보자.

    1) 객체 생성 과정

    아래 객체 생성을 그림으로 한 줄씩 살펴보자.

    // 1. 클래스 작성 (설계도) 
    class Tv {
        // Tv 속성 (멤버 변수)
        String color;
        boolean power;
        int channel;
        // Tv의 기능(메서드)
        void power(){ power =!power;}
        void channelUp(){ ++channel;}
        void channelDown() {--channel;}
    
    }
    
    public class TvTest {
        public static void main(String[] args) {
    				// 2. 객체 생성 
            Tv t;
            t = new Tv();
    				// 3. 객체 사용 
            t.channel = 7;
            t.channelDown();
            System.out.println("현재 채널은 " + t.channel + "입니다.");
        }
    }
    
      • 메모리에 참조변수(리모컨) t 공간이 확보가 된다.
        • 참조변수: 다른 변수의 메모리 위치를 저장하고 있는 변수를 의미한다. 참조변수 생성: Tv t;

    2. 객체 생성 & 참조변수에 넣기 : t = new Tv();

    • 연산자 new에 의해 Tv클래스의 인스턴스가 메모리의 빈 공간에 생성
      • 객체의 멤버들은 초기화되어 생성
    • 대입 연산자를 통해 객체의 주소값이 t에 저장

    3. 객체 사용: t.channel = 7;

    • channel에 7을 저장한다.

    4. 객체 사용: t.channelDown();

    • channelDown 메서드를 호출하여 channel를 1 감소시킨다.

     

    5. System.out.println("현재 채널은 " + t.channel + "입니다.");

    • 감소된 6이 출력된다.

     

     

    2) 객체 생성 과정 - 두 개

    아래 예제에서 주의할 부분은 t2 = t1;이다. t2가 지닌 참조변수가 변경되는 부분이다.

    class Tv {
        // Tv 속성 (멤버 변수)
        String color;
        boolean power;
        int channel;
        // Tv의 기능(메서드)
        void power(){ power =!power;}
        void channelUp(){ ++channel;}
        void channelDown() {--channel;}
    
    }
    
    public class TvTest {
        public static void main(String[] args) {
            Tv t1 = new Tv();
            Tv t2 = new Tv();
            System.out.println("t1 현재 채널은 " + t1.channel + "입니다.");
            System.out.println("t2 현재 채널은 " + t2.channel + "입니다.");
            t2 = t1;
            t1.channel = 7;
            System.out.println("t1 현재 채널은 " + t1.channel + "입니다.");  // t1 현재 채널은 7입니다.
            System.out.println("t2 현재 채널은 " + t2.channel + "입니다.");  // t2 현재 채널은 7입니다.
    
        }
        }
    
    1. Tv t1 = new Tv(); Tv t2 = new Tv();

    2. t2 = t1;

    • t2도 t1과 동일한 값을 참조한다.
    • 결과적으로 0x200번지 객체는 참조하지 않아 GC에 의해 제거된다.

     

    2.5 객체 배열

    ⭐  객체 배열 == 참조변수 배열

    아래는 3개의 Tv 객체를 만드는 방법입니다.

    class Tv {
        // Tv 속성 (멤버 변수)
        String color;
        boolean power;
        int channel;
        // Tv의 기능(메서드)
        void power(){ power =!power;}
        void channelUp(){ ++channel;}
        void channelDown() {--channel;}
    
    }
    
    public class TvTest {
        public static void main(String[] args) {
           Tv[] tvArr = new Tv[3];
           
           for(int i = 0; i < tvArr.length; i++){
               tvArr[i] = new Tv();
           }
           
        }
        }
    
    1. Tv [] tvArr = new Tv[3];
      • new Tv[3]는 참조변수 배열을 의미한다.

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

    • for문을 돌려 Tv라는 객체를 생성해준다.

     

    2.6 클래스의 또 다른 정의

    클래스는 크게 3가지 의미를 지닌다.

    1. 설계도
      • 객체를 생성하기 위한 틀
    2. 데이터 + 함수 (구조체 + 함수)
      • 클래스는 데이터와 함수의 결합으로 즉, 구조체 + 함수이다.
    3. 사용자 정의 타입
      • 사용자가 원하는 타입을 직접 만들 수 있다.

     

     

    3. 변수와 메서드

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

    변수는 클래스 변수, 인스턴스 변수, 지역 변수 모두 세 종류가 있다. 자세한 부분은 표를 보면 알 수 있다.

     

    변수의 종류 선언 위치  생성 시기  설명 
    클래스 변수 (CV) 클래스 영역 클래스가 메모리에 올라갈 때 - 클래스 변수 선언 방법은 앞에 static를 붙이면 됨
    - 인스턴스마다 독립적인 저장공간을 갖는 인스턴스 변수와 다르게 클래스 변수는 모든 인스턴스가 공유하게 된다.
    - 객체 생성이 필요없이 사용 가능 - 접근하기 위해 “클래스이름.클래스변수”
    - public을 넣으면 프로그램 내 어디서나 접근할 수 있는 전역변수 성격을 지님
    인스턴스 변수 (IV) 클래스 영역 인스턴스 생성 시 - 값을 읽거나 저장을 위해서는 인스턴스를 생성해야함
    - 인스턴스는 독립적인 저장공간을 가진다.
    지역 변수 (LV) 클래스 영역 이외의 영역
    (메서드, 생성자, 초기화 블럭 내부)
    변수 선언문이 수행되었을 때 - 메서드 내에서만 사용 가능하며 메서드 종료되면 소멸되어 사용이 불가능하다.
    - {} 블록 내에서만 사용 가능

     

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

     클래스 변수:
     아래 예시와 같이 모든 카드가 공통으로 가진 속성을 선언한다. ex) 카드의 폭, 높이 
    ⭐  인스턴스 변수:
     개별 속성인 경우 사용 ex) 카드의 무늬, 숫자
    • c1.width = 50;
      • 클래스 변수를 변경하면 인스턴스가 하나의 저장공간을 공유하여 모두 변경된 값을 지닌다.
    class Card {
        String kind;
        int number;
        // 클래스 변수: 모든 객체가 동일한 경우 사용
        static int width = 100;
        static int height = 200;
    }
    
    public class CardTest {
        public static void main(String[] args) {
            System.out.println(Card.width + " " + Card.height); // 100 200 
    
            Card c1 = new Card();
            c1.kind = "Heart";
            c1.number = 7;
    
            Card c2 = new Card();
            c1.kind = "Space";
            c1.number = 4;
    
            c1.width = 50;
            System.out.println(c1.width);  // 50 
            System.out.println(c2.width);  // 50
            System.out.println(Card.width);// 50
        }
        }
    
    • 메모리 구조로 그려보기!
      • jvm 메모리 구조 개념은 아래 3.7에서 자세히 나온다.
      • 여기서 중요하게 파악할 부분은 클래스 변수는 공유된다는 점이다.

    3.3 메서드

    메서드는 크게 선언부와 구현부로 이루어져 있다.

     

    선언부

    • 메서드 이름
    • 반환 타입
      • 반환 값을 적어준다.
      • 반환값이 없는 경우 ‘void’ 적어야 한다.

    구현부

    • return문
      • void가 아닌 경우 return 반환값이 반시드 존재
      • 반환타입과 일치하거나 자동 형변환이 가능한 것만 가능

     

     

    3.7 JVM 메모리 구조

    응용프로그램이 실행되면 JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고, JVM은 이 메모리를 용도에 따라 여러 영역으로 나눠 관리한다. 그중 주요 영역인 메서드, 스택, 힙 영역에 대해 알아보자. 주요 영역은 스택을 제외한 나머지 영역은 스레드 간 공유를 한다.

    Runtime Data Area
    JVM 메모리 구조

     

    1) 메서드 영역

    • 클래스파일(*. class)을 읽어 분석하여 이곳에 저장한다. 이곳에는 클래스, 인터페이스 static 영역 등을 저장한다.
    • 스레드 간 공유

    2) 스택 영역

    • 메서드의 작업에 필요한 메모리 공간을 제공한다.
    • 메서드가 호출되면 호출스택에 호출된 메서드를 위한 메모리가 할당된다.
    • 메서드가 완료되면 할당된 메모리공간은 반환되어 비워진다.
    • 쓰레드간 해당 공간을 공유하지 않는다.
    • 지역 변수, 리턴값 등 임시 값 생성

    3) 힙 영역

    • 인스턴스가 생성되는 공간
    • 쓰레드간 공유
    • new 키워드로 생성되는 객체, 배열로 gc가 주기적으로 제거하는 영역

     

    3.8 기본형 매개변수와 참조형 매개변수

     기본형 매개변수: 변수의 값을 읽기만 가능 (read) → 값 전달
    참조형 매개변수: 변수의 값을 읽고 변경 가능 (read & write) → 주소를 전달

    아래는 기본형, 참조형 매개변수 예제이다.

    class Data {int x;}
    
    public class PrimitiveEx {
        static void primitiveChange(int x){
            x = 100;
            System.out.println("primitiveChange x:" + x);  // primitiveChange x:100
        }
        static void ReferChange(Data d){
            d.x = 1000;
            System.out.println("ReferChange x: " + d.x);  // ReferChange x: 1000
        }
        public static void main(String[] args) {
            Data d = new Data();
            d.x = 10;
            System.out.println("main x:" + d.x);   // main x:10 
            // 1. 기본형 매개변수: 변경 안됨  
            primitiveChange(d.x);
            System.out.println("main x:" + d.x);   // main x:10
            // 2. 참조형 매개변수: 변경됨 
            ReferChange(d);
            System.out.println("main x:" + d.x);   // main x:1000
        }
    }
    

    1) 기본형 매개변수 과정

    1. ReferChange 메서드 호출되면서, d.x가 ReferChange 메서드의 매개변수 x로 복사됨
      • 값 자체를 copy

    2. ReferChange 메서드에서 x 값을 1000 변경

    • 지역 변수 값 1000 변경

    3. ReferChange 메서드가 종료되면서 매개변수 x는 스택에서 제거 

     

    2) 참조형 매개변수 과정

    1. ReferChange 메서드가 호출되면서 참조변수 d의 값(주소)이 매개변수 d에 복사됨
      • 주소값을 복사

    2. ReferChange 메서드에서 매개변수 d로 x 값 1000 변경

    3. ReferChange 메서드 종료되면서 매개변수 d는 스택에서 제거됨

     

     

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

    ⭐  클래스 메서드(static 메서드): 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메서드 사용하지 않는) 메서드를 정의
    ⭐  인스턴스 메서드: 인스턴스 변수와 관련된 작업을 하는. 즉, 메서드 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드
           ⇒ 인스턴스 변수(iv)를 사용하는지 여부에 따라 구분됨

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

      클래스 메서드(static 메서드) 인스턴스 메서드
    정의 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메서드 사용하지 않는) 메서드를 정의
    ex) Math.random()
    인스턴스 변수와 관련된 작업을 하는. 즉, 메서드 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드
    언제 사용 - 인스턴스 변수(iv) & 인스턴스 메소드를 사용하지 않는 경우 인스턴스 변수를 사용하는 경우
    특징 - 인스턴스 변수 사용 불가
    - 인스턴스 메소드 사용 불가
     
    호출 방식  클래스이름.메서드이름() 참조변수.메서드이름()

     

    두 클래스 사용 방법은 아래 예시와 같다.

    class MyMath2 {
        long a, b;
    
        // 인스턴스 메소드 - 인스턴스 변수를 사용 
        long add(){return a + b;}
        long subtract(){return a - b;}
        long multiply(){return a * b;}
        long divide(){return a / b;}
    
        // 클래스 메소드(static 메서드) - 인스턴스 변수를 사용 안함! 
        static long add(long a, long b){return a + b;}
        static long subtract(long a, long b){return a - b;}
        static long multiply(long a, long b){return a * b;}
        static long divide(long a, long b){return a / b;}
    }
    
    public class MyMathTest2 {
        public static void main(String[] args) {
            // 1. 클래스 메소드 호출 - 객체 생성 필요 없음
            System.out.println(MyMath2.add(200L, 100L));
            System.out.println(MyMath2.subtract(200L, 100L));
            System.out.println(MyMath2.multiply(200L, 100L));
            System.out.println(MyMath2.divide(200L, 100L));
    
            // 2. 인스턴스 메소드 호출 - 객체 생성 필요
            MyMath2 mm = new MyMath2();
            mm.a = 200L;
            mm.b = 100L;
            System.out.println(mm.add());
            System.out.println(mm.subtract());
            System.out.println(mm.multiply());
            System.out.println(mm.divide());
    
        }
    }
    

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

    아래 예시와 같이 클래스 메서드는 인스턴스 메소드 or 변수를 호출할 수 없다.

    • 이유? 클래스 메서드가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수 있다.
      • 객체를 생성하지 않으면 인스턴스 멤버는 없다.
    class Test {
        int iv;
        static int cv;
    
        // 인스턴스 메소드
        void instanceMethod2(){
        }
        void instanceMethod(){
            
        }
    
        // 클래스 메소드
        static void classMethod2(){
        }
        static void classMethod(){
            classMethod2();
            instanceMethod2();     // 인스턴스 메소드 호출 불가 
            System.out.println(cv);
            System.out.println(iv); // 인스턴스 변수 호출 불가 
            
        }
    }
    

     

     

    다음 시간에는 자바의 정석 6장 객체지향 언어 1 - 오버로딩, 생성자, 변수의 초기화에 대해서 알아 보겠습니다. 😀

    댓글

Designed by Tistory.