[혼공자] 3주차_06

다율·2024년 1월 21일
1

2024 혼공자

목록 보기
4/7
post-thumbnail

기본 미션: 어렵거나 중요하다고 생각하는 용어를 혼공 용어 노트에 정리하고 공유하기

저는 이곳에 정리해보겠습니다!
(학교에서 배웠던 내용이라 헷갈리는 것이나 중요한 것 위주로 조금 정리해보았습니당)

객체 : 자신의 속성을 가지고 식별이 가능한 모든 것이라고 생각하면 됨(자동차, 책, 강의 등), 필드와 메소드으로 구성
객체 모델링 : 현실세계의 객체를 소프트웨어 객체로 설계하는 것(시간 소요)
인스턴스 : 클래스로부터 만들어진 객체
필드 : 클래스 내에 있는 지역 변수
정적 : Static, 클래스에 고정되어 있는 것


선택 미션: 객체 지향 프로그래밍의 개념 정리하기

객체 지향 프로그램이란 ?
: 객체를 모델링하고 이를 조립해 프로그램을 만드는 기법. 추상화, 상속, 다형성, 캡슐화등의 특징을 가짐


06 클래스

06-1 객체 지향 프로그래밍

객체 내용은 위의 미션들에서 확인하기!

1) 객체의 상호작용

객체는 독립적이지만, 다른 객체와 메소드를 수단으로 상호작용 함

  • 객체가 다른 객체의 기능을 이용하는 것이 메소드 호출
// 리턴 값 = 객체.메소드(매개값1, 매개값2..);
int result = Calculator.add(10, 20);

// return값 : 30

2) 객체 간의 관계

  1. 집합 관계
    • 객체 하나는 부품이고 하나는 완성품 (핸들, 엔진과 자동차)
  2. 사용 관계
    • 객체 간의 상호작용, 다른 객체를 호출하여 원하는 결과를 얻음 (사람이 자동차를 사용)
  3. 상속관계
    • 상위 객체를 기반으로 하위 객체를 생성하는 관계 (기계와 자동차, 핸드폰)

3) 객체와 클래스

  • 클래스(설계도) : 객체를 생성하기 위한 필드와 메소드가 정의되어 있음
  • 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스라고 하고 만들어지는 과정은 인스턴스화라고 함
  • 하나의 클래스(설계도)로 객체(인스턴스)를 여러개 만들 수 있음 (현실세계와 동일)

    개발자가 클래스(설계도)를 설계 -> 객체(인스턴스)를 만드는 인스턴스화 과정 -> 객체 완성!

4) 클래스 선언

  • 클래스 이름은 다른 클래스와 식별할 목적으로 사용되므로 식별자 작성 규칙
    따라 만듦
  • 소스파일 이름도 클래스 이름과 같도록 해야 함
  • 한 파일에 2개 이상의 클래스를 선언가능하지만, public은 소스파일 이름과 같은 클래스에만 붙이기 (일반적으로 하나의 클래스만 생성)
// 예시
public class 클래스 이름 {

}

5) 객체 생성과 클래스 변수

  • new 연산자 사용하기
    • 클래스로부터 객체를 생성시키는 연산자 (heap 영역에 생성)
    • new 연산자를 사용한 만큼 객체가 메모리에 생성됨
클래스 변수;
변수 = new 클래스();

클래스 변수 = new 클래스();

// 예시
Student s1 = new Student();

6) 클래스의 구성멤버

  • 필드, 생성자, 메소드 등이 있음
    • 필드(Field) : 객체의 데이터가 저장되는 곳
    • 생성자(Constructor) : 객체 생성 시 초기화 담당 (클래스 이름과 동일한 이름, return 타입 없음)
    • 메소드(Method) : 객체의 동작에 해당하는 실행 블록 (return 타입 있음)
public class ClassName {

	int fieldname;		// 필드
    
    ClassName() { ... }		// 생성자

	void methodName() { ... }		// 메소드
}

06-2 필드

1) 필드 선언

  • 클래스 중괄호에서 선언, 메소드와 생성자 내부에는 선언 X (로컬변수가 됨)
  • 변수 선언과 비슷하지만, 필드를 변수라고 부르지 않음
  • 초기값이 지정되지 않으면 자동으로 기본 초기값 설정 (변수와 같음)
String company = '카카오';
int speed;		// 0
boolean start;	// false

2) 필드 사용

  • 필드 값을 읽고 변경하는 작업
  • 외부 클래스에서 필드값을 사용하려면 먼저 객체를 생성해야 함
  • 생성 후 . 객체 접근연산자(도트 연산자)를 사용해 필드나 메소드를 접근 가능함
// 외부 클래스일 경우
Car myCar = new Car();
myCar.speed = 60;

06-3 생성자

  • 생성자 : new 연산자로 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당함
    • 객체 초기화란? 필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 하는 것

1) 기본 생성자

  • 모든 클래스에 존재
  • 생성자 선언을 생략한다면 JVM이 자동으로 기본 생성자를 추가해줌
    • 기본생성자란? 중괄호 내용이 비어있는 생성자
  • 하지만 명시적으로 선언된 다른 생성자가 있으면 기본 생성자를 추가해주지 않음
  • 클래스가 public으로 선언되면 기본 생성자에도 public이 붙지만 없이 선언되면 기본 생성자에도 붙지 않음

.java(소스 파일) -> 컴파일 -> .class(바이트코드 파일)
Car myCar = new Car()이 부분이 기본 생성자를 호출하는 것

2) 생성자 선언

  • 메소드와 비슷한 모양이지만, return 타입이 없고 클래스 이름과 동일 (생성자 오버로딩)
클래스이름(매개변수 선언 , ...) {
	// 객체의 초기화 코드
}

3) 필드 초기화

  • 필드를 선언할 때 초기값 주기, 생성자에서 초기값 주기 (2가지 방법)
  • this. 사용하기 (필드를 뜻함, 전역)
public Korean(String name, String ssn) {
		this.name = name;		// 필드 초기화
		this.ssn = ssn;
}

4) 생성자 오버로딩

  • 다양한 방법으로 객체를 초기화, 생성할 수 있도록 제공
  • 매개변수의 타입, 개수, 순서를 다르게 선언 (클래스 이름은 같음)
	public Car() {};				// 기본 생성자
	
	public Car(String model) {		// 생성자
		this.model = model;
	}
	
	public Car(String model, String color) {	// 생성자 오버로딩
		this.model = model;
		this.color = color;
	}

5) 다른 생성자 호출: this()

  • 생성자 간의 중복된 코드를 줄일 수 있음
  • 자신의 다른 생성자를 호출하는 코드, 생성자의 첫 줄에서만 허용됨
  • 뒤에 추가적인 실행문이 올 수 있음
	public Car() {};				
	
	public Car(String model) {		
		this(model, "검정");			// 중복 코드 줄이기
	}
	
	public Car(String model, String color) {	
		this.model = model;			
		this.color = color;
	}

06-4 메소드

  • 메소드 선언부를 메소드 시그니처라고 함
  • 선언부와 실행 블록
    • 리턴 타입 : 메소드가 리턴하는 결과의 타입을 표시
    • 메소드 이름 : 메소드의 기능이 드러나도록 식별자 규칙에 맞게 이름을 지음
    • 매개 변수 선언 : 메소드를 실행할 때 필요한 데이터를 받기 위한 변수를 선언
    • 메소드 실행 블록 : 실행할 코드를 작성
// 메소드 형태
 	리턴타입 메소드이름(매개변수 선언, ...) {
    
    		실행할 코드 작성
            
    }

1) 메소드 선언

  • 선언부(리턴 타입, 메소드 이름, 매개변수 선언)와 실행블록으로 구성

리턴 타입

  • 리턴하는 값의 타입 (리턴 값: 메소드 실행 후 결과값)
    • 리턴 값이 있다면 반드시 선언부에 리턴 타입을 명시해야 함, 없으면 void

메소드 이름

  • 자바 식별자 규칙에 맞게 작성하면 됨
  • 이 메소드가 어떤 기능을 수행하는지 알 수 있도록 기능 이름으로 짓는게 좋음

매개 변수 선언

  • 메소드 실행 시, 필요한 데이터를 외부로부터 받기 위해 사용함

사용 예시

// class
public class Calculator {
	
	// 메소드
	void powerOn() {
		System.out.println("전원을 켭니다.");
	}
	void powerOff() {
		System.out.println("전원을 끕니다.");
	}
	
	int plus(int x, int y) {
		int result = x = y;
		return result;
	}
	
	double divide(int x, int y) {
		double result = (double)x / (double)y;
		return result;
	}
}

// main
public class CalculatorExample {

	public static void main(String[] args) {
		
		Calculator myCalc = new Calculator();
		myCalc.powerOn();
		
		int plus = myCalc.plus(3,5);
		System.out.println(plus);
		
		byte x = 10;
		byte y = 4;
		double divide = myCalc.divide(x, y);
		System.out.println(divide);
		
		myCalc.powerOff();

	}

}

매개 변수의 개수를 모를 경우

  • 매개 변수를 배열 타입으로 선언하기
  • 배열을 생성하지 않고 값의 목록만 넘기기
// 예시

public class Computer {
	// 둘다 같은 값을 리턴함
	int sum1(int values[]) {
		int sum = 0;
		for(int i = 0; i < values.length; i++) {
			sum += values[i];
		}
		return sum;
	}
	
	int sum2(int ... values) {
		int sum = 0;
		for(int i = 0; i < values.length; i++) {
			sum += values[i];
		}
		return sum;
	}
}


public class ComputerExample {

	public static void main(String[] args) {
		
        //  메소드 사용방법 잘 보기!
		Computer myCom = new Computer();
		
		int values[] = {1, 2, 3};		// 먼저 선언
		int result1 = myCom.sum1(values);
		System.out.println("result1 : " + result1);
		
		int result2 = myCom.sum1(new int[]{1, 2, 3, 4, 5});		// 내에서 선언
		System.out.println("result2 : " + result2);
		
		int result3 = myCom.sum2(1, 2, 3);
		System.out.println("result3 : " + result3);
		
		int result4 = myCom.sum2(1, 2, 3, 4, 5);
		System.out.println("result4 : " + result4);
	}

}

2) 리턴(return)문

리턴 값이 있는 메소드

  • 메소드 선언에 리턴 타입이 있는 메소드는 반드시 return문이 있어야 함
  • return문 이후에 실행문이 오면 error발생

리턴 값이 없는 메소드: void

  • 리턴값을 저장하는 것이 아니라 메소드 실행을 강제종료 시키는 역할을 하기도 함

객체(클래스) 내부에서 호출

public class Calculator {

  int plus(int x, int y) {
          int result = x + y;
          return result;
      }

      double avg(int x, int y) {
          double sum = plus(x, y);
          double result = sum / 2;
          return result;
      }
 }

객체(클래스) 외부에서 호출

  • 클래스로부터 객체 생성 후 가능함
		Car2 myCar = new Car2();
		
		myCar.keyTurnOn();
		
		myCar.run();
		
		int speed = myCar.getSpeed();

3) 메소드 오버로딩

  • 클래스 내에 같은 이름의 메소드를 여러개 선언하는 것
  • 생성자 오버로딩과 비슷함
  • 매개변수의 타입, 순서, 개수가 달라야 함
public class Calculator1 {
	// 메소드 오버로딩
	// 정사각형의 넓이
	double areaRectangle(double width) {
		return width * width;
	}
	
	// 직사각형의 넓이
	double areaRectangle(double width, double height) {
		return width * height;
	}
}

06-5 인스턴스 멤버와 정적 멤버

  • 인스턴스 멤버 : 객체마다 가지고 있는 멤버
  • 정적 멤버 : 클래스에 위치시키고 객체들이 공유하는 멤버

1) 인스턴스 멤버와 this

  • 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드를 뜻함(인스턴스 필드, 인스턴스 메소드)
  • 객체이름.필드 or 메소드로 접근함

인스턴스 멤버 선언

  • 지금까지 클래스에서 선언하던 방식

this

  • this.model은 필드를 객체에서 자기 자신, 필드(전역변수)를 뜻하게 됨
Car(String model) {
	this.model = model;
}

2) 정적 멤버와 static

  • 클래스에 고정된 멤버, 객체를 생성하지 않고도 사용할 수 있는 필드와 메소드(정적 필드, 정적 메소드)
  • 클래스이름.필드 or 메소드로 접근함(객체이름도 가능하지만 구분을 위해서!)
  • 선언 시 static을 앞에 붙임
  • main() 메소드도 static이 앞에 붙음

정적 메소드 선언 시 주의할 점

  • 객체가 생성된 후 사용 가능한 인스턴스 필드나 메소드는 사용할 수 없고, this도 사용할 수 없음

3) 싱글톤

  • 하나만 생성되는 객체를 뜻함
  • 외부에서의 생성자 호출을 막기 위해 private를 붙임
  • 자신의 타입인 정적 필드를 하나 선언, 자신의 객체를 생성해 초기화함
  • 클래스 내부에서는 new 연산자로 생성자 호출이 가능
  • 외부에서 필드 값을 변경하지 못하게 막고, 대신 외부에서 호출 가능한 정적 메소드를 선언
// 내가 헷갈리는 관계로.. 
public class Singleton {
	
	private static Singleton singleton = new Singleton();
	
	private Singleton() {
		// private 생성자로 외부에서 인스턴스를 생성하지 못하게 막음
	}
	
	static Singleton getInstance() {
		return singleton;
	}
}



public class SingletonExample {

	public static void main(String[] args) {
		
//		Singleton obj = new Singleton(); 	컴파일 에러
		
		Singleton obj1 = Singleton.getInstance();
		Singleton obj2 = Singleton.getInstance();
		
		if(obj1 == obj2)
			System.out.println("같은 Singleton 객체입니다.");
		else
			System.out.println("다릅니다.");
		// 출력결과 : 같은 객체
	}

}

4) final 필드와 상수

final 필드

  • 저장된 초기값이 최종값으로, 실행 중에 수정할 수 없음
  • 필드에서 주거나, 생성자에서 초기값을 줄 수 있음
public class Person {
	final String nation = "Korea";
	final String ssn;
	String name;
	
	public Person(String ssn, String name) {
		this.ssn = ssn;
		this.name = name;
	}
}

상수

  • static이면서 final이어야 함
  • 객체마다 존재하지 않고 클래스에만 존재, 초기값 저장 후 변경 불가
  • 상수 이름은 대문자로 작성하는 것이 관례임, 여러 단어라면 _로 연결하기
public class Earth {
	static final double EARTH_RADIUS = 6400;
}

06-6 패키지와 접근 제한자

  • 폴더 기능뿐만 아니라 클래스의 일부분으로 클래스를 유일하게 만드는 식별자 역할
  • 클래스 이름이 동일하더라도 패키지가 다르면 다른 클래스로 인식

1) 패키지 선언

  • 패키지 이름 : 모두 소문자로 작성하고, java로 시작하는 패키지는 자바 표준 API에서 사용하므로 사용하면 안됨
package 상위패키지.하위패키지;

public class 클래스 이름 { ... }

import문

  • 사용하고자 하는 클래스 또는 인터페이스가 다른 패키지에 소속되어 있다면 import로 컴파일러에게 알려줘야 함
  • 개수에 제한이 없음
  • ctrl + shift + o : 사용된 클래스를 조사해 알아서 import문을 추가해줌
import 상위패키지.하위패키지.클래스 이름;
import 상위패키지.하위패키지.*;		// 해당 패키지에 소속된 클래스를 사용한다는 뜻

2) 접근 제한자

  • 클래스 및 인터페이스 그리고 멤버의 접근을 제한하기 위해 사용
  • 클래스, 생성자, 필드, 메소드 접근제한이 가능
  1. public : 외부 클래스가 자유롭게 사용할 수 있도록 함
  2. protected : 같은 패키지 또는 자식 클래스에서 사용할 수 있도록 함
  3. private : 개인적인 것이라 외부에서 사용할 수 없도록 함
    위 세가지 접근 제어가자 적용 되지 않으면..
  4. default : 같은 패키지에 소속된 클래스에서만 사용할 수 있도록 함

큰 순서대로 public > protected > (default) > private

3) Getter와 Setter 메소드

  • Setter : 필드는 외부에서 접근할 수 없도록 막고, 메소드를 공개해 외부에서는 메소드를 통해 필드에 접근하도록 함 (메소드에서 검증 후 필드에 저장할 수 있기 때문)
  • Getter : 메소드로 필드값을 가공하여 외부로 전달할 수 있음

필드는 private로 + Getter, Setter 메소드 작성하기 (필드를 안전하게 변경/사용)

private 타입 fieldName;	

//Getter, 리턴타입이 boolean일 경우 메소드 이름은 is로 시작
public 리턴타입 getFieldName() {		// 메소드 이름: get + 필드이름(첫 글자는 대문자)
	return fieldName;
}

// Setter
public void setFieldName(타입 fieldName) {	// 메소드 이름: set + 필드이름(첫 글자는 대문자)
	this.fieldName = fieldName;
}

깃허브 링크

https://github.com/dayul/SelfStudy_Java

profile
새싹 개발자 🌱

0개의 댓글