06.1 this 예약어
- 자신의 메모리를 가리키는 this
- 생성된 인스턴스 스스로를 가리키는 예약어
- 참조변수
- 인스턴스를 가리키는 변수
- 출력시 ‘클래스 이름@ 메모리 주소’
- 생성자에서 다른 생성자를 호출하는 this
class Person { int age; String name; boolean isMarried; int kidCount; public Person() { this(29, "이름없음"); //this로 Person(String , int) 생성자의 호출 } // 디폴트 생성자 public Person(int age, String name) { this.age = age; this.name = name; } //매개변수 2 public Person(int age, String name, boolean isMarried, int kidCount) { this.age = age; this.name = name; this.isMarried = isMarried; this.kidCount = kidCount; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + ", isMarried=" + isMarried + ", kidCount=" + kidCount + '}'; } }
- 디폴트 생성자가 호출되는 경우 초깃값 29 , “이름없음” 대입!
- this문장이 제일 먼저 와야함!
- 왜냐? > 클래스가 생성될 때 호출되므로 클래스 생성이 완료되지 않은 시점에 다른 코드가 있다면 오류가 발생할 수 있음
- 자신의 주소를 반환하는 this
class Person { String name; int age; public Person() { this("이름 없음", 1);//매개변수 2의 생성자를 호출합니다 } public Person(String name, int age) { this.name = name; this.age = age; } Person returnItSelf() { //반환형은 클래스형 return this; // this 를 반환합니다 } } class CallAnotherConst { public static void main(String[] args) { Person noName = new Person(); System.out.println("noName = " + noName.age); System.out.println("noName = " + noName.name); System.out.println("========================"); Person p = noName.returnItSelf(); //this값을 클래스변수에 대입합니다 System.out.println("p = " + p); // noName.returnIfSelf() 의 반환 값을 출력합니다 System.out.println("noName = " + noName); // 참조 변수 출력 } }
- 클래스 자료형과 상관없이 클래스내에서 this 를 사용시 자신의 주소 값을 반환할 수 있습니다.
- 06.2 객체 간 협력
- 학생 클래스 구현하기
class Student { public String studentName; //학생 이름 public int grade; // 학년 public int money; // 학생이 가진돈! public Student(String studentName, int money) { this.studentName = studentName; this.money = money; } public void takeBus(Bus bus) { bus.take(1000); //버스를 타면 1000원 지불하는 기능 this.money -= 1000; } public void takeSubway(Subway sub) { sub.take(1500); //지하철을 타면 1500원 지불하는 기능 this.money -= 1500; } public void showInfo() { System.out.println(studentName + "님의 남은 돈은" + money + "입니다"); } }
- 버스 클래스 구현
class Bus { int busNumber; //버스 번호 int passengerCount; //승객 수 int money; // 버스 수입 public Bus(int busNumber) { this.busNumber = busNumber; } //constructor public void take(int money) { this.money += money; //버스 수입 증가 passengerCount++; //승객수 증가 } public void showInfo() { System.out.println("Bus{" + "busNumber=" + busNumber + ", passengerCount=" + passengerCount + ", money=" + money + '}'); } }
- 지하철 클래스 구현
class Subway { String lineNumber; int passengerCount; int money; public Subway(String lineNumber) { this.lineNumber = lineNumber; } public void take(int money) { this.money += money; passengerCount++; } public void showInfo() { System.out.println("Subway{" + "lineNumber='" + lineNumber + '\'' + ", passengerCount=" + passengerCount + ", money=" + money + '}'); } }
- 학생, 버스, 지하철 객체 협력
- James 와 Tomas는 각각 버스와 지하철을 한번 씩 타고 집에갑니다!
class TakeTrans { public static void main(String[] args) { Student james = new Student("james", 5000); Student tomas = new Student("tomas", 10000); //학생 2명 생성 Bus bus100 = new Bus(100); //노선 번호가 100번인 버스를 생성합니다 james.takeBus(bus100); james.showInfo(); bus100.showInfo(); System.out.println("========================"); Subway subwayGreen = new Subway("2호선"); //노선 번호가 2호선인 지하철 생성 tomas.takeSubway(subwayGreen); //tomas가 2호선 tomas.showInfo(); subwayGreen.showInfo(); } }
- 두 개의 학생 인스턴스 생성!
- james 인스턴스에서 학생 이름은 James 가진돈 5000으로 초기화... TOMAS도 마찬가지!
- bus100 와 subwayGreen 객체 생성 후 메서드 실행!
class Taxi { int taxiNumber; int money; int passengerCount; public Taxi(int taxiNumber) { this.taxiNumber = taxiNumber; } public void takeTaxi(int money) { this.money += money; passengerCount++; } public void showInfo() { System.out.println("Taxi{" + "taxiNumber='" + taxiNumber + '\'' + ", money=" + money + ", passengerCount=" + passengerCount + '}'); } }
class TakeTrans { public static void main(String[] args) { Student james = new Student("james", 5000); Student tomas = new Student("tomas", 10000); Student edward = new Student("edward", 20000); //학생 2명 생성 Bus bus100 = new Bus(100); //노선 번호가 100번인 버스를 생성합니다 james.takeBus(bus100); james.showInfo(); bus100.showInfo(); System.out.println("========================"); Subway subwayGreen = new Subway("2호선"); //노선 번호가 2호선인 지하철 생성 tomas.takeSubway(subwayGreen); //tomas가 2호선 tomas.showInfo(); subwayGreen.showInfo(); Taxi taxi1010 = new Taxi(1010); edward.takeTaxi(taxi1010, 10000); edward.showInfo(); taxi1010.showInfo(); System.out.println("========================"); } }
- taxi 객체와 student 객체의 생성!
- 학생 클래스 구현하기
- 06.3 static 변수
- 변수를 여러 클래스에서 공통으로 사용하려면?
class Student { public int studentID; //학생 번호! public String studentName; //학생 이름 public int grade; // 학년 public int money; // 학생이 가진돈! public String address; //학생의 주소
- 학생마다의 고유한 학번 studentID...
- 입학하면 학번이 자동적으로 생성되도록 만들고 싶다!
- 각 인스턴스 마다 따로 생성되는 변수가 아닌 클래스 전반에서 공통으로 사용할 수 있는 기준 변수가 필요합니다!
- 학생 한 명 생성시 기준 변수 값을 증가! 인스턴스 학번 변수에 대입!
static변수
- 클래스에서 공통으로 사용하는 변수
- static 변수의 정의 사용 방법
- static 변수
- 정적 변수
- static(예약어) int(자료형) serialNum(변수이름)
- staic변수는 프로그램이 실행되어 메모리에 올라갔을 때 딱 한 번 메모리 공간이 할당
- 모든 인스턴스가 공유하는 값이 됩니다
클래스변수
라고도 부릅니다
- static변수 사용하기 예제
class Student { public static int serialNum; //static 변수는 인스턴스 생성과 상관없이 먼저 생성됩니다 public int studentID; //학생 번호! public String studentName; //학생 이름 public int grade; // 학년 public int money; // 학생이 가진돈! public String address; //학생의 주소
class StudentTest1 { public static void main(String[] args) { Student studentLee = new Student(); studentLee.setStudentName("이지원"); System.out.println("studentLee = " + studentLee.serialNum); studentLee.serialNum++; //static 변수 값의 증가 Student studentSon = new Student(); studentSon.setStudentName("손수경"); System.out.println("studentSon.serialNum = " + studentSon.serialNum); System.out.println("studentLee.serialNum = " + studentLee.serialNum); } }
- studentLee 생성 후 전체 인스턴스에서 공톹으로 사용하는 serialNum 변수 값을 1 증가
- studentSon 객체 생성
- studentSon Lee 모두 1001의 ID 값을 출력합니다
- static 변수 serialNum 변수는 모든 인스턴스가 공유
- 2개의 참조변수가 동일한 변수 메모리를 가리킵니다
일반 멤버 변수
- 인스턴스가 생성될 때마다 새로 생성되어 각각 다른 studentName을 가짐
static 선언 변수
- 인스턴스 생성과 상관없이 그 값을 모든 인스턴스가 공유하게 됩니다
클래스변수
라고도 부릅니다
- static 변수
- 학번 생성하기
- 학생 한 명 생성될 때마다 학번 자동부여
public Student() { serialNum++; studentID = serialNum; //증가된 값을 인스턴스 변수에 부여합니다 }
- 클래스 변수
- 인스턴스의 생성과는 별개이기에 인스턴스보다 먼저 생성
- staic 변수는 인스턴스와가 생성되지 않아도 사용가능하기에 Student.serialNum 과 같이 클래스 이름으로 함께 사용도 가능
- 클래스 메서드
- static변수를 위한 메서드
public class StudentTest4 { public static void main(String[] args) { Student2 student2 = new Student2(); student2.setStudentName("이지원"); System.out.println("student2.getStudentName() = " + student2.getStudentName()); System.out.println("student2.serialNum = " + Student2.getSerialNum()); System.out.println("student2.getStudentID() = " + student2.getStudentID()); Student2 student21 = new Student2(); student21.setStudentName("박상준"); System.out.println("Student2.getSerialNum() = " + Student2.getSerialNum()); System.out.println("student21.getStudentID() = " + student21.getStudentID()); } }
- 클래스 메서드와 인스턴스 변수
- 클래스 메서드 내부에서는 인스턴스 변수를 사용불가
public static int getSerialNum() { //static getter int i = 10; studentName = "박상준상박"; //불가능! return serialNum; }
- int i : 지역변수
- 메서드 호출시 메모리에 생성 > 메서드가 끝나면 사라짐
- studentName
- Student2 클래스의 멤버 변수, 인스턴스가 생성될 때 만들어지는 인스턴스 변수
- 인스턴스 생성되고나서 사용가능합니다!
- int i : 지역변수
- 클래스 메서드 내부에서는 인스턴스 변수를 사용불가
- 변수를 여러 클래스에서 공통으로 사용하려면?
06.4 변수 유효 범위
- 변수 유효 범위
- 지역 변수
- 함수나 메서드 안에서만 사용
- 멤버 변수
- 클래스 안에서 사용
- static 변수
- 여러 인스턴스에서 공통으로 사용
- 지역 변수의 유효 범위
- 함수나 메서드 내부에서만
- 스택
- 지역 변수가 생성되는 메모리
- 멤버 변수의 유효범위
- 힙 메모리
- 클래스 생성시 ...
- 클래스의 어느 메서드
- 힙 메모리
- static 변수의 유효 범위
- 프로그램 실행시 메모리에 프로그램이 상주
- 프로그램 영역중 DATA 영역 존재
- 상수, 문자열, static 변수
- 처음부터 데이터 영역 메모리에 생성
- private이 아니라면, 클래스 외부에서 사용가능
- 프로그램이 시작할 때 부터 끝날 때 까지 메모리에 상주하기에...
- 프로그램 실행시 메모리에 프로그램이 상주
- 지역 변수
06.5 static응용 - 싱글톤 패턴
- 싱글톤 패턴
- 인스턴스를 단 하나만 생성하는 디자인 패턴
- 디자인 패턴?
- 프로그램 특성에 따른 설계 유형을 이론화
- 싱글톤 패턴으로 회사 클래스 구현하기
- 생성자를 private으로 만들기
public class Company { private Company() { } }
- 생성자가 존재하지 않는 클래스는 컴파일러가 자동으로 디폴트 생성자 코드를 넣어 줍니다. 컴파일러가 만들어주는 디폴트 생성자는 항상 public
- 하지만, 싱글톤 → 접근제어자 private인 생성자 호출!
- 컴파일러가 디폴트 생성자 만들지 않습니다!
- 외부 클래스에서 마음대로 Company 인스턴스 생성 X
- Company 클래스 내부에서만 이 클래스의 생성을 제어가능
- 외부 클래스에서 마음대로 Company 인스턴스 생성 X
- 컴파일러가 디폴트 생성자 만들지 않습니다!
- 하지만, 싱글톤 → 접근제어자 private인 생성자 호출!
- 생성자가 존재하지 않는 클래스는 컴파일러가 자동으로 디폴트 생성자 코드를 넣어 줍니다. 컴파일러가 만들어주는 디폴트 생성자는 항상 public
- 클래스 내부에 static으로 유일한 인스턴스 생성
public class Company { private static Company instance = new Company(); //유일하게 생성한 인스턴스 private Company() { } }
- 외부에서 인스턴스를 생성 X → 프로그램에서 하나정도의 사용가능한 인스턴스는 필요
- Company내부에 인스턴스 하나 생성
- 해당 인스턴스는 프로그램 전체에서 사용할 유일한 인스턴스
- private으로 선언하여 외부에서 해당 인스턴스 접근 불가능 → 인스턴스 오류 방지
- Company내부에 인스턴스 하나 생성
- 외부에서 인스턴스를 생성 X → 프로그램에서 하나정도의 사용가능한 인스턴스는 필요
- 외부에서 참조할 수 있는 public 메서드 만들기
public static Company getInstance() { if (instance == null) { instance = new Company(); } return instance; //유일하게 생성하 인스턴스의 반환 } // 외부에서 참조할 수 있도록 public get() 메서드 구현
- private으로 선언한 유일한 인스턴스를 외부에서 사용가능하도록 getter 선언
- 인스턴스 반환 메서드는 static으로 선언!→ getInstance() 메서드는 인스턴스 생성과 관계없이 호출 할 수 있어야함
싱글톤 패턴으로 클래스 구현 연습
package kr.or.test; /* */ public class Company { private static Company instance = new Company(); //유일하게 생성한 인스턴스 private Company() { } public static Company getInstance() { if (instance == null) { instance = new Company(); } return instance; //유일하게 생성하 인스턴스의 반환 } // 외부에서 참조할 수 있도록 public get() 메서드 구현 } class CompanyTest { public static void main(String[] args) { Company myCompany1 = Company.getInstance(); Company myCompany2 = Company.getInstance(); //클래스 이름으로 getInstance() 호출하여 참조 변수에 대입합니다 System.out.println(myCompany1 == myCompany2); //두 변수가 같은 주소인지? } } class CarFactoryTest { public static void main(String[] args) { CarFactory factory = CarFactory.getInstance(); Car mySonata = factory.createCar(); Car yourSonata = factory.createCar(); System.out.println("mySonata.getCarNum() = " + mySonata.getCarNum()); System.out.println("yourSonata.getCarNum() = " + yourSonata.getCarNum()); System.out.println("========================"); } private static class CarFactory { private static CarFactory instance = new CarFactory(); private static CarFactory getInstance() { if (instance == null) { instance = new CarFactory(); } return instance; } public Car createCar() { return new Car(); } } private static class Car { private static int serialNum=10000; private int carNum; public Car() { serialNum++; this.carNum = serialNum; } public int getCarNum() { return carNum; } public void setCarNum(int carNum) { this.carNum = carNum; } } }
- 생성자를 private으로 만들기
- 클래스 내부에서 자신의 주소를 가리키는 예약어를
this
라고 합니다
- 클래스에 여러 생성자가 오버로드 되어 있을 경우에 하나의 생성자에서 다른 생성자를 호출할 때
this
를 사용합니다
- 클래스 내부에 선언하는 static 변수는 생성되는 인스턴스마다 만들어지는 것이 아닌 여러 인스턴스가 공유하는 변수입니다. 따라서 클래스에 기반한 유일한 변수라는 의미로
클래스변수
라고도 합니다
- 지역 변수는 함수나 메서드 내부에서만 사용할 수 있고
스택
메모리에 생성됩니다. 멤버 변수 중 static예약어를 사용하는 static데이터영역
메모리에 생성됩니다
- 김씨 4_000 지불. 아메리카노. 콩다방 4500 라테. 객체지향
public class Test { public static void main(String[] args) { Cafe cafe1 = new Cafe("별다방"); Cafe cafe2 = new Cafe("콩다방"); Person kim = new Person("김씨", 100000); kim.buyCoffee(cafe1, "아메리카노"); kim.buyCoffee(cafe2, "라테"); System.out.println("kim = " + kim); } } class Person { String name; int money; public Person(String name, int money) { this.name = name; this.money = money; } public void buyCoffee(Cafe cafe, String menu) { if (cafe.getCafeName() .equals("별다방") && menu.equals("아메리카노")) { cafe.setMoney(cafe.getMoney() + 4000); this.money -= 4000; } else if (cafe.getCafeName() .equals("콩다방") && menu.equals("라테")) { cafe.setMoney(cafe.getMoney() + 4500); this.money -= 4500; } } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", money=" + money + '}'; } } class Cafe { private String cafeName; private int money; public Cafe(String cafeName) { this(cafeName, 10000); } public Cafe(String cafeName, int money) { this.cafeName = cafeName; this.money = money; } public String getCafeName() { return cafeName; } public void setCafeName(String cafeName) { this.cafeName = cafeName; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } } class 별다방 extends Cafe { public 별다방() { super("별다방"); } } class 콩다방 extends Cafe { public 콩다방() { super("콩다방"); } }
-
Uploaded by Notion2Tistory v1.1.0