[Java] 4. 객체 지향 문법

seungwon·2021년 6월 15일
0

Java

목록 보기
4/5

목차

  • 객체 지향 언어의 특징
  • Class, Instance (클래스, 객체)
  • 절차 지향 프로그래밍 vs 객체 지향 프로그래밍
  • 객체 생성 및 접근
  • 생성자(constructor)
  • this 레퍼런스
  • 가비지 컬렉션
  • 메소드
  • 메소드 오버로딩
  • 접근 지정자
  • 참고자료 (사진 출처)
  • Static

객체 지향 언어의 특징

  1. Abstraction(추상화) : 실세계 -> 모델링
    프로그램에 필한 변수, 함수만 뽑아내기 (이름을 잘 지어야 함)
  1. Encapsulation(캡슐화) : 객체를 캡슐(Class)로 싸서 내부를 볼 수 없게 하는 것
    = 외부의 접근으로부터 객체 보호
    Class 배치를 잘해야 함

  2. Inheritance(상속) : 하위 객체가 상위 객체의 속성을 모두 가진다 = 물려받는다 , 기능 확장

  3. Polymorphism(다형성) : 같은 이름의 메소드가 클래스나 객체에 따라 다르게 동작하도록
    (메소드 오버로딩, 메소드 오버라이딩)

실세계 객체의 특징

  • 객체마다 고유한 특성(state) -> 변수 와 행동(behavior) -> 함수 를 가짐
  • 다른 객체들과 상호작용하면서 존재

Class, Instance (클래스, 객체)

  • 클래스(class) : 객체 모양을 선언한 "틀"
    method(객체의 행동), field(객체의 속성 = property)는 모두 클래스 내에 구현
    • class의 구성
    • field : heap 에 생성됨
    • method : 코드 영역에 생성됨
  • 객체(instance) : 클래스 모양대로 생성된 실체
    프로그램 실행 중에 생성된다
    메모리 공간을 갖는 구체적인 실체
    객체 내 데이터에 대한 보호, 외부 접근 제한

절차 지향 프로그래밍 vs 객체 지향 프로그래밍

절차 지향 프로그래밍객체 지향 프로그래밍
작업 순서로 표현,
함수들의 집합
객체들간의 상호 작용으로 표현,
클래스/객체들의 집합


객체 생성 및 접근

  • 객체 생성 : new 키워드 -> 객체의 생성자 호출

  • 객체 생성 과정

  1. 객체에 대한 레퍼런스 변수 선언
  2. 객체 생성 : 클래스 타입 크기의 메모리 할당 -> 객체 내 생성자 코드 실행
  • 객체의 멤버 접근 : 객체 레퍼런스. 멤버
Circle pizza; // (1) 레퍼런스 변수 선언

pizza = new Circle(); // (2) 객체 생성 - new 연산자 이용

// 객체 멤버 접근
pizza.radius.10;
pizza.name = "supreme pizza"
double area = pizza.getArea();

실행시에 코드는 다른곳에 존재, class를 만들때 그 코드로 돌아가서 이 class를 메모리에 로드함

생성자(constructor)

객체가 생성될 때 초기화를 위해 실행되는 메소드

  • 생성자 이름은 클래스 이름과 반드시 동일
  • 생성자 여러 개 작성 가능 (오버로딩)
  • 생성자는 new를 통해 객체를 생성할 때, 객체당 한 번 호출
  • 생성자는 리턴 타입을 지정할 수 없음
  • 생성자의 목적은 객체 초기화
  • 생성자는 객체가 생성될 때 반드시 호출됨.
  • 개발자가 생성자를 작성하지 않았으면 컴파일러가 자동으로 기본 생성자 삽입

생성자 오버로딩

클라이언트 입장에서 여러개 골라서 사용할 수 있음

this 레퍼런스

객체 자신에 대한 레퍼런스
-> 클래스의 멤버에 대해 사용

  • 객체의 멤버 변수와 메소드 변수의 이름이 같은 경우
  • 다른 메소드 호출 시 객체 자신의 레퍼런스를 전달할 때
  • 메소드가 객체 자신의 레퍼런스를 반환할 때
public class Circle { 
	int radius;
    
	public Circle() {
		this.radius = 1;
	} 
	public Circle(int radius) {
		this.radius = radius; //this! 
	}
	double getArea() {
		return 3.14*this.radius*this.radius; 
	}
	... 
}

this()로 다른 생성자 호출

  • 클래스 내의 다른 생성자 호출
  • 생성자 내에서만 사용 가능
  • 반드시 생성자 제일 첫문장에 와야함
    ∵ 생성자 호출이 끝나야 heap메모리에 로드됨 -> 메모리 로드 후에 할당을 해야함

public class Book {
 	String title;
	String author;
    
    void show() { 
    	System.out.println(title + " " + author); 
    }
	
    public Book() {  
    	this("", ""); // this.title =""; this.author=""; (X:이렇게쓰지않음)
        System.out.println("생성자 호출됨");   
    }
	
    public Book(String title) {
    	this(title, "작자미상"); // BOOK(title,"작자미상"); (X:불가능)
    }	
   
    public Book(String title, String author) {
    	this.title = title; this.author = author;  
    }
    
    public static void main(String [] args) {
    	Book littlePrince = new Book("어린왕자", "생텍쥐페리"); 
        Book loveStory = new Book("춘향전");
        Book emptyBook = new Book();
        loveStory.show();
    }
}

가비지 컬렉션

  • JVM의 가비지 컬렉터가 자동으로 가비지를 회수하는 과정(런타임에 이루어짐)
    실시간으로 바로바로는 아니고 일정 시점에 회수함 (∵ JVM의 가장 중요한 역할은 자바 프로그램을 돌리는 것이므로 가비지 생길때마다 회수하면 속도가 느려짐)

    JVM이 가비지 컬렉션 시점을 전적으로 판단

가비지 컬렉션 작동 요청

System.gc()
바로 작동함을 의미하지는 않음

객체 소멸

new에 의해 할당된 객체 메모리 -> JVM의 가용메모리로 되돌려 주는 행위
∴ 자바 응용프로그램에서 임의로 객체를 소멸할 수 없음 -> 장점이자 단점
(Heap이 부족할 때 임의로 해제하고 싶어도 불가능)

가비지

  • 레퍼런스가 하나도 없는 객체 (누구도 사용할 수 없게 된 메모리)
    객체 생성시 ref.count로 몇개의 레퍼런스가 그 객체를 가리키고 있는지 관리한다 -> ref.count = 0이 되면 그 객체는 가비지가 되는 것.

∴ 사용하지 않는 객체에 대해 바로바로 레퍼런스를 끊어줘야 함
객체의 어느 변수가 다른 객체를 가리킬 때 필요없어지면 NULL을 넣어줘야 함

메소드

접근 지정자 + 리턴 타입 + 메소드 이름 + 메소드 인자들 + 메소드 코드

인자 전달 방식

  1. 기본 타입의 값 전달 : Call by Value
    • 값이 복사되어 전달 (지역변수는 Stack에 저장됨)
    • 메소드의 매개변수가 변경되어도 호출한 실인자 값은 변경되지 않음
  2. 객체 혹은 배열 전달 : Call by Reference
    • 객체나 배열의 레퍼런스만 전달 : 객체 혹은 배열이 통째로 복사되어 전달되는 것이 아님
    • 메소드의 매개변수와 호출한 실인자 객체나 배열 공유

메소드 오버로딩

이름이 같은 메소드 작성

  • 매개변수의 개수나 타입이 서로 다르고
  • 이름이 동일한 메소드들
  • 리턴 타입은 오버로딩과 관련 없음

접근 지정자

협업시 파악할 코드를 판단하는 기준이 됨

private, protected, public, 디폴트(접근지정자 생략)

  • default : package-private 라고도 함
  • field : 대부분 private 사용 (상수만 public 사용)
  • method : 서비스(공개)할 method먼저 public, 파생된 method는 private

접근 지정자의 목적

  • 클래스나 일부 멤버를 공개하여 다른 클래스에서 접근하도록 허용
  • 객체 지향 언어의 캡슐화 정책은 멤버를 보호하는 것 - 접근 지정은 캡슐화에 묶인 보호를 일부 해제할 목적 (유효성 체크도 가능함)
Calender cal;
cal.month = 13; 
//setter 함수내에서 이런 것들에 대한 유효성 체크가 가능함

사용

  • member(field,method) 앞 : 접근지정자 4개 모두 가능
  • class : public , default만 가능

패키지

관련 있는 클래스 파일(컴파일된 .class)을 저장하는 디렉터리

자바 응용프로그램은 하나 이상의 패키지로 구성

Static

static 멤버 vs non-static 멤버

  • static 멤버
    클래스 당 하나만 생성(클래스 멤버라고도 부름)
    클래스가 로딩될 때 공간 할당

    클래스가 로딩된다 = 코드를 코드영역에 올림
    -> static 멤버만 생김(static 영역-별도의 영역-에 생김)

    동일한 클래스의 모든 객체에 의해 공유
    객체 생성 이전에 클래스 명으로 접근 가능
  • non-static 멤버
    객체 생성시에 멤버 생성됨
    멤버들은 객체마다 독립적으로 별도 존재(인스턴스 멤버)
    필드,메소드는 객체 생성 후 사용 가능
    멤버들은 다른 객체에 의해 공유되지 않고 배타적

static의 활용

  • 전역 변수 / 전역 함수 기능 만들 때
  • java 에서 전역 변수 / 함수 라는 말을 사용하지 않음
  • 공유 멤버를 작성할 때

static 메소드

  • non-static 멤버에 접근할 수 없음 (<-> non-static 메소드는 static 멤버 사용 가능)
    ∵ 객체가 생성되지 않아도 static 메소드는 실행될 수 있음

  • this 사용 불가능
    ∵ this 레퍼런스 : 현재 객체를 가리키는 것

final

final 클래스 : 상속 불가

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

final 메소드 : 오버라이딩 불가

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

final 필드 : 상수 선언

  • 상수 필드는 선언 시에 초기 값을 지정하여야 한다
  • 실행 중에 값을 변경할 수 없다
class SharedClass {
	public static final double PI = 3.14; 
}

public class FinalFieldClass {
	final int ROWS = 10; // 상수 정의, 이때 초기 값(10)을 반드시 설정
    
    	void f() {
    		int [] intArray = new int [ROWS]; // 상수 활용
        	ROWS = 30; // 컴파일 오류 발생, final 필드 값을 변경할 수 없다. 
    	}
}

참고 자료 (사진 출처)

명품 Java Programming(황기태, 김효수 저)

0개의 댓글