ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 🎮 [JAVA 자바] #7 | 자바 클래스와 객체, 객체지향 프로그래밍, static, final, 메모리, 생성자
    CS/Java 2022. 4. 17. 05:20

     


    🎮 객체지향 프로그래밍

     - 객체지향 프로그래밍 (Object-Oriented Programming) 

    컴퓨터가 수행하는 작업을 객체들간의 상호작용으로 표현. 객체들의 집합으로 프로그램 작성

    실세계의 개체를 속성과 메서드가 결합한 형태의 객체로 추상화하는 것이 객체 지향 설계(이 시스템이 어떤 구성요소로 이루어져 있는지 파악하기). 객체 모듈화를 통해 생산성 향상

     

    프로그램 = 클래스들의 집합

    프로그램 실행 = 서로 협력하는 객체들의 집합

     

    * 절차 지향 프로그래밍 : 작업 순서를 표현하는 컴퓨터 명령 집합, 함수들의 집합으로 프로그램 작성

    * UML (Unified Modeling Language) : 시스템 설계를 그림으로 표현. 개발자 사이 의사소통을 위한 도구

     

    UML Class 다이어그램 예시

     

     - OOP 특징 

    추상화(abstraction) : 중요하고 필수적인 것 추출 (쓸데없는거 X)

    캡슐화(encapsulation) : 데이터와 기능을 하나로 묶어 내부 데이터 구조, 구현, 방법을 분리 (모듈 단위로 쪼갬)

    일반화(generalization) : 여러 개체들이 가진 공통된 특성을 추출

    다형성(polymorphism) : 클래스 혹은 객체에서 다르게 동작하도록 분리

     

     - OOP 장단점 

    1. 자연적인 모델링

    2. 높은 재사용성

    3. 요구사항에 유연, 유지보수 용이

    -> 복잡한 SW 생산성 향상, (단점 : 효율성은 감소할수도)

     

     - 디자인 패턴 

    객체지향 프로그래밍 중 반복적으로 발생하는 문제들

    문제 해결을 위한 객체지향 설계 노하우를 몇 가지 패턴으로 정리 -> 템플릿, 유형화

    (책 : Head First Design Patterns, GoF의 디자인패턴)


    🎮 클래스와 객체

     - 클래스 

    객체 모양을 정의한 , 객체를 생성하기 위한 목적

     

     - 객체 (object) 

    클래스의 모양대로 생성된 실체(Instance)

    프로그램 실행에 필요한 실세계 개체의 기능을 반영하기 위한 목적

     

    * 객체 생성 : 인스턴스화

    new 연산자는 클래스로부터 객체를 생성한다. ClassName obj = new ClassName();

    객체 참조 변수는 지역변수로 stack에 저장, 멤버변수와 멤버함수들은 독립적 메모리 공간 Heap에 저장됨.

    Circle myCircle = new Circle(); // myCircle은 객체 참조 변수, Circle()은 생성자

     

     - 클래스 구성 

    클래스 선언과 정의 모두 '클래스명.java'에 작성 (클래스의 멤버변수와 멤버 메소드 선언)

     

    멤버변수 : 필드 또는 속성

    생성자 : 기본생성자(default constructor)는 매개변수 없고 아무 작업 없이 단순 리턴하는 생성자

    멤버함수 : 메소드 또는 오퍼레이션

    // Circle.java
    public class Circle { // 접근 지정자 + 클래스 + 클래스 이름
        public int radius; // 필드 (멤버변수)
        public String name; 
        
        public Circle() { // 생성자 메소드
        }
        
        public double getArea() { // 메소드 (멤버함수)
            return 3.14*radius*radius;
        }
    }

    🎮 변수의 종류 

     - 지역변수

    메소드 영역 안에서 선언한 변수 및 매개 변수로, 메모리 위치는 스택 영역. 선언된 블록이 실행되는 동안만 존재. 블록 내부에서만 사용됨.

     

    * 우선순위 : 지역 변수 > 인스턴스 변수

     

     - 인스턴스 변수

    non-static 멤버. 객체마다 독립적으로 존재. new로 생성되므로 Heap영역. 객체 생성 후에 사용 가능(런타임). 다른 객체에 공유되지 않고 배타적. (ex. 클래스 파일 내에 static 안 붙은 멤버변수)

     

     - 클래스 변수 (static) 

    static 멤버. 객체마다 생성되지 않고 클래스 당 하나만 생성. Method영역. 클래스가 로딩될 때 공간할당(객체를 생성하지 않고도 사용). 해당 클래스의 모든 객체에 의해 공유

     

      인스턴스 변수 클래스 변수
    유형 non-static 멤버 static 멤버
    공간적 특성 객체마다 독립적으로 존재.
    Heap영역
    객체마다 생성되지 않고 클래스 당 하나만 생성.
    Method영역
    시간적 특성 객체 생성 후에 사용 가능
    (런타임)
     클래스가 로딩될 때 공간할당
    (
    객체를 생성하지 않고도 사용)
    공유의 특성 다른 객체에 공유되지 않고 배타적 해당 클래스의 모든 객체에 의해 공유

     

    class StaticExample {
        int n; // 인스턴스 변수
        void g() {...} // 인스턴스 메소드
        
        static int m; // 클래스 변수
        static void f() {...} // 클래스 메소드
    }

    🎮 static과 final 키워드

     - static 멤버 공유 

    해당 클래스의 모든 객체에 의해 공유

    객체 2개 생성했을 때, 객체 하나의 멤버변수의 값을 바꾸면 다른 객체의 멤버변수의 값도 바뀜. (공유되어서)

     

     - static의 활용 

    1) 전역 필드/메소드의 역할 : 다른 모든 클래스에서 사용할 수 있음. 객체 매번 생성할 필요 X

    2) 공유 멤버 작성할 때 : 하나만 생성되어 클래스의 객체들이 공유

     

     - static 메소드 제약조건 

    객체가 생성되지 않은 상황에서도 static 메소드가 실행될 수 있기 때문에,

    1) static 메소드에서는 static 변수 또는 static 메소드만 접근 가능

    2) 현재 객체 가리키는 this 사용 불가

    반대로, non-static 메소드는 static 멤버 사용 가능

     

     - final 필드 

    상수 선언. 선언 시 초기값 반드시 지정. 값 변경 불가능

    final double PI = 3.14;
    public static final int ROWS = 10;

     

     - final 클래스 

    클래스 상속 불가

    final class FinalClass { ... }
    class subClass extends FinalClass { ... } // 컴파일 오류. FinalClass 상속 불가

     

     - final 메소드 

    오버라이딩 불가

    public class SuperClass {
        protected final int finalMethod() {...}
    }
    class subClass extends SuperClass {
        protected int fianlMethod() {...} //컴파일 오류, 오버라이딩 불가능
    }

    🎮 메모리

     - JVM 내부 구조 

    클래스 파일 => 클래스 로더(모듈) <=> 클래스 라이브러리

    클래스 로더 <=> 실행시간 데이터 영역(런타임 data area) <=> 실행 엔진 <=> Native 메소드 인터페이스 <=> ...

    실행시간 데이터 영역 :

       - 메소드 영역(클래스 변수)

       - 스택 영역(매개변수, 지역변수)  

       - 힙 영역 : 인스턴스변수(new)

       - (+ Native 메소드 스택)

     

     - 기본 타입 변수 메모리 할당 

    1) 로딩 시점에 메소드 영역전역변수와 메소드의 바이트 코드가 입력됨  2) PC가 수행할 명령어 가리킴  3) 스택 영역에 스택 프레임이 생기고 지역변수가 입력되고, 끝나면 스택에서 사라짐

     

     - 객체 생성과 메모리 할당 

    1) 로딩시점에 메소드 영역클래스의 메소드의 바이트 코드가 입력됨  2) PC가 수행할 명령어 가리킴  3) 스택 영역에 스택 프레임이 생기고 args와 지역변수가 입력됨  4) 스택의 args는 힙 영역의 args[1], args[0] ...을 가리킨다. 또 그것들은 각각 인자 값을 가리킴  5) 객체 레퍼런스 변수는 스택 영역에 입력됨  6) 객체 레퍼런스 변수는 힙 영역의 데이터를 가리킴


    🎮 생성자

     - 생성자 

    객체가 생성될 때 초기화를 위해 실행되는 메소드. 생성자가 없는 클래스는 없음

    클래스와 이름이 같고, 반환값과 반환 타입이 없고, 객체를 생성할 때 한 번만 호출되며, 여러 개 작성 가능(오버로딩)

     

     - 기본 생성자 (default constructor) 

    클래스에 생성자가 하나도 선언되지 않은 경우, 컴파일러에 의해 자동으로 삽입됨.

    개발자가 클래스에 생성자 하나라도 작성한 경우 자동 삽입 X -> 객체 생성 시 해당하는 기본생성자 안만들어줘서 컴파일 오류 안나게 주의

     

     - 커스텀 생성자 (Custom constructor) 

    사용자에 의해 정의된 생성자


    🎮 오버로딩

     - 생성자 오버로딩 

    매개변수의 개수 또는 타입이 다른 생성자들 다수 작성

     

     - 메소드 오버로딩 

    매개 변수의 개수 또는 타입이 서로 다르고 동명 메소드 작성 -> 모두 같으면 메소드 오버로딩 실패

    리턴 타입은 무관

     

    // 생성자 오버로딩
    public Circle() {
        radius = 1;
    }
    public Circle(int r) {
        radius = r;
    }
    
    // 메소드 오버로딩
    public int getSum(int i, int j) {
        return i+j;
    }
    public int getSum(int i, int j, int k) {
        return i+j+k;
    }
    /* 
    매개변수의 개수, 타입 모두 같고 리턴타입 무관이라서 메소드 오버로딩 실패
    public double getSum(int i, int j) {
        return i+j;
    }
    */

    🎮 this 레퍼런스

     - this 

    객체 자신에 대한 레퍼런스로, 1) 이름 충돌을 해결하거나 2) 객체 자신의 레퍼런스를 전달할 때 사용

     

     - this()  

    클래스 내의 다른 생성자 호출

    생성자 메소드 내에서만 사용가능

    제일 첫번째 문장에서만 호출가능

     

    public Book() {
        this("",""); // 다른 생성자 호출
    } 
    
    public Book(String title) {
        this(title, "작자미상"); // 다른 생성자 호출
    }
    
    public Book(String title, String author) {
        this.title = title; // this 안쓰면 오류. 이름 충돌 해결
        this.author = author;
    }