-
9. 객체지향프로그램3개발자 수업/Java 2021. 10. 6. 18:47
1. 객체 자신을 가리키는 this
1) 인스턴스 자신의 메모리를 가리킴
2) this() : 생성자에서 또 다른 생성자를 호출할 때 사용
- 클래스에 생성자가 여러 개인 경우, this()를 이용하여 생성자에서 다른 생성자를 호출
- 생성자에서 다른 생성자를 호출하는 경우에는 인스턴스 생성이 미완성인 상태이므로 다른 수행문을 쓸 수 없음
3) 자신의 주소를 반환public class Person { private String name; private int age; public Person() { this("no name", 20); } public Person(String name, int age) { this.name = name; this.age = age; } public void showInfo() { System.out.println(this.name + " " + this.age); } public Person getPerson() { return this; } public static void main(String[] args) { Person person = new Person(); person.showInfo(); person.name = "이순신"; person.age = 30; person.showInfo(); Person person2 = person.getPerson(); System.out.println(person); System.out.println(person2); } }
2. 객체 간의 협력(collaboration)
1) OOP에서 협력
- 필요한 메세지를 전송하고 이를 처리하는 기능이 구현되어야 함- 매개변수로 객체가 전달되는 경우가 발생
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 showInfo() { System.out.println(busNumber + "번 버스의 승객은 " + passengerCount + "명 이고, 수익은 " + money + "원 입니다."); } }
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 showInfo() { System.out.println(lineNumber + "번 전철의 승객은 " + passengerCount + "명 이고, 수익은 " + money + "원 입니다."); } }
public class Taxi { String companyName; int money; public Taxi(String companyName) { this.companyName = companyName; } public void take(int money) { this.money += money; } public void showInfo() { System.out.println(companyName + " 택시 수입은 " + money +"원 입니다."); } }
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(1000); this.money -= 1000; } public void takeSubway(Subway subway) { subway.take(1500); this.money -= 1500; } public void takeTaxi(Taxi taxi) { taxi.take(10000); this.money -= 10000; } public void showInfo() { System.out.println(studentName + "의 남은 돈은 " + money + "원 입니다."); } }
/* * 최지만은 지각을 해서 택시를 타야했습니다. * 20000원을 갖고 있었는데 10000원을 택시비로 사용했습니다. * 택시는 '이젠운수' 회사 택시를 탔습니다. * * 출력 * 최지만의 남은 돈은 10000원입니다. * 이젠운수 택시 수입은 10000원입니다. */ public class CollaborationTest { public static void main(String[] args) { Student student1 = new Student("김광현", 5000); Student student2 = new Student("최지만", 20000); Bus bus1000 = new Bus(1000); Subway subwayGreen = new Subway(2); Taxi taxiEzen = new Taxi("이젠운수"); student1.showInfo(); bus1000.showInfo(); System.out.println(); student1.takeBus(bus1000); student1.showInfo(); bus1000.showInfo(); System.out.println("-------------------"); // student2.showInfo(); // subwayGreen.showInfo(); // System.out.println(); // // student2.takeSubway(subwayGreen); // student2.showInfo(); // subwayGreen.showInfo(); student2.showInfo(); taxiEzen.showInfo(); System.out.println(); student2.takeTaxi(taxiEzen); student2.showInfo(); taxiEzen.showInfo(); } }
3. 여러 인스턴스에서 공통으로 사용하는 변수를 선언 => static 변수
1) 공통으로 사용하는 변수 필요한 경우
- 여러 인스턴스가 공유하는 기준 값이 필요한 경우
- 학생마다 새로운 학번 생성
- 회사에서 사원이 입사할 때 새로운 사번이 필요한 경우
- 카드 회사에서 카드를 새로 발급할 때마다 새로운 카드 번호를 부여
2) 데이터 영역 메모리
- 공유
3) static 변수 선언과 사용하기
- 인스턴스가 생성될 때마다 만들어지는 변수가 아닌, 처음 프로그램이 로딩될 때 메모리를 할당받음
- 클래스 변수, 정적 변수라고도 함 <----> 인스턴스 변수
- 인스턴스 생성과 상관 없이 사용 가능하므로 클래스 이름으로 직접 참조
4) static 메서드 구현과 활용
- 클래스 메서드, 정적 메서드
- 클래스 이름으로 호출 가능
- 인스턴스 생성 전에 호출될 수 있으므로 static 메서드 내부에서는 인스턴스 변수를 사용할 수 없음/* * 1) static 변수와 메서드는 인스턴스 변수와 메서드가 아니므로 클래스 이름으로 직접 참조 * 2) static 변수는 인스턴스에서 공통으로 사용하는 영역임을 알 수 있음 */ public class Employee { // class variable private static int serialNum = 1000; // instance member variable private int employeeId; private String employeeName; private String department; public Employee() { serialNum++; this.employeeId = Employee.serialNum; } // class method public static int getSerialNum() { return serialNum; } public static void setSerialNum(int serialNum) { Employee.serialNum = 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("이순신"); Employee employeeLee2 = new Employee(); employeeLee2.setEmployeeName("이도"); System.out.println(employeeLee.getEmployeeName() + ", " + employeeLee.getEmployeeId()); System.out.println(employeeLee2.getEmployeeName() + ", " + employeeLee2.getEmployeeId()); System.out.println(Employee.getSerialNum()); Employee.setSerialNum(1003); System.out.println(Employee.getSerialNum()); } }
4. 변수의 유효 범위와 메모리
1) 변수의 유효 범위(scope)와 생성과 소멸(life cycle)은 각 변수의 종류마다 다름
2) 지역변수, 멤버변수, 클래스 변수는 유효범위와 life cycle, 사용하는 메모리도 다름
변수 유형 선언 위치 사용 범위 메모리 생성과 소멸
-------------------------------------------------------------------------------------------------------------------
지역변수 메서드 내부 메서드 내부 스택 함수가 호출될 때 생성되고
(local 함수가 끝나면 소멸됨
variable)
멤버변수 클래스 멤버 클래스 내부 힙 인스턴스가 생성될 때 힙에 생성되고
(instance 변수로 선언 GC가 메모리 수거할 때 소멸됨
variable)
static 변수 클래스 내부 클래스 내부 데이터 영역 프로그램이 처음 시작할 때 상수와 함께 생성되고
(class 프로그램이 끝나고 메모리를 해제할 때 소멸됨
variable)
3) static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로 너무 큰 메모리를 할당하는 것은 좋지 않음/* * 변수의 종류 선언위치 생성시기 * -------------------------------------------------------------------------------------- * 클래스, 정적(static) 변수 클래스 영역 클래스가 메모리에 올라갈 때(인스턴스 생성하지 않아도 사용 가능) * 인스턴스 변수 클래스 영역 무조건 new 연산자로 인스턴스 생성 시 * 지역 변수 메서드 영역 메서드가 호출될 때 생겨나고, 메서드 종료 시 소멸됨 * (초기화가 반드시 필요, static 변수 사용 못함) */ public class Card /* extends Object */ { // 인스턴스 변수 --- 반드시 인스턴스 생성해야 접근 가능 private String color; private String company; // static 변수 (=정적변수, 클래스변수, 공유변수) --- 인스턴스 생성 없이도 클래스명.static으로 접근 가능 static int width = 100; static int height = 50; // 인스턴스 메서드 public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } @Override public String toString() { // TODO Auto-generated method stub return "Card의 색상: " + this.getColor() + ", Card의 회사: " + this.getCompany() + ", 크기 : (" + Card.height + ", " + Card.width + ")"; } } public class CardTest { public static void main(String[] args) { Card card = new Card(); card.setColor("노랑"); card.setCompany("국민은행"); System.out.println(card); Card.height = 150; Card.width = 80; Card card2 = new Card(); card2.setColor("파랑"); card2.setCompany("농협"); System.out.println(card2); } }
public class Calculator { // 인스턴스 메서드 : new 연산자로 인스턴스를 생성해야지만 참조변수명.인스턴스메서드명 으로 접근가능 public int add(int x, int y) { double dresult = Calculator.divide(10.5, 11.7); System.out.println("인스턴스 메서드 내에서 static 메서드 호출 : " + dresult); return x + y; } // 인스턴스 메서드 public int substract(int x, int y) { return x - y; } // 정적(static) 메서드 : 인스턴스 생성없이 클래스명.정적메서드명 으로 접근가능 public static long multiply(long x, long y) { /* * static 메서드는 이미 메모리 상단에 올라가 있고 인스턴스 생성 없이 접근 가능해야 되는데 * 인스턴스가 생성되어야지만 사용가능한 add()의 경우는 호출할 수 없음 * 인스턴스가 언제 생성될지를 아무도 모르기 때문에 static 메서드 안에서는 인스턴스 메서드가 절대 오면 안 됨 */ // this.add(10,5); return x * y; } // 정적 메서드 public static double divide(double x, double y) { return x / y; } } public class CalcuratorTest { public static void main(String[] args) { Calculator cal = new Calculator(); // 인스턴스 메서드 호출 int addResult = cal.add(100, 200); System.out.println("인스턴스 메서드 add() 호출결과 : " + addResult); // static 메서드 호출 long mulResult = Calculator.multiply(100, 20); System.out.println("static 메서드 multiply() 호출결과 : " + mulResult); double divResult = Calculator.divide(100.2, 10.2); System.out.println("static 메서드 divResult() 호출결과 : " + divResult); } }
5. static 응용 -- 싱글톤 패턴(singleton pattern)
1) 싱글톤 패턴이란?
- 프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴
- static 변수, 메서드를 활용하여 구현할 수 있음
2) 싱글톤 만드는 방법
- 해당 클래스 자신의 타입으로 정적 멤버 선언과 생성
- 해당 클래스를 외부에서 new 연산자로 인스턴스 생성 못하게 생성자를 private으로 생성
- 정적 멤버의 주소를 공유하기 위해서 외부에서 호출할 수 있는 getInstance() 제공함
3) 싱글톤을 사용하는 이유
- 단 하나의 인스턴스만 생성을 원하고자 할 때 사용함
- ex) 사용자 환경설정(시간, 날짜정보), 커넥션 풀public class Company { // 외부에서 접근 못하도록 private 적용 private static Company instance = new Company(); // 기본 생성자 private Company() {} // 외부에서 호출할 수 있도록 getInstance() 제공 public static Company getInstance() { if(instance == null) { instance = new Company(); } return instance; } } import java.util.Calendar; import java.util.Date; public class CompanyTest { public static void main(String[] args) { Company company1 = Company.getInstance(); Company company2 = Company.getInstance(); Company company3 = Company.getInstance(); System.out.println(company1); System.out.println(company2); System.out.println(company3); // 결과 값이 다 똑같음 kr.co.ezenac.singleton.Company@73a28541 // Object 클래스의 equals() : 주소비교 if(company1.equals(company2)) { System.out.println("같은 객체입니다."); } else { System.out.println("다른 객체입니다."); } // 객체의 == 연산자 : 주소값 비교연산 if(company2==company3) { System.out.println("같은 객체입니다."); } else { System.out.println("다른 객체입니다."); } //Calendar calendar = new Calendar(); Calendar calendar = Calendar.getInstance(); Date date = calendar.getTime(); System.out.println(date); } }
'개발자 수업 > Java' 카테고리의 다른 글
11. 컬렉션 프레임워크 (0) 2021.10.07 10. 배열 (0) 2021.10.06 8. 객체지향프로그래밍2 (0) 2021.10.05 6. Review / 7.객체지향프로그램 (0) 2021.10.04 5. 반복문 (while문, do~while문, for문) (0) 2021.10.01