객체란? 물리적으로 존재하거나 개념적인 것 중에서 다른 것과 식별 가능한 것을 말함. ex) 물리적으로 존재하는 자동차, 자전거, 책, 사람은 물론 개념적인 학과, 강의, 주문 등 모두 객체. 객체는 속성과 동작으로 구성. 사람은 이름, 나이 등의 속성과 웃다, 걷다 등의 동작이 있음.
속성 = 필드 (field)
동작 = 메소드 (method)
사람 : 속성 : 이름, 나이
동작 : 웃다, 먹다
객체 모델링 : 현실 세계 객체의 대표 속성과 동작을 추려내어 소프트웨어 객체으 필드와 메소드로 정의하는 과정이다.
객체의 상호작용 : 객체와 객체 간의 상호작용 ex) 사람 - 전자계산기 : 사람은 전자계산기의 기능을 사용, 전자계산기는 결과를 사람에게 리턴.
객체 지향 프로그램에서도 객체들은 달느 객체와 서로 상호작용하면서 동작. ㄱ개체들 사이의 상호작용 수단 = 메소드. 객체가 다른 객체의 기능을 이용할 때 이 메소드를 호출.
메소드 호출 : 메소드 (매개값1, 매개값2) : 메소드 호출을 통해 객체들은 데이터를 서로 주고받음. 메소드 이름과 함께 전달하고자 하는 데이터를 괄호 안에 기술. = 매개값. 매개값은 메소드가 실행할 때 필요한 값. 리턴값은 메소드의 실행 결과. 호출한 곳으로 돌려주는 값.
정리 = 메소드 속에 매개값을 넘겨주면, 메소드가 특정 기능을 수행하여 결과값을 다시 리턴해준다.
리턴값 = 호출한 곳에서 변수로 대입 받아 사용한다.
객체 간의 관계
: 객체는 단독으로 존재 가능하나, 대부분 다른 객체와 관계를 맺음. 관계의 종류 = 집합 관계, 사용 관계, 상속 관계.
집합 관계 = 완성품과 부품의 관계. ex) 자동차 = 엔진, 타이어, 핸들/ 자동차와 부품들 = 집합 관계
사용 관계 = 다른 객체의 필드를 읽고 변경하거나 메소드를 호출하는 관계.
상속 관계 = 부모와 자식 관계.
1) 캡슐화 : 객체의 데이터(필드), 동작(메소드)를 하나로 묶고 실제 구현 내용을 외부에 감추는 것. 외부 객체는객체 내부의 구조를 알지 못하며, 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있다.
왜? 필드와 메소드를 캡슐화하여 보호하는 이유 = 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 함. 접근 제한자를 사용.
2) 상속 : 부모 역할의 상위 객체와 자식 역할의 하위 객체 존재. 부모 = 자기가 가진 필드와 메소드를 자식 객체에게 물려주어 자식 객체가 사용할 수 있도록 한다.
-> 코드의 재사용성을 높여줌. (중복 코딩을 하지 않을 수 있다.)
-> 유지 보수 시간을 최소화시켜 준다. (부모 객체으 필드와 메소드를 수정하면 모든 자식 객체들은 수정된 필드와 메소드를 사용 가능.)
3) 다형성 : 사용 방법은 동일하지만 실행 결과가 다양하게 나오는 성질을 말함. ex) 자동차의 부품을 교환하면 성능이 다르게 나오듯이 프로그램을 구성하는 객체(부품)를 바꾸면 프로그램의 실행 성능이 다르게 나올 수 있다. - 다형성 구현 위해서는 자동 타입 변환과 재정의 기술 필요, 상속과 인터페이스 구현 통해 얻어짐.
객체를 생성할 때 = 설계도 필요. 설계도 = 클래스 : 클래스로부터 생성된 객체를 해당 클래스의 '인스턴스'라고 명함. 클래스로부터 객체를 만드는 과정 = 인스턴스화. 동일한 클래스로부터 여러개의 인스턴스 제작 가능. 동일한 설계도로 여러개의 제품을 찍어내는 것과 동일함.
클래스 선언 = 객체 생성을 위한 설계도를 작성하는 작업. 생성자 = 객체 생성, 필드 = 객체가 가져야 할 데이터, 메소드 = 개체의 동작.
public class 클래스명{
}
public = 공개된 클래스 : 클래스 : 첫 글자 대문자. 카멜 표기법 사용.
이게 왜 중요하냐? -> 공개 클래스는 어느 위치에 있든 패키지와는 상관없이 바로 접근이 가능하다. 그래서 막 특별한이유가 없다면, 소스파일 하나당 클래스는 하나만 선언하자.
객체 생성 연산자 : new() :
new() 연산자는 객체를 힙 영역에 생성한 후, 그 객체의 주소를 리턴한다. 그 다음, 변수에 대입하여 우리가 그 값을 사용할 수 있도록 해주는 역할을 한다.
클래스의 역할 : 라이브러리 : 실행 불가하지만 다른 클래스에서 이용
실행 클래스 : main() 메소드를 가지고 있는, 실행 가능한 클래스
클래스 구성 : 클래스 선언 = 객체 초기화 역할을 담당하는 생성자, 객체에 포함될 필드, 메소드를 선언하는코드 포함. 생성자, 필드, 메소드 = 클래스 구성 멤버.
public class PlusMinus{
int Plus; -> 필드 : 객체의 데이터가 저장되는 곳
PlussMinus(){;} -> 생성자 : 객체 생성 시 초기화 역할을 담당함.
int methodPlus(){ -> 메소드 : 객체의 동작으로 호출 시 실행하는 블록.
}
}
필드 : 필드는 객체의 데이터를 저장함. 선언 형태 = 변수 선언과 흡사, 쓰임은 다름.
-> 객체의 데이터 = 고유 데이터, 현재 상태 데이터, 부품 데이터 : 자동차 객체 : 제작회사, 모델, 색깔, 최고 속도 = 고유 데이터. 현재 속도, 엔진 회전 수 = 상태 데이터. 차 본체, 엔진, 타이어 = 부품에 해당.
선언 = 반드시 클래스 블록에서 선언되어야.
초기값 제공 X -> 객체 생성 시 자동으로 기본값 초기화.
필드 사용 = 필드를 사용하는 것 = 필드값을 읽고 변경하는 것. 클래스에서 필드를 선언했다고 해서 바로 사용 가능한 건 아님. 필드 = 객체의 데이터 = 객체가 존재하지 않으면 필드도 존재 안 함. 클래스로부터 객체 생성 후, 필드 사용.
ex)
void method(){
Love myLove = new Love();
->Love 객체 생성
myLove.heart = 100; -> 닷 연산자로 점 찍어서 들고 오는 것 : heart라는 필드를 myLove라는 객체에서 들고 옴. = method라는 메소드인 외부!에서 필드 사용.
}
객체 내부 {
int heart;
Love(){
heart=100;
}
void method(){
heart = 100;
} -> 생성자와 메소드는 객체가 생성된 후 호출되므로, 내부에서 필드를 사용 가능함.
}
닷 연산자 : 객체가 가지고 있는 필드나 메소드에서 접근하고자 할 때 참조 변수뒤에 붙임.
생성자 : new 연산자 : 객체를 생성할 시, 초기화 역할 딱 그것만. 선언 형태는 메소드와 유사하긴 한데, 리턴 타입은 없고 이름 = 클래스 이름과 동일하게 선언
객체를 생성한 후 연이어 생성자를 호출해서 객체를 초기화하는 역할을 함. 필드 초기화를 하거나 메소들르 호출해서 객체를 사용할 준비를 함.
객체의 주소 리턴, 클래스 변수에 대입되어 객체의 필드나 메소드에 접근할 때 이용.
기본 생성자 = 하나 이상의 생성자를 모든 클래스가 가지기 가능. 컴파일러가 생성자 선언 없으면 기본 생성자를 자동으로 추가시켜줌.
생성자 선언 = 클래스(매매변수, ...) {
객체의 초기화 코드
}
-> 생성자 블록
생성자 = 메소드와 유사한 모양을 가짐, 다만 리턴 타입이 없고 클래스 이름과 동일. 매개 변수 = new 연산자로 생성자를 호출할 때 매개값을 생성자 블록 내부로 전달하는 역할.
필드 초기화 = 객체마다 동일한 값을 가지고 있다면 필드 선언 시 초기값을 대입하는 것이 좋다. 객체마다 다른 값을 가져야 한다면, 생성자에서 필드를 초기화하는 것이 좋음.
this 키워드 ; 매개변수명이 필드명과 동일하기 때문에 필드를 구분해주기 위해 this 키워드를 필드명 앞에 붙여줌. this = 현재 객체를 말함, this.name = 현재 객체의 데이터 (필드)로서의 name을 뜻함.
생성자 오버로딩 = 매개값으로 객체의 필드를 다양하게 초기화 = 생성자 오버로딩이 필요. 생성자 오버로딩 = 매개변수를 달리하는 생성자를 여러개 선언.
생성자 오버로딩 된 경우 = new 연산자로 생성자를 호출할 때 제공되는 매개값의 타입과 수에 따라 실행될 생성자가 결정.
생성자 오버로딩이 많아질 경우, 생성자 간의 중복 코드가 발생 가능. 매개변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자에서 중복 코드 많이 봄. 공통 코드를 한 생성자에서만 집중적 장성, 나머지는 this를 사용해서 공통 코드를 가지고 있는 생성자를 호출하는 법으로 개선.
메소드 : 객체가 수행할 기능, 동작. 함수라고 하기도 하지만 객체 내부의 함수 = 메소드. 객체와 객체간의 상호작용을 담당.
메소드 선언 = 객체의 동작을 실행 블록으로 정의. 메소드 호출 = 실행 블록을 실제로 실행.
리턴 타입 = 메소드 실행후 호출한 곳으로 전달하는 결과값의 타입. 리턴값이 없는 메소드 = void로 저장.
다만, 리턴 타입이 있다면 실행 블록 내부에서 return 문으로 리턴값 지정.
메소드 호출 = 메소드 블록 실행. 클래스에서 메소드를 선언했다고 바로 호출은 XX, 객체가 존재하지 않으면 메소드를 호출할 수 없다.
객체 내부 = 메소드명으로 호출, 객체 외부 = 닷 연산자, 참조 변수를 이용해 호출. 메소드가 리턴 값이 있을 시, 대입 연산자를 사용해 리턴값을 변수에 저장할 수 있음.
가변 길이 매개변수 = 매개변수의 개수에 맞게 매개값을 제공해야 함. 메소드가 가변길이 매개변수를 가지고 있다면 개수와 상관없이 매개값 줄 수 있음. (쉼표로 해서 제공)
매개값들은 자동으로 배열 항목으로 변환되어 메소드에서 사용. 메소드 호출 시 직접 배열을 매객밧으로 제공해도 됨.
return : 메소드의 실행을 강제 종료하고 호출한 곳으로 돌아간다는 의미. 메소드 선언에 리턴 타입이 있을 경우 = return문 뒤에 리턴값을 추가로 지정.
메소드 오버로딩 = 메소드 이름은 같되 매개변수의 타입, 개수, 순서가 다른 메소드를 여러개 선언.
목적 = 다양한 매개값을 처리하기 위해서.