클래스는 설계도
이다.
클래스(설계도)를 사용해서 실제 메모리에 만들어진 실체를객체,인스턴스
라고 한다.
//선언한 순간 Student는 메모리에 올라간다(X). 메모리에 올라가지는 않고, 인스턴스가 생성되면 메모리에 올라간다.(O) //클래스(설계도)를 사용해서 실제 메모리에 만들어진 실체를 객체,인스턴스라고 한다.
// Student = 설계도 : 그저, 하나의 파일이라고 생각? : (붕어빵틀)
Student student1; // 객체생성은 아님. car라는 참조 변수가 메모리 영역 stack이라는 영역에 만들어지는 단계
student1 = new Student(); // 실체 : 메모리에 올라온 객체 (팥붕 하이)
// new 연산자를 통해 메모리 내에 공간을 할당받고, 메모리 주소값(참조값)을 반환한다. -> 생성된 객체를 참조할 수 있는 참조값을 car에 담는다.
// 메모리를 할당 받는다는 것은 heap 영역에 저장된다는 것이다.
// heap영역은 생성된 객체들이 GC에 의해 자동 소멸되어지는 공간이다.
new 연산자는 객체를 Heap이라는 메모리 영역에 메모리 공간을 할당해주고 메모리주소를 반환한 후 생성자를 실행시켜준다
[참고] https://yoo11052.tistory.com/52
멤버변수
, 혹은필드
라고 칭한다.
클래스에 소속된 변수를 뜻한다.
Student student1 = new Student(); //x001
student1.name = "학생1";
student1.age = 15;
student1.grade = 90;
Student student2 = new Student(); //x002
student2.name = "학생2";
student2.age = 16;
student2.grade = 80;
Student[] students = new Student[2]; //x005
// ✔ 자바에서 대입은 항상 변수에 들어 있는 값을 복사한다!
// 각 student 변수에는 뭐가 들어있었을까? ("값"이 아닌 "주솟값"을 복사한다는 점을 생각해보자!)
students[0] = student1; //x005[x001][x002] 라고 생각
students[1] = student2;
students[0].name="해킹";
System.out.println(student1.name); // 출력 값 : 해킹
- 기본형(Primitive Type):
int
,long
,double
,boolean
처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형이라 한다.- 참조형(Reference Type):
Student student1
,int[] students
와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형이라 한다. 참조형은 객체 또는 배열에 사용된다.
int a = 10;
int b = a;
-> 리터럴 값이 복사되어 a가 변경되어도 b에는 영향이 없다. (다른 건물)
Student s1 = new Student();
Student s2 = s1;
-> 주소 값이 복사되어 a가 변경되면 b도 변경된다. (같은 건물)
Data data = null; System.out.println(data); data = new Data(); System.out.println(data); data = null; // GC의 효과 발생 ! 앞선 Data 인스턴스를 참조하는게 아무것도 없음 System.out.println(data);
절차 지향 프로그래밍
- 절차. 즉 실행 순서를 지향한다. ("어떻게"를 중심으로 해결할 지 프로그래밍)
- 하나의 흐름대로 처리하는 방식
객체 지향 프로그래밍
- 객체. 즉 어떠한 사물이나 사건을 지향한다. ("무엇을"중심으로 해결할 지 프로그래밍)
- 객체를 중심으로 바라보다보니 서로간의 상호작용을 중요시 함.
가장 큰 차이
- 데이터 처리 방식 : 변수(데이터)와 기능(함수)를 분리하는지 여부이다.
-> 절차지향 : 데이터와 기능을 분리시켜 사용한다.
-> 객체지향 : 객체 안에 기능을 포함해서 사용한다.
그러나
static
이 붙으면 객체를 생성하지 않고도 메서드를 호출 할 수 있다.
속성과 기능을 하나로 묶어서 필요한 기능을 메서드를 통해 외부에 제공하는 것
MusicPlayer player = new MusicPlayer(); //음악 플레이어 켜기 player.on(); //볼륨 증가 player.volumeUp(); //볼륨 증가 player.volumeUp(); //볼륨 감소 player.volumeDown(); //음악 플레이어 상태 player.showStatus(); //음악 플레이어 끄기 player.off();
MemberInit 클래스
public class MemberInit { String name; int age; int grade; }
절차지향 코드1 (모듈화 X)
다음은 절차지향에서 사용했던 생성자이다.
public static void main(String[] args) { MemberInit member1 = new MemberInit(); member1.name = "user1"; member1.age = 15; member1.grade = 90; MemberInit member2 = new MemberInit(); member2.name = "user2"; member2.age = 16; member2.grade = 80; MemberInit[] members = {member1,member2}; } }
절차지향 코드2 (모듈화 O)
위 과정에서 메서드를 추출한 방법이다. 여전히 모듈화를 사용했으나, 객체지향적이지는 못하다.
MemberInit member1 = new MemberInit(); initMemeber(member1, "user1", 15,90); MemberInit member2 = new MemberInit(); initMemeber(member2, "user2", 16,80); MemberInit[] members = {member1,member2}; } } static void initMemeber(MemberInit member, String name, int age, int grade){ member.name = name; member.age = age; member.grade = grade; }
클래스 내에 메서드 넣기
클래스 내에 메서드를 넣어줌으로서 객체지향적인 코드가 완성되었다!
public class MemberInit { String name; int age; int grade; //this : 자기 자신(인스턴스)의 참조값을 가리킨다 x001.name //같은 변수이름이면 코드블럭의 우선순위는 매개변수가 갖게 된다. void initMember(String name, int age, int grade){ this.name = name; this.age = age; this.grade = grade; } }
객체지향 코드1
MemberInit member1 = new MemberInit(); member1.initMember("user1", 15,90); MemberInit member2 = new MemberInit(); member2.initMember("user2", 16,80); MemberInit[] members = {member1,member2};
프로그래밍을 하다보면 객체를 생성하고 그 즉시 초기값을 할당해야 하는 경우가 많다.
따라서 객체 지향 언어는객체를 생성 하자마자 즉시 필요한 "기능"을 수행
할 수 있도록생성자
라는 기능을 제공한다.생성자는 메서드와 비슷하지만 다음과 같은 차이가 있다.
- 생성자의 이름은 클래스
이름과 같아야 한다
. 따라서첫 글자도 대문자
로 시작!- 생성자는
반환 타입이 없다
!그 외에는 메서드와 같은 기능
을 한다.
생성자가
하나도 없으면
자바 컴파일러
는매개변수도, 어떠한 기능도 없는 기본 생성자
를 자동으로 만들어준다.but 생성자가
하나라도 있으면
기본 생성자를 만들지 않는다.
생성자를 정의했다면,
정의한 생성자를 "반드시" 호출 해야한다
는제약사항
이 생긴다.
-> 생성자를 사용하면 필수값 입력을 보장할 수 있다.만일 생성자를 직접 정의했는데, 호출하지 않으면
컴파일 에러
가 발생한다.📌
좋은 프로그램
은 무한한 자유도가 주어진 프로그램이 아니라적절한 제약사항이 주어진 프로그램
이다
아래와 같이 생성자도 매개변수에 따라 오버로딩이 가능하다!
public class MemberConstruct { String name; int age; int grade; MemberConstruct(String name, int age, int grade){ System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade); this.name = name; this.age = age; this.grade = grade; } MemberConstruct(String name, int age){ this.name = name; this.age = age; this.grade = 50; }
근데 여기서 this.name, this.age 와 같이 중복되는 코드를 지우고 싶으면 어떻게 해야할까?
this()
this() 기능으로 위와같은 기능을 수행할 수 있다.
- this() 는
생성자 내부
에서만 사용 가능하다.- this() 는 생성자 블록
첫 줄
에서만 가능하다. (아니면 컴파일 오류)MemberConstruct(String name, int age, int grade){ System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade); this.name = name; this.age = age; this.grade = grade; } MemberConstruct(String name, int age){ this(name,age,50); //변경 : 중복제거 // this.name = name; // this.age = age; // this.grade = 50; }