[자바 문법 #4] 클래스 (Class)

김지현·2023년 10월 29일
0

JAVA

목록 보기
4/14

1. 객체지향 프로그래밍

객체 : 세상에 존재하는 물체, 식별이 가능한 것, 속성과 행위로 구성
객체지향 : 소프트웨어를 하나씩 조립해서 하나의 완성된 프로그램을 구성
객체끼리의 상호작용 : 메서드를 통해 이루어짐

객체 간의 관계

  • 사용 관계 : ex) 사람 객체가 자동차 객체를 사용
  • 포함 관계 : ex) 타이어, 차문, 핸들 객체가 자동차 객체에 포함되어 있음
  • 상속 관계 : ex) 자동차와 기차 객체가 공통된 기계시스템 객체를 토대로 만들어져 상속 받음

객체와 클래스

  • 객체를 생성하기 위해서는 설계도에 해당하는 클래스가 필요
  • 클래스를 토대로 생성된 객체를 '인스턴스'라고 하고, 이 과정을 '인스턴스화'라고 함
  • 동일한 클래스로 여러 개의 인스턴스 생성 가능

객체 지향 프로그래밍의 특징

  1. 캡슐화
  • 속성(필드)와 행위(메서드)를 하나로 묶어 객체로 만든 후 실제 내부 구현 내용은 외부에서 알 수 없게 감추는 것
  • 외부 객체에서는 캡슐화된 객체의 내부 구조를 알 수 없고 노출시켜준 필드 혹은 메서드를 통해 접근
  • java에서는 캡슐화된 객체의 필드와 메서드를 노출 시킬지 감출 지 결정하기 위해 접근 제어자를 사용
  1. 상속
  • 부모 객체는 가지고 있는 필드와 메서드를 물려주어 자식 객체가 이를 사용할 수 있도록 함
  • 각각의 객체들을 상속 관계로 묶음으로써 객체 간의 구조를 파악하기 쉬워짐
  • 필드와 메서드를 변경하는 경우 부모 객체만 수정하면 되므로 일관성을 유지하기 좋음
  • 필드와 메서드를 물려받아 사용하므로 코드의 중복이 줄어들며 재사용성이 증가함
  1. 다형성
  • 객체가 연산을 수행할 때 하나의 행위에 대해 각 객체가 가지고 있는 고유한 특성에 따라 다른 여러가지 형태로 재구성 되는 것을 의미
  1. 추상화
  • 객체에서 공통된 부분들을 모아 상위 개념으로 새롭게 선언하는 것

2. 클래스 설계

클래스 구성 : 필드, 생성자, 메서드

클래스 설계 과정
1. 클래스 선언
2. 속성(필드) 정의
3. 객체 생성 방식(생성자) 정의
4. 객체가 가지고 있어야 할 행위(메서드) 정의

//예시 자동차 클래스
public class Car {
    private String model; 	// 자동차 모델 변수

	public Car() {} 		// 기본 생성자

	public void horn() {	// 메서드
        System.out.println("빵빵");
    }
}

3. 객체

객체 생성

생성

new Car();	// Car 클래스 객체 생성
  • new : 객체 생성 연산자
  • new 연산자 뒤에 생성자 호출 코드 작성

참조형 변수

Car car1 = new Car(); // Car클래스의 객체인 car1 인스턴스 생성
Car car2 = new Car(); // Car클래스의 객체인 car2 인스턴스 생성
  • new 연산자를 통해 객체 생성 ➡️ 해당 인스턴스 주소 반환 ➡️ 해당 클래스의 참조형 변수 사용

객체 속성 : 필드

필드 : 객체의 데이터를 저장, 크게 고유 데이터, 상태 데이터, 객체 데이터로 분류

필드 사용 : 필드의 값을 변경하거나 읽는 것, 실제로 필드의 데이터를 가지고 있는 것은 객체이므로 객체를 생성한 후에 필드 사용 가능

  • 외부 접근 : 객체의 내부 필드에 접근할 때 도트(.) 연산자 사용 ➡️ car.color = "blue"
  • 내부 접근 : 객체 내부 메서드에서 내부 필드에 접근 시 바로 호출하여 사용

객체의 행위 : 메서드

메서드 : 객체간의 협력을 위해 사용, 블록 내부에 실행할 행위를 정의하며 리턴 타입과 매개변수 지정이 필요 (생략 가능)

메서드 호출 : 메서드에 작성된 코드 실행, 필드와 마찬가지로 객체 생성 후 호출 가능

  • 외부 접근 : 필드와 마찬가지로 도트(.) 연산자 사용

오버로딩

  • 하나의 메서드 이름으로 여러 기능을 구현하도록 하는 java의 기능
  • 한 클래스 내에 동일한 메서드가 있더라도 매개변수의 개수 또는 타입, 순서 등이 다르면 매서드를 재정의할 수 있음
  • 장점 : 메서드 이름 하나로 상황에 따른 동작을 개별로 정의하고 이름을 절약할 수 있음

매개변수

  • 기본형 : 메서드 호출 시 매개값으로 지정한 값을 매개변수에 복사하여 전달
  • 참조형 : 메서드 호출 시 매개값으로 지정한 값의 주소를 매개변수에 복사하여 전달

4. 인스턴스와 클래스 멤버

필드와 메서드는 선언하는 방법에 따라 인스턴스 멤버와 클래스 멤버로 구분 (멤버 = 필드 + 메서드)

인스턴스 멤버

  • 인스턴스 필드 + 인스턴스 메서드
  • 객체 생성 후 사용 가능
  • 객체의 인스턴스 필드는 각각의 인스턴스마다 고유한 값을 가질 수 있음
  • 메서드는 메서드 영역에 두고 모든 인스턴스가 공유하여 사용

클래스 멤버

  • 클래스 필드 + 클래스 메서드
  • 클래스는 java의 클래스 로더에 의해 메서드 영역에 저장되고 사용됨
  • 클래스 멤버 : 메서드 영역의 클래스와 같은 위치에 고정적으로 위치하고 있는 멤버 ➡️ 객체 생성 없이 사용 가능
  • 선언 : static 키워드 사용 / 일반적으로 공용적인 데이터를 저장하는 필드는 클래스 멤버로 선언, 인스턴스 필드를 사용하지 않고 실행되는 메서드는 클래스 메서드로 선언
  • 클래스 멤버로 선언된 메서드 ➡️ 인스턴스 멤버 사용 불가 / 인스턴스 멤버로 선언된 메서드 ➡️ 클래스 멤버 사용 가능

지역 변수 : 메서드 내부에 선언한 변수로 메서드가 종료될 때가지만 값이 유지됨
final 필드 : 해당값을 프로그램 실행 도중에 수정 불가
상수 : 값이 반드시 한 개이며 불변함

  • static final : 모든 인스턴스가 공유할 수 있는 값이 한 개이며 불변인 상수 선언

5. 생성자

생성자 : 객체가 생성될 때마다 호출되며 객체를 초기화하는 역할
기본 생성자 : 선언할 때 매개변수가 없이 선언되는 생성자, 생성자를 선언하지 않았다면 자동으로 추가됨
생성자 오버로딩 : 필드 초기화시 오버로딩을 사용하여 효율적 처리 가능

인스턴스마다 다른 값을 가져야 한다면 생성자를 통해 필드를 초기화
↔ 인스턴스마다 동일한 값을 가진다면 초기값 대입

 public Car(String modelName) {
        model = modelName;
    }

 public Car(String modelName, String colorName) {
        model = modelName;
        color = colorName;
    }
    
public class Main {
    public static void main(String[] args) {
    	Car car1 = new Car("GV60");
        Car car2 = new Car("GV70", "Blue");
	}
}

6. this

this

  • 인스턴스 자신을 표현하는 키워드
  • 객체 내부 생성자 및 메서드에서 객체 내부 멤버에 접근하기 위해 사용
  • 리턴 타입이 인스턴스 자신의 클래스 타입이라면 return this;를 사용하여 자신의 주소 반환 가능
  • ex) 생성자 선언시 매개변수명과 객체의 필드명이 동일한 경우, this 키워드를 통해 객체의 필드에 값을 대입하여 저장

this()

  • 인스턴스 자신의 생성자를 호출하는 키워드
  • 객체 내부 생성자 및 메서드에서 해당 객체의 생성자를 호출하기 위해 사용
  • 생성자를 통해 객체의 필드를 초기화하여 중복 코드를 줄일 수 있음
public Car(String model, String color) {
    this(model, color, 100000000);		// 아래의 생성자 호출
}

public Car(String model, String color, double price) {
    this.model = model;
    this.color = color;
    this.price = price;
}

7. 접근 제어자

제어자

클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미 부여
접근 제어자는 클래스 내부에 선언된 데이터를 보호하기 위해 사용 (캡슐화), 객체를 변경이 없는 상태로 유지하기 위해 사용 (무결성)

  • 접근 제어자 : public, protected, default, private
  • 그 외 제어자 : static, final, abstract

public : 접근 제한 없음
protected : 같은 패키지 내, 다른 패키지의 자손 클래스에서 접근 가능
default : 같은 패키지 내에서만 접근 가능
private : 같은 클래스 내에서만 접근 가능

사용 가능 접근 제어자

  • 클래스 : public, default
  • 메서드 & 멤버변수 : public, protected, default, private
  • 지역변수 : 없음

사용 가능 제어자

  • 클래스 : public, default, final, abstract
  • 메서드 : public, protected, default, private, final, abstract, static
  • 멤버변수 : public, protected, default, private, final, static
  • 지역변수 : final

⚠️ 제어자 사용 주의 사항

  • 메서드에 staticabstract 동시 사용 불가
  • 클래스에 abstractfinal 동시 사용 불가
  • abstract메서드의 접근 제어자가 private일 수 없음
  • 메서드에 privatefinal을 같이 사용할 필요 없음

Getter와 Setter

객체의 private 필드를 읽어오거나 저장하기 위해 사용
규칙 : get/set + 필드 이름

Getter : 외부에서 객체의 private 필드를 읽어올 때 사용

public String getModel() {
    return model;
}

Setter : 외부에서 객체의 private 한 필드를 저장/수정할 필요가 있을 때 사용

public void setModel(String model) {
    this.model = model;
}

8. packge와 import

packge(패키지) : 클래스의 일부분이면서 클래스를 식별해주는 용도
상위 패키지와 하위 패키지를 도트(.)로 구분

import : 다른 패키지에 있는 클래스를 사용하기 위해 명시하는 키워드

profile
Server Developer

0개의 댓글