생성자 (constructor)
heap에 인스턴스 메모리 생성
생성자
• 생성자 기본 문법 <class_name>([<argument_list]) { [<statements] }
• 객체를 생성할 때 new 키워드와 함께 사용 - new Student();
• 생성자는 일반 함수처럼 기능을 호출하는 것이 아니고 객체를 생성하기 위해 new 와 함께 호출 됨
• 객체가 생성될 때 변수나 상수를 초기화 하거나 다른 초기화 기능을 수행하는 메서드를 호출 함
• 생성자는 반환 값이 없고, 클래스의 이름과 동일
• 대부분의 생성자는 외부에서 접근 가능하지만, 필요에 의해 private 으로 선언되는 경우도 있음
기본 생성자 (default constructor)
• 클래스에는 반드시 적어도 하나 이상의 생성자가 존재
• 클래스에 생성자를 구현하지 않아도 new 키워드와 함께 생성자를 호출할 수 있음
• 클래스에 생성자가 하나도 없는 경우 컴파일러가 생성자 코드를 넣어 줌 = public Student(){}
• 매개 변수가 없음, 구현부가 없음
초기화 과정을 하기위해 생성자 사용시 () {} 값 넣음
ex)
package ch06; ㅤ public class Student { ㅤ public int studentNumber; public String studentName; public int grade; ㅤ public Student() {} // 생성자 overloading ㅤ public Student(int studentNumber, String studentName, int grade) { this.studentNumber = studentNumer; // this 붙여주기!, this는 public가져왔고 오른쪽은 매개변수 & 이름 같게하는게 좋음 this.studentName = studentName; this.grade = grade; } ㅤ public String showStudentInfo(); ㅤ return studentName + “학생의 학번과 학년은” + studentNumber + grade + “입니다.” } -> 얘는 메인 아님메인으로 클래스 생성
public class StudentTest { ㅤ public static void main(String[] args) { ㅤ Student studentLee = new Student(); studentLee.studentID = 54321; studentLee.setStudentName(“Kim”); studentLee.address = “경기도 성남시”; system.out.println(studentLee.showStudentInfo()); // 멤버변수는 초기화, string은 null값, int는 0
OR
Student studentKim = new Student(12345, “kim”, 3); System.out.println(studentKim.showStudentInfo()); } *멤버변수만 가능! 지역변수는 호출될 때 초기화가 안 됨
클라이언트 코드 : 서비스를 사용하는 쪽 모듈 & 객체를 가져다 쓰는 쪽
서비스 코드 : 서비스 제공하는 객체 모듈
default 생성자 안되게 설정할 수도 있음
생성자 오버로딩 (overloading)
참조 자료형 변수
변수의 자료형
1) 기본 자료형 : int, long, float, double
2) 참조 자료형 : String, Date, Student // 생성해서 사용
*String은 예외
참조 자료형 정의하여 사용하기
ex)
package ch09; ㅤ public class Student { int studentID; String studentName; ㅤ Subject Korea; Subject math; ㅤ Student (int studentId, String StudentName) { this. studentId = studentId; this. studentName = studentName; ㅤ korea = new Subject(); math = new Subject(); } ㅤ public void setKoreaSubjecct(String name, int score) { ㅤ korea.subjectName = name; korea.score = score; ㅤ} ㅤ public void setMathSubject(String name, int score) { ㅤ math.subjectName = name; mat.score = score; } ㅤ public void showScoreInfo() { int total = korea.score + math.score; System.out.println(studentName + “학생의 총점은” + total + “점입니다.”) } }package ch09: ㅤ public class SubjectTest { ㅤ public static void main(String[] args) { student studentLee = new Student(100, “Lee”) studentLee.setKoreaSubject(“국어”, 100); studentLee.setMathsubject(“수학”, 99); studentLee.showScoreInfo(); }
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ
접근 제어 지시자 (accesss modifier)
private : 같은 클래스 내부에서만 접근 가능 ( 외부 클래스, 상속-상위하위- 관계의 클래스에서도 접근 불가)
default (아무것도 X) : 같은 패키지 내부에서만 접근 가능 ( 상속 관계라도 패키지가 다르면 접근 불가) 다른 패키지인 경우 import 하여 사용
protected : 같은 패키지나 상속관계의 클래스에서 접근 가능하고 그 외 외부에서는 접근 할 수 없음
public : 클래스의 외부 어디서나 접근 할 수 있음
get()/ set() 메서드
SET과 GET의 차이점
set = 설정, get = 값을 가져오는 것 ㅤ User-id 라는 변수를 선언을 한다고 가정했을 때, User-id의 변수에 어떠한 값(ID)에 저장(set)을 한다. ㅤ User-id 에 저장된 값을 불러오는 것이 get이다. ㅤ 쉽게 설명하면, ㅤ 돼지저금통을 만든다 > 변수 선언 ㅤ 그 안에 돈을 저축한다 > set ㅤ 그 안에 돈이 얼마나 들어 있는지 본다 > getSET과 GET 사용이유
결국에는, SET, GET 메소드를 사용하는 이유는 외부로부터 변수값에 직접적으로 접근하는것을 막기 위해서다. 직접 접근하개 되면 값이 변하게 되고 그러면 데이터 무결성이 깨질 수 있기 때문이다. ㅤ 대표적으로 자바에서는 함수를 통해 값을 전달받고, 전달하고 방식을 권장하고 있다. ㅤ 또한 클래스 내에서 변수 private(캡슐화, 정보은닉)를 선언해서 외부에서 접근할 수 없도록 한다.출처 : https://akdl911215.tistory.com/261
정보 은닉(infomation hiding)
public void setMonth(int month) { ㅤ if ( month < 1 || month > 12) { isValid = false; } else { this.month = month; } }
• 객체 지향 프로그램에서 정보 은닉은 필요한 외부에서 접근 가능한 최소한의 정보를 오픈함으로써 객체의 오류를 방지하 클라이언트 객체가 더 효율적으로 객체를 활용할 수 있도록 해준다.
ex)
package ch10; ㅤ public class Birthday { ㅤ private int day; //초기값 0 private int month; private int year; ㅤ private boolean isValid; // 초기값 false ㅤ public int getDay() { return day; } ㅤ public void setDay(int day) { ㅤ if (day <1 || day >30) { isValid = false; } else { isValid = true; this.day = day } ㅤ public int getMonth() { return month; } ㅤ public void setMonth(int day) { ㅤ if (month <1 || month >12) { isValid = false; } else { isValid = true; this.day = day } } public int getYear() { return Year; } ㅤ public void setYear(int day) { this.year = year } ㅤ //get set : 마우스 오른쪽 + source + generate getters and setters ㅤ public void showDate() { if (isVlaid) { System.out.println( year + “년” + month + “월” + day + “일 입니다.”); } else { System.out.println(“유효하지 않은 날짜입나디.”); } }package ch10; ㅤ public class BirthdayTest { ㅤ public static void main (Stirng[] args) { Birthday date = new BirthDay(); date.setYear(2019); date.setMonth(13); date.setDay(30); } }
private의 경우 메소드 쪽에 (get set 함수 쪽) 제한을 걸면서 오류를 방지할 수 있음
-> 외부에서 해당 값에 접근할 수 없음.
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ
캡슐화 (encapsulation)
정보 은닉을 활용한 캡슐화
-> 일관된 하나의 공개된 메서드(함수)에만 접근하도록 하는 것
레포트 만들기 예제
public class MakeReport { ㅤ StringBuffer buffer = new StringBuffer(); ㅤ private String line = "===========================================\n"; private String title = " 이름\t 주소 \t\t 전화번호 \n"; ㅤ private void makeHeader() { buffer.append(line); buffer.append(title); buffer.append(line); } ㅤ private void generateBody() { buffer.append("James \t"); buffer.append("Seoul Korea \t"); buffer.append("010-2222-3333\n"); ㅤ buffer.append("Tomas \t"); buffer.append("NewYork US \t"); buffer.append("010-7777-0987\n"); } ㅤㅤ private void makeFooter() { buffer.append(line); } ㅤ public String getReport() { makeHeader(); generateBody(); makeFooter(); return buffer.toString(); } }public class TestReprt { ㅤ public static void main(String[] args) { ㅤ MakeReport report = new MakeReport(); String builder = report.getReport(); ㅤ System.out.println(builder); } ㅤ }
StringBuffer
this가 하는 일
생성자에서 다른 생성자를 호출 하는 this
public class Person { ㅤㅤ String name; int age; ㅤㅤ public Person () { this (“이름없음”, 1); // 아직 인스턴스 생성된 것이 아니기 때문에 이전에 다른 코드 쓸 수 없음 } ㅤㅤ public Person(String name, int age) { this.name = name; this.age = age; }ㅤ }
자신의 주소를 반환하는 this
public class Person { ㅤ String name; int age; ㅤ public Person() { this("이름없음", 1); } ㅤ public Person(String name, int age) { this.name = name; this.age = age; } ㅤ public Person getPerson() { return this; } ㅤ public static void main(String[] args) { Person p = new Person(); p.name = "James"; p.age = 37; ㅤ Person p2 = p.getPerson(); System.out.println(p); System.out.println(p2); } }[this] - 클래스에 생성자가 여러 개인 경우, this를 이용하여 생성자에서 다른 생성자를 호출할 수 있음 - 생성자에서 다른 생성자를 호출하는 경우, 인스턴스의 생성이 완전하지 않은 상태이므로 this() statement 이전에 다른 statement를 쓸 수 없음
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ
Student
package ch14; ㅤ public class Student { String studentName; int money; ㅤ public Student(String studentName, int money) { this.studentName = studentName; this.money = money; } ㅤ public void takeBus(Bus bus) { bus.take(1)0; this.moeney -= 1000; } ㅤ public void takesubway (Subway subway) { subway.take(1200); this.money -= 1200; } ㅤ public void showBusInfo() { System.out.println(busNumber + "번 버스의 승객은 " + passengerCount + "명 이고, 수입은 " + money + "원 입니다"); }Bus
public class Bus { int busNumber; int passengerCount; int money; ㅤ public Bus(int busNumber) } this. busNumber = busNumber; } ㅤ public void take(int money) { this.money += money; passengerCount++; } ㅤㅤ public void showBusinfo() { System.out.println(lineNumber + "번 버스의 승객은 " + passengerCount + "명 이고, 수입은 " + money + "원 입니다"); } }Subway
public class Subway { ㅤㅤ int lineNumber; int passengerCount; int money; ㅤ public Subway(int lineNumber) { this.lineNumber = lineNumber; } ㅤㅤ public void take(int money) { this.money += money; passengerCount++; } ㅤㅤㅤ public void showSubwayInfo() { System.out.println(lineNumber + "번 지하철의 승객은 " + passengerCount + "명 이고, 수입은 " + money + "원 입니다"); } }Take
public class TakeTransTest { ㅤ public static void main(String[] args) { Student studentJ = new Student("James", 5000); Student studentT = new Student("Tomas", 10000); ㅤ Bus bus100 = new Bus(100); ㅤ Subway subwayGreen = new Subway(2); ㅤ studentJ.takeBus(bus100); studentT.takeSubway(subwayGreen); ㅤ studentJ.showInfo(); studentT.showInfo(); ㅤ bus100.showBusInfo(); ㅤ subwayGreen.showSubwayInfo(); } ㅤ }
공통으로 사용하는 변수가 필요한 경우
• 여러 인스턴스가 공유하는 기준 값이 필요한 경우
• 학생마다 새로운 학번 생성
• 카드회사에서 카드를 새로 발급할때마다 새로운 카드 번호를 부여
• 회사에 사원이 입사할때 마다 새로운 사번이 필요한
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ
static 변수
동일한 클래스에서 생성된 여러 인스턴스 공유
static 변수 선언과 사용하기
static int serialNum;
• 인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당
• 클래스 변수, 정적변수라고도 함(vs. 인스턴스 변수)
• 인스턴스 생성과 상관 없이 사용 가능하므로 클래스 이름으로 직접 참조
과정
프로그램을 구동시키면 프로그램이 메모리에 올라가는데, 메모리에 올라간 상태 = 프로세스 (thread상태로 돌아감)메모리 올라갈 때 두가지 영역
데이터 영역 처음부터 메모리 잡음 (상수, 리터럴, static) -> 프로세스 로딩되는 순간 데이터 영역에 잡히고, 프로그램이 다 끝나서 메모리에서 unload되는 순간 없어짐 ㅤ 코드 영역 명령어집합 ㅤ 인스턴스가 생성될때마다 메모리 할당 – heap (동적) GC (garbage collector) 에 의해 제거
ex)
public class Employee { ㅤㅤ public static int serialNum = 1000; ㅤㅤ private int employeeId; private String employeeName; private String department; ㅤ public Employee() // default 생성자 { serialNum++; employeeId = serialNum; } ㅤ public int getEmployeeId() { return employeeId; } public void setEmployeeId(int employeeId) { this.employeeId = employeeId; } public String getEmployeeName() { return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } ㅤ }public class EmployeeTest { ㅤ public static void main(String[] args) { Employee employeeLee = new Employee(); employeeLee.setEmployeeName("이순신"); System.out.println(employeeLee.serialNum); ㅤ Employee employeeKim = new Employee(); employeeKim.setEmployeeName("김유신"); employeeKim.serialNum++; ㅤ System.out.println(employeeLee.serialNum); System.out.println(employeeKim.serialNum); ㅤ } }
참고) 인스턴스와 상관없이 사용 가능하기 때문에 class이름으로 참조해서 사용가능
-> System.out.println(employee.serialNum);
static 메서드
private static int serialNum = 1000; ㅤ public static int getSerialNum() { return serialNum; } ㅤ public static void setSerialNum(int serialNum) { Employee.serialNum = serialNum; } ㅤ System.out.println(Employee.getSerialNum());
static 메서드(클래스 메서드)에서는 인스턴스 변수를 사용할 수 없다
Employee.java
public static void setSerialNum(int serialNum) { int i = 0; ㅤ employeeName = "Lee"; //오류발생 (만약 다른 곳에서 호출할 때 인스턴스가 생성되어있지 않을 수도 있을 수 있는데, static 메서드는 인스턴스 유무와 상관없이 호출될 수 있어야하기 때문 ㅤ Employee.serialNum = serialNum; }EmployeeTest2.java
public class EmployeeTest2 { ㅤㅤ public static void main(String[] args) { ㅤ System.out.println(Employee.getSerialNum()); Employee.setSerialNum(1003); System.out.println(Employee.getSerialNum()); ㅤ } }
변수의 유효 범위와 메모리

싱글톤 패턴이란?
public static Company getInstance() { ㅤ if( instance == null) { instance = new Company(); } return instance; ㅤ }CompanyTest.java
public class CompanyTest { ㅤ public static void main(String[] args) { Company company1 = Company.getInstance(); ㅤ Company company2 = Company.getInstance(); ㅤ System.out.println(company1); System.out.println(company2); ㅤ //Calendar calendar = Calendar.getInstance(); } }
본 게시글은 fastcampus 박은종강사 수업을 듣고 개인적으로 정리한 내용임을 밝힘.