: 반 (뭔가가 모여있다) => 공통요소로 묶자!
클래스 선언
class 클래스명{ 필드(변수, 메서드) }
클래스 사용
클래스명 객체명 = new 클래스명(); 객체명.필드;
'.' : 하위 연산자 (A.b : A안에 b)
- '객체명'이라는 이름으로 저장공간이 하나 만들어지고 그 안에는 heap메모리에 들어가있는 필드들의 주소값이 들어가있다고 생각하자.
- 접근할 때 자동으로 클래스에 그 객체에 주소값이 넘어간다고 머릿속에 저장!!
밑에 사진을 참고해서 생각해보자.
절자지향 언어와 객체지향 언어의 차이점을 빵으로 이해해보자.
절차지향(C언어)
빵 반죽 => 발효 => 굽기 => 포장 => 판매
- 즉, 전에 있는 로직이 끝나기 전에 다음이 진행이 안됨.
- 자료구조,알고리즘에 특화되어있다.
- 자료구조를 만드는데 목적을 가진다.
- 이런 작업들을 딱 1명이 한다.
객체지향(Java, Python)
- 만들어진 자료구조를 사용하는데 목적을 가진다.
그 전에 썼던 사람(판매,굽기...)을 고용할 수 있다.
- 반죽 class, 발효 class... 전부 각각의 클래스로 만들 수 있다.
- 한번 만들어 놓은 것을 불러오기만 하면 된다.
추상적인 개념을 실체화 시킨것!
ex) 도형을 클래스명(클래스)로 쓰고 세모,네모,동그리미들을 객체라고함.
=> 추상적인 개념을 실체화하는 것을 클래스의 객체화라고 한다.
예를 들어 개념정리를 해보자.
-> 엄마차 아빠차 내차가 있다고 가정해보자.
자동차의 공통 요소는 ' 가격, 브랜드, 색깔 '이 있다.
3 * 3 = 9, 즉, 9개의 변수를 만든다..?
momCar_price, dadyCar_price.... 너무많다!
그래서!
자동차의 공통 요소를 만들어 놓고
엄마차, 아빠차, 내차를 자동차 타입으로 선언해 놓자.
이게 무슨말인고 하니..
Car class에 price, color, brand 변수 선언한다. (= 공통요소를 한번씩만 선언)
Car.momcar ( = momcar를 Car type(자동차 타입)으로 사용하자)
=> momcar(객체)로 Car클래스 안에있는 변수에 접근할 수 있다.
클래스 선언을 해보며 받아들여보자.
Car momcar = new Car();
(stack영역) (생성자)
new는 momcar를 실체화 시켜주는 애.
즉 생성자 라고 한다.
stack 영역에는 momcar가 존재.
momcar는 지역변수. (momcar라는 저장공간이 stack영역에 생긴다.)
해당 주소값에 대한 값을 가진다.
heap 메모리 영역에 Car type 안에는 price, color, brand(필드)가 있다.
price, color, brand의 주소값을 담고 있는것 = momcar
heap에는 주소값만 있다.
cf) 클래스안에 있는 애들을 필드라고함.
내부적으로는 momcar, dadycar가
price, color, brand애들을 각각 따로따로 가지고 있다..!
그런데,,
momcar.price라고 값을 불러오고 싶다면
Car class는 이 price가 momcar인지 dadycar인지 어떻게 구분 할까?
- momcar가지고 있는 주소값이 Car class로 자동으로 넘어간다.
- Car class에서는 누구의 차든 각각 구분을 할 수 있다.
- 왜냐면 객체는 한개가 아니기 때문이다.
cf)
=> 어느 it커뮤니티에서 클래스는 무엇인가요? 란 질문에 달린 답변 두 가지.
1. 타입이다.
2. 주어이다. ( 영어 주어는 항상 대문자임)
Monkey.eat(바나나)
주어 동사 목적,보어
메서드명을 동사로 쓰는 이유가 여기서 파생됨.
추상적인 개념을 실체화 시킨다.
클래스로 접근하지 않고,
클래스타입의 객체를 만들어서 그 객체로 접근한다.
new car을 했기 때문에 car class를 momCar라고 실체화시킴.
momCar : 인스턴스(실체화) 변수
인스턴스 : 예시 예시를 설명하면 모두가 이거에 대해 알게됨 공포하는것
즉 인스턴스변수로 설정하면 모두가 momCar라는걸 알게됨
== 실체화를 시킨 것! Car가아니라 momCar예요!
클래스명()
초기화의 목적이 있다.
메서드와 같은 기능을 가지고 있지만, 리턴이 없으며,
리턴타입도 없다. 따라서 메서드라고 부르지 않는다.
< main부분 >
Car momCar = new Car();
↑기본 생성자라고 한다.
Car momCar = new Car(9000,"Black","Benz");
-> 사용하는 부분이기 때문에 값을 3개 넘겨줘야함.
Car dadyCar = new Car();
Car myCar = new Car();
이렇게 저장공간3개 생겼다면, 각 저장공간에 각기 다른 필드가 생김.
각각 초기화를 해줘야 함.
그런데 초기화를 9번이나 해야하는가?
=> 쉽게 하기위한것 : 생성자!
생성자는 new Car(); new뒤에 클래스 이름과 똑같은애
Car( )는 메서드 생성자는 메서드가 아니지만 메서드 기능과 똑같다.
다만 리턴타입이 없는 메서드라고 생각하자.
< Class부분 >
Car() {}
매개변수의 아얘 없을때 해당 기본 생성자로 들어가게 된다.
오버로딩을 통해서 내가 초기화할 변수의 갯수도 정할수있고
아얘 초기화를 안하게끔 기본생성자를 우리가 만들 수도 있다.
그냥 선언만할건데 값넣으라고 오류가 뜰 수도있으니 꼭 함께 만들기
< 기본생성자 생성방법 >
=> Alt + Shift + S + O
Select fields to initialize : 초기화 할 필드를 선택해라
이름을 같게 해도 구분점이 생긴다.
임의로 생성자를 만들면 이게 기본생성자가 된다.
Car(int price, String color, String brand){ this.price = price; // ↑전역변수 ↑지역변수 price // 그 객체의 프라이스. 뜻 // this : 객체주소를 자동으로 받는 애 this.color = color; this.brand = brand; }
this.price = price;
그 객체의 price. 외부에서 받은 값을 초기화한다.
price, color만 초기화하고싶다면...
==> 그래서 메서드에서 오버로딩이란걸 배운다.