[JAVA] 04. 클래스, 객체

gogori6565·2022년 9월 29일
0

JAVA

목록 보기
8/11

클래스, 객체, 인스턴스?

  • 객체(Object) : 소프트웨어 세계에 구현할 대상, 속성과 기능을 가지는 프로그램 단위, ‘클래스의 인스턴스’라고 도 함
  • 클래스(Class) : 객체를 찍어내기 위한 틀, 설계도
  • 인스턴스(instance) : 클래스를 바탕으로 실체화되어 메모리에 할당된 실체

객체 vs 인스턴스 차이
→ 클래스의 타입으로 선언되었을 때 객체라 부르고, 그 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부름

클래스 (class)

클래스

  • class 키워드로 선언

필드와 메소드

  • 필드(field) : 객체 내 멤버 변수
  • 메소드(method) : 함수, 객체의 행동을 구현

접근지정자

1) public : 어디서든 접근 허용
2) protected : 상속관계에 놓여있을 때, 유도 클래스에서의 접근 허용
3) private : 클래스 내 (클래스 내에 정의된 함수) 에서만 접근 허용
4) 디폴트 : 접근지정자 생략

생성자

  • 클래스의 이름과 동일한 특별 메소드
  • 각 객체가 생성될 때 자동으로 한 번 호출됨

객체 생성

new 키워드로 생성

객체 멤버 접근

레퍼런스.멤버

//Circle 클래스 이름

//객체 생성 - new 사용
Circle pizza;
pizza = new Circle();

//객체 멤버 접근 - (.)연산자
pizza.radius=10;
pizza.name="피자";

생성자

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

  • 각 객체마다 객체 생성 시 자동으로 한 번 호출된다
  • 클래스 이름과 반드시 동일해야한다
  • 리턴타입을 지정할 수 X
  • 개발자가 생성자를 작성하지 않았다면 컴파일러가 자동으로 기본 생성자를 삽입해 호출한다

default constructor (기본 생성자)

형태 = ClassName() { } - 파라미터 및 중괄호 내부 없음

매개변수가 없고 아무 작업 없이 리턴하는 생성자(String은 null, int는 0...), 클래스에 생성자가 하나도 선언되지 않았을 경우 컴파일러에 의해 자동 삽입됨
(하나라도 선언 되었다면 자동 삽입 X)


레퍼런스

자바 타입의 큰 범주, 즉 카테고리

자바에서 변수형은 두가지로 나뉜다

1) 레퍼런스형(reference type) : 값을 변수에 대입하지만 변수는 참조값(메모리상)을 가지고 있지 값을 직접 들고 있지는 않는 형태
-> String, 클래스, 인터페이스, 배열, 열거형 ...

2) 기본형(primitives type) : 값을 변수에 대입하여 사용하는 형태
-> int, double, boolean, char ...

Student std = new Student("홍길동", 18);
  • 이 경우 Student 는 '레퍼런스 타입(클래스 타입)' / std는 '레퍼런스 변수' 라고 부름
  • 레퍼런스형은 대문자로 시작함 (String, Student ...) / 기본형은 소문자로 시작함 (int, double ...)

this 레퍼런스

객체 자신에 대한 레퍼런스, this.멤버

[주로 쓰이는 경우]
1. 객체의 멤버 변수와 메소드 변수 혹은 메소드의 매개변수와 이름이 같을 때
2. 다른 메소드 호출 시 객체 자신의 레퍼런스를 전달할 때
3. 메소드가 객체 자신의 레퍼런스를 반환할 때

//문제
Cook c = new Cook("케이크", 15000);

class Cook {
  private String name;
  private int price;
  
  public Cook(String name, int price) {
    name = name; // 인스턴스 변수 name 초기화(X) -> 파라미터 자기 자신한테 대입하는 것으로 인식
    price = price; // 인스턴스 변수 price 초기화(X) -> 파라미터 자기 자신한테 대입하는 것으로 인식
  }
}

매개변수로 들어온 name과 price 자기 자신에게 대입하는 것으로 수행되기 때문에 클래스 내 인스턴스 변수가 초기화되지 않음. 따라서 이 경우 this 레퍼런스를 사용!

//해결
Cook c = new Cook("케이크", 15000);

class Cook {
  private String name;
  private int price;
  
  public Cook(String name, int price) {
    this.name = name; // 인스턴스 변수 name 초기화(O)
    this.price = price; // 인스턴스 변수 price 초기화(O)
  }
}

this() 다른 생성자 호출

  • 클래스 내의 다른 생성자 호출
  • 생성자 내에서만 사용 가능
  • 반드시 생성자 코드의 제일 처음에 수행
public Book(String title){
	this(title, "작자미상");
}

public Book(String title, String author){
	this.title = title;
    this.author = author;
}

//main 내 코드 중
Book loveStory = new Book("춘향전");
//1번 생성자로 갔다가 2번 생성자로 옮겨져 "춘향전 작자미상" 이 된다.

메소드 (method)

  • 자바의 모든 메소드는 반드시 클래스 안에 있어야 함 (캡슐화 원칙)

인자 전달 방식

  1. 기본 타입의 값 전달
  • 값이 복사되어 전달
  • 메소드의 매개변수가 변경되어도 호출한 실인자 값은 변경되지 않음 ('값에 의한 호출' 이기 때문)
  1. 객체 혹은 배열 전달]
  • 객체나 배열의 레퍼런스만 전달, 즉 통째로 복사되는 것이 아님
  • 실인자 객체나 배열 공유 (참조에 의한 호출)

메소드 오버로딩 (Overloading)

이름이 같은 메소드를 작성할 수 있다

  • 단, 매개변수의 개수나 타입이 서로 달라야함 (리턴 타입은 상관 X)

객체 소멸

new 에 의해 할당된 객체 메모리를 가용 메모리로 되돌려주는 행위

  • 자바에서는 임의로 객체를 소멸할 수 없음! (개발자 : "오히려좋아")

가비지 컬렉션

가비지 : 가리키는 레퍼런스가 하나도 없는 객체 (사용할 수 없게 된 메모리)

가비지 컬렉션 : 자바 가상 기계의 '가비지 컬렉터'가 자동으로 가비지 수집 반환

  • 개발자에 의해 강제로 가비지 컬렉션을 호출할 수 있다. System.gc()

접근 지정자

1) private : 동일 클래스 내에서만 접근 허용
2) protected : 같은 패키지 내 모든 클래스에서 접근 허용 및 상속 받은 서브 클래스는 다른 패키지에 있어도 접근 가능
3) public : 다른 모든 클래스에서 접근 허용
4) default (접근지정자 생략) : package-private라고도 함. 같은 패키지의 클래스에만 접근 허용

getter(), setter()

private으로 선언된 필드는 어떻게 접근하는가?

  • getter() : private 필드를 반환(get)
  • setter() : private 필드를 변경(set)

1. 게터(getter) : private 필드를 우회적으로 접근(read)하게 함

  • private 필드를 반환한다 -> return balance
  • 접근지정자는 public -> public int getBalance()
  • 메소드명은 get + 필드명 으로 한다 -> getBalance()
class Bank {
	private int balance;
    
    public int getBalance() {
    	return balance;
    }
}

2. 세터(setter) : private 필드를 우회적으로 변경(write)함

  • private 필드를 변경한다
  • 접근지정자는 public
  • 메소드명은 set + 필드명 으로 한다
class Bank {
	private int balance;
    
    public void setBalance(int price) {
    	balance = price;
    }
}

static

non-static 의 특성

한 마디로 공유 안함.

1) 공간적 특성 : 멤버들은 객체마다 독립적으로 별도 존재 ('인스턴스 멤버' 라고 부름)
2) 시간적 특성 : 필드와 메소드는 객체 생성 후 사용 가능
3) 비공유 특성 : 멤버들은 다른 객체에 의해 공유되지 않고 배타적

static

'공유'의 개념이 담긴 키워드 (클래스의 모든 객체들에서 공유됨)

객체마다 생기는 것이 아니라 클래스 당 하나만 생성됨, 클래스 멤버라고도 부름
객체를 생성하지 않고도 사용 가능

한 마디로 공유함.

[특성]
1) 공간적 특성 : static 멤버들은 클래스 당 하나만 생성 ('클래스 멤버' 라고 부름)
2) 시간적 특성 : static 멤버들은 클래스가 로딩될 때 공간 할당
3) 공유의 특성 : static 멤버들은 동일한 클래스의 모든 객체에 의해 공유

class StaticSample {
//non-static
int n; // non-static 필드
void g() {...} // non-static 메소드

//static
static int m; // static 필드
static void f() {...} // static 메소드
}

static 멤버 접근

  1. 객체의 멤버로 접근
Circle c1;
c1.m; //static m
  1. 클래스의 멤버로 접근 - 객체 없어도 수행 가능
Circle.m; //static m

static의 활용

  1. 전역 변수와 전역 함수를 만들 때 활용
  • static 멤버를 가진 클래스 사례
    • Math 클래스 : java.lang.Math
      1) 모든 필드와 메소드가 public static으로 선언
      2) 다른 모든 클래스에서 사용할 수 있음
  1. 공유 멤버를 작성할 때
  • static 필드나 메소드는 하나만 생성. 클래스의 객체들 공유

static 메소드의 제약 조건

  1. static 메소드는 non-static 멤버 접근할 수 없음
  • 객체가 생성되지 않은 상황에서도 static 메소드는 실행 가능하기에 static 메소드에서 non-static 메소드와 필드 사용 불가
  • 반대로, non-static 메소드에서 static 사용은 가능
  1. static 메소드는 this 사용불가!
  • static 메소드는 객체가 생성되지 않은 상황에서도 호출이 가능하므로, 현재 객체를 가리키는 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() { ... } // 컴파일 오류, 오버라이딩 할 수 없음
}

+) 오버라이딩이란?
오버로딩(overloading)이란 서로 다른 시그니처를 갖는 여러 메소드를 하나의 이름으로 정의하는 것이었습니다.

오버라이딩(overriding)이란 상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니쳐를 갖는 메소드로 다시 정의하는 것이라고 할 수 있습니다.

final 필드

final 필드, 상수 선언

  • 상수를 선언할 때 사용
class SharedClass{
	public static final double PI = 3.14;
}
  • 상수 필드는 선언 시 초기값 지정해야함
  • 상수 필드는 실행 중 값 변경 불가
profile
p(´∇`)q

0개의 댓글