[이것이 자바다] 06. 클래스

SeonJin·2023년 8월 29일
0

Java

목록 보기
4/11
post-custom-banner

📚 이것이 자바다 [개정판]


sec01. 객체 지향 프로그래밍

1. 객체란?

  • 객체 = 속성(필드) + 동작(메소드)
  • 물리적으로 존재하거나 개념적인 것 중에서 다른 것과 식별 가능한 것

2. OOP의 특징

  • 캡슐화
    • 필드와 메소드를 하나로 묶고 실제 구현 내용을 외부에 감추는 것이다
    • 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하기 위함이다
    • 접근 제한자를 통해 노출할 것인지 숨길 것인지 결정한다
  • 상속
    • 코드의 재사용성을 높여준다
    • 유지 보수 시간을 최소화시켜 준다
    • 자식 객체는 부모 객체의 기능을 물려받고 기능을 추가하여 확장한다
  • 다형성
    • 사용 방법은 동일하지만 실행 결과가 다양하게 나오는 성질이다

sec02. 객체와 클래스

  • 클래스 ⇒ 인스턴스화 (클래스로부터 객체를 만드는 과정) ⇒ 인스턴스(객체)
  • 하나의 클래스로부터 여러 개의 인스턴스를 만들 수 있다

sec03. 클래스 선언

// 클래스 선언
public class 클래스명 {
	// 객체 생성
	클래스 변수 = new 클래스(); 
  // 스택에 저장된 객체의 주소를 힙에 생성된 객체가 참조

	// 필드 선언
	type fieldName;

	// 생성자 선언 (클래스명과 동일)
	ClassName() {...} 

	// 메소드 선언
	type methodName() {...}

💡 하나의 소스 파일에 여러 개의 클래스를 선언하는 경우
파일명과 동일한 클래스만 공개(public) 클래스로 선언할 수 있다

💡 필드와 지역(로컬)변수의 차이점
필드 : 클래스 내에 선언, 객체 내부에 존재하며 객체 내/외부 어디든 사용 가능
변수 : 생성자나 메소드 내에서 선언되어 그 내부에서만 사용 가능


sec04. 객체 생성과 클래스 변수

  • 클래스 변수 = new 클래스();
  • 클래스로부터 객체를 생성하려면 객체 생성 연산자인 new 가 필요하다
  • new 연산자는 객체를 생성시킨 후객체의 주소를 리턴한다

sec05. 클래스의 구성 멤버

public class ClassName {
	// 필드 선언
	타입 fieldName;

	// 생성자 선언
	ClassName() {...}

	// 메소드 선언
	타입 methodName() {...}
  • 필드
    - 객체의 데이터를 저장하는 역할

  • 생성자
    - new 연산자로 객체를 생성할 때 객체 초기화 역할
    - 메소드와 비슷하지만 리턴 타입이 없고, 클래스 이름과 동일하다
    - 모든 클래스에는 생성자가 존재한다

  • 메소드

    • 객체가 수행할 동작
    • 객체와 객체간의 상호 작용을 위해 호출된다

sec06. 필드 선언과 사용

  • 타입 필드명 = 초기값; 타입 필드명;
  • 필드명은 첫 문자를 소문자로 하고 캐멀 스타일로 작성한다
  • 초기값을 설정하지 않은 필드는 객체 생성 시 타입의 기본값으로 초기화된다
  • 필드는 객체의 데이터이므로 객체가 존재해야만 사용할 수 있다
  • 외부 객체에서 사용할 때는 도트 연산자(.)를 사용한다
class Car2 {
	// 필드 선언
	String model = "그랜저";
	String color = "balck";
	int maxSpeed = 350;
	int speed;
}

public **class** CarMain2 {
	public static void main(String[] args) {
		// Car 객체 생성
		Car2 myCar = new Car2();
		
		// Car 객체의 필드값 읽기
		System.out.println("모델명: " + myCar.model);
		System.out.println("색상: " + myCar.color);
		System.out.println("최고속도: " + myCar.maxSpeed);
		System.out.println("현재속도: " + myCar.speed);
		
		// Car 객체의 필드값 변경
		myCar.speed = 60;
		System.out.println("수정된 속도: " + myCar.speed);
	}

}

sec07. 생성자 선언과 호출

1. 생성자

  • 클래스 변수 = new 클래스(); → 생성자 호출
  • new 연산자는 객체를 생성한 후 객체를 초기화하는 역할을 한다
// 생성자 선언
ClassName(매개변수, ...) {
	// 객체 초기화 코드
}
// 생성자 호출
ClassName 변수명 = new ClassName(매개변수);

2. 생성자 오버로딩

  • 매개값을 통해 객체의 필드를 다양하게 초기화하기 위한 방법
  • 매개변수를 달리하는 생성자를 여러 개 생성하는 것이다
Car() {...}
Car(String model) {...}
Car(String model, String color) {...}
Car(String model, String color, int maxSpeed) {...}

3. 다른 생성자 호출

// model만 초기화하는 생성자
Car3(String model) {
	this(model, "은색", 250); // #1 생성자 호출
}

// model과 color를 초기화하는 생성자
Car3(String model, String color) {
	this(model, color, 250); // #1 생성자 호출
}

// #1 모든 필드를 초기화하는 생성자 (공통코드로 사용되는 생성자)
Car3(String model, String color, int maxSpeed) {
	this.model = model;
	this.color = color;
	this.maxSpeed = maxSpeed;
}

sec08. 메소드 선언과 호출

  • 메소드 선언: 객체의 동작을 실행 블록으로 정의하는 것
  • 메소드 호출: 실행 블록을 실제로 실행하는 것
  • return문 : 메소드의 실행을 강제 종료하고 호출한 곳으로 돌아간다
  • 메소드명은 첫 문자를 소문자로 시작하고 캐멀 스타일로 작성한다
// 리턴값이 있는 메소드 선언
리턴타입 메소드명 (매개변수, ...) { 실행코드 };

// 리턴값이 없는 메소드 선언
void 메소드명 (매개변수, ...) { 실행코드 };

// 메소드 호출
타입 변수 = 메소드명();

sec09-10. 인스턴스 멤버 & 정적 멤버

  • 인스턴스(instance) 멤버
    • 객체에 소속되어 객체를 생성해야만 사용할 수 있는 멤버
    • 객체를 생성하고 참조변수명으로 접근한다

  • 정적(static) 멤버
    • 클래스에 고정되어 객체 없이도 사용할 수 있는 멤버
    • 클래스명으로 접근한다
    • 정적 필드는 필드 선언과 동시에 초기값을 주는 것이 일반적이다
    • 공용적인 필드는 정적 필드로 선언하는 것이 좋다
    • 인스턴스 멤버 사용 불가, this 사용 불가
      • → 객체 생성한 경우 가능
public class Car {
	// 인스턴스 필드 선언
	int speed;
	// 인스턴스 메소드 선언
	void run() {
		System.out.println(speed + "으로 달립니다.");
	}
	static void simulate() {
		// 객체 생성
		Car myCar = new Car();
		// 인스턴스 멤버 사용
		myCar.speed = 200;
		myCar.run();
	}
	public static void main(String[] args) {
		// 정적 메소드 호출
		simulate();
		// 객체 생성
		Car myCar = new Car();
		// 인스턴스 멤버 사용
		myCar.speed = 30;
		myCar.run();
	}
}

sec11. final 필드와 상수

  • final 초기값이 저장되면 이것이 최종값이 되어 수정할 수 없다
  • 필드 선언 시에 초기값을 대입하거나, 생성자에서 초기값을 대입한다
  • 상수 이름은 모두 대문자로 작성하고, 언더바(_)로 단어를 연결한다
    // 상수 선언 및 초기화
    static final double EARTH_RADIUS = 6400;
    	
    // 상수 선언
    static final double EARTH_SURFACE_AREA;
    
    // 정적 블록에서 상수 초기화
    static {
    	EARTH_SURFACE_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
    }

sec13. 접근 제한자

  • 객체의 무결성을 유지하게 위해서는 객체의 필드를 외부에서 변경하거나 메소드를 호출할 수 없도록 막아야 한다
  • 클래스, 멤버변수, 메서드, 생성자에서 사용될 수 있다
  • public 접근 제한이 없음
  • protected 같은 패키지 내, 다른 패키지의 자손클래스에서 접근 가능(상속하는 경우)
  • (default) 같은 패키지 내에서만 접근 가능, 아무것도 붙이지 않은 상태
  • private 같은 클래스 내에서만 접근 가능

sec14. Getter, Setter

  • 객체지향프로그래밍에서는 객체의 무결성이 중요하기 때문에 직접적인 필드 접근을 막고 메소드를 통해 접근하는 것을 선호한다
  • private 제어자를 사용하는 경우!!
  • setter()데이터를 검증하여 유효한 값만 필드에 저장한다 (데이터 접근, 수정)
  • getter()부적절한 데이터인 경우 적절한 값으로 변환하여 리턴한다 (변경한 데이터 읽기)
private 타입 fieldName;

// getter
public 타입 **getF**ieldName() {
	return fieldName;
}

public boolean **isF**ieldName

// setter
public void setFieldName(타입 fieldName) {
	this.fieldName = fieldName;
}

sec15. 싱글톤 패턴

  • 단 한 개의 객체만 생성해서 사용하고 싶은 경우에 적용할 수 있다
  • 생성자를 private 접근 제한하여 외부에서의 생성자 호출을 막는 것이 핵심
  • 싱글톤 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있다
public class 클래스 {
	// private 접근 권한을 갖는 정적 필드 선언과 초기화
	// 자신의 클래스 타입으로 정적 필드를 선언하고 
	// 미리 객체를 생성하여 초기화
	private static 클래스 singleton = new 클래스();
	
	// private 접근 권한을 갖는 생성자 선언
	private 클래스() {}
	
	// public 접근 권한을 갖는 정적 메소드 선언
	// 정적 메소드를 public으로 선언하여 정적 필드값을 리턴할 수 있다
	// -> 외부에서 객체를 얻는 유일한 방법
	public static 클래스 getInstance() {
		return singleton;
	}
}
profile
study notebook
post-custom-banner

0개의 댓글