기간 : 220926~220929
어느덧 3주차에 접어들었다. 뭔가 하루가 정말 빨리빨리 지나가는 기분이다.
공부하다보면 생각보다 많이 안한거같은데 시간이 훅훅지나간다 🥲
배열
배열
을 사용한다.0
부터 시작for
문을 통해 사용 ( for-each문 사용 가능)데이터타입[] 배열변수명 = new 데이터타입[데이터갯수];
int[] scores1 = new int[100]; // 저장할 원소 갯수만 알고 있는 경우
데이터타입[] 배열변수명 = {...};
int[] scores2 = {90, 80, 72, ..., 60} // 원소값을 알고 있는 경우
데이터타입[] 배열변수명;
배열변수명 = new 데이터타입[데이터갯수]({...});
int[] scores3;
int[] scores3 = new int[10]({10, ...}) // 선언 후 나중에 초기화 하는 경우
null
값으로 초기화 가능데이터타입[] 배열변수명 = null;
int[] arr = null;
메모리
- 원소가 원시타입인 경우
- 배열 변수에는 첫번째 원소의 주소값만 저장
-> 원소가 연속적으로 저장되기 때문에 주소 인덱싱을 통해 타 원소 접근 가능
- 원소가 참조타입인 경우
이차원 배열
데이터타입[][] 배열변수명 = new 데이터타입[행][열];
int[][] scores = new int[3][3]; //
이후 일차원 배열과 유사
메모리
- 원소가 원시타입인 경우
- 배열 변수에는 첫번째 원소 주소값만 저장
->int[] nums2d
에는 실제 데이터의 주소가 배열로 저장되어 있음
- 원소가 참조타입인 경우
배열 비교
equals()
사용배열 복사
함수
동사+목적어
형태로 작성메서드 : 객체를 구현하기 위한 클래스 내부에 구현되는 함수
- 멤버 함수라고도 함
반환타입 함수명(매개변수) {
내용
return 반환값;
}
하나
이거나 없음
void
를 지정return new int[] (x, y);
오버로딩
class A {
int x, y;
public A() {}
public A(int x, int y) {...} // 오버로딩
public int add() {...}
public int add(int x, int y) {...} // 오버로딩
재귀함수?
- 함수에서 자기 자신을 다시 호출해 작업을 수행하는 방식
-> 재귀함수의 대부분은 반복문으로 바꿔서 구현할 수 있다vs 반복문
- 반복문보다 코드의 길이가 짧다
- 재귀함수 호출과 함께 스택에 적재되고 완료될 때 까지 유지
-> 많은 메모리 사용
객체
필드 (데이터)
와 이를 기능하게하는 메서드 (함수)
를 가짐객체 관계
클래스
객체지향을 할 때
- 객체를 정의
- 각 객체의 속성을 멤버변수로 기능을 메서드로 구현하고
- 각 객체 간의 협력을 구현
인스턴스
인스턴스
라고 부름new
키워드를 통해 생성클래스? 객체? 인스턴스?
- 클래스 vs 객체
- 클래스: 설계도
- 객체: 설계도로 구현한 모든 대상
- 객체 vs 인스턴스
- 클래스 타입으로 선언되었을 때 객체라고 부름
Student student;
-> 객체변수라고도 함- 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부름
Student student = new Student();
생성자 (Constructor)
new
키워드를 통해 객체를 생성할 때 호출되는 메서드
객체 생성과 동시에 원하는 값으로 초기화할 수 있는 메서드
생성자의 이름은 클래스의 이름과 동일
대부분의 클래스에서는 보통 생성자 오버로딩
이 많이 되어있음
-> 객체 생성을 다양하게 생성할 수 있도록
생성자 정의를 하지않은 클래스는 자바컴파일러가 자동으로 생성함 (디폴트 생성자)
-> 생성자를 하나라도 생성했을 경우 디폴트 생성자는 생성되지 않는다
-> 필요 시 기본 생성자도 정의
생성자 내부에서 또 다른 객체의 생성은 좋지않다
-> 객체의 결합도가 높아짐
캡슐화 (Encapsulation)
관련있는 필드와 메소드를 하나로 묶고 외부에서 접근하지 못하도록 구현하는 방법을 의미
외부에는 통합된 인터페이스만을 제공해서 일관된 기능을 구현하게 함
각각의 메서드나 멤버변수를 접근함으로써 발생하는 오류를 최소화
접근제어자
, setter/getter
를 통해 캡슐화를 구현한다.
접근 제어자
접근제어자 | 같은 클래스 멤버 | 같은 패키지 멤버 | 자식 클래스 멤버 | 그 외 |
---|---|---|---|---|
public | ⭕️ | ⭕️ | ⭕️ | ⭕️ |
protected | ⭕️ | ⭕️ | ⭕️ | ❌ |
default | ⭕️ | ⭕️ | ❌ | ❌ |
private | ⭕️ | ❌ | ❌ | ❌ |
private: 클래스 내부를 세부적으로 구현하기 위해 사용
public: private필드와 프로그램 사이 인터페이스 역할
default: 접근 제어자 기본값
protected
public > protected > default > private
setter / getter
static
접근제어자 static 데이터타입 변수명 = 초기값;
private static int serialNum = 1000;
static
을 이용해 메서드를 만들 경우 인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수 사용 불가!!! ❌singleton pattern
구현방법
- 생성자는 private로 생성
private Company();
- 클래스 내부 유일한 private 인스턴스 생성
private static Company instance = new Company();
- 외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공
public static Company getInstance() { if( instance == null) { instance = new Company(); } return instance; }
어노테이션
@AnnotationName
이번 주 객체지향에 대해 어느정도 수업을 듣게되었다.
듣고나서 헷갈리는 부분도 많고 당장은 어떻게 사용해야할지 감이 잘 안와서
어렵긴한데 자꾸 찾아보고 듣다보니 어느정도는 이해할 수 있을지도 😅
(사실은 🤯)
상속 (inheritance)
private
는 자식도 이용 불가자식클래스 extends 부모클래스 {}
public class SportCar extends Car {...}
상속의 장점
오버라이드
반환타입 / 메서드명 / 매개변수
를 가져야한다상속이 안되는 경우?
- 부모 클래스의
private
로 정의된 필드나 메서드- 부모 클래스 자체가
final
로 정의된 경우
-> final은 해당 상태가 최종이므로 더이상의 수정이 불가한 상태
다형성 (Polymorphism)
업캐스팅, 다운캐스팅 (형변환)
Customer customer = new VIPCustomer();
위처럼 자식 클래스는 부모 클래스의 타입을 내포하고 있으므로 부모 클래스로의
묵시적 형변환(업캐스팅, promotion) 가능
VIPCustomer vipCustomer = new Customer(); // X
반대로 위처럼 부모 클래스는 자식 클래스로 다운캐스팅이 불가능❗️
-> 자식 클래스는 부모 클래스를 상속받아 추가적인 필드나 메서드를 구현하여 부모 클래스가 사용할 수 없다.
VIPCustomer vipCustomer = (VIPCustomer)customer
// 명시적으로 선언해줘야 함
instanceof
- 원래의 인스턴스 형이 맞는지 체크하는 키워드
- 맞으면 ture, 틀리면 false를 반환
가상 메서드
자바에서는 모든 메서드가 가상 메서드이다
부모 객체에서 자식 인스턴스가 있는 경우 부모 클래스의 이름으로 함수를 호출하여도 각자의 자식 인스턴스의 함수가 실행됨
Shape 클래스 가상 메서드 테이블
오버라이딩 유무 | 메서드 주소값 | |
---|---|---|
draw() | ❌ | 100 |
getCenterPoint() | ❌ | 200 |
Circle 클래스 가상 메서드 테이블
오버라이딩 유무 | 메서드 주소값 | 설명 | |
---|---|---|---|
draw() | ⭕️ | 300 | 재정의된 함수 호출 |
getCenterPoint() | ❌ | 200 |
재정의 된 경우 다음과 같이 새로운 주소값을 가진다 ❗️
추상 클래스
abstract class 클래스명
abstract 반환타입 메서드명(매개변수);
추상 클래스를 사용하는 이유
- 자식 클래스들을 관리하기 위함
- 자식 클래스들의 공통적인 특성을 추출해서 선언
- 자식들을 하나의 객체변수로 관리하기 좋다!
- 공통적인 필드와 메서드는 추상 클래스에서 선언했기 때문에 실체 클래스를 작성할 때 공통적인 필드나 메서드는 생각하지 않아도되어 시간 절약
인터페이스
interface 인터페이스명 {
// 상수
// 추상 메서드
// 디폴트 메서드
// 정적 메서드
}
class 클래스명 implements 인터페이스명 {}
public
이여야함 (public
이 기본 접근 제어자로 생략 가능)OOP 개념을 배우고 있는데 다양한 용어들이 나오고 그에 파생되는 용어도 되게 많아서 헷갈리는 부분이 많은 것 같다.
핵심적인 개념을 배웠으니 앞으로 다양한 예제를 접하면서 헷갈리는 부분은 계속 반복적으로 복습해야겠다 😁