[Java] 자바 프로그래밍 - 06 객체지향프로그래밍 - 02

Dev_Honey·2022년 12월 9일
0

JAVA

목록 보기
7/8
post-thumbnail

1. this

자신의 메모리를 가리킴
생성자에서 다른 생성자를 호출
자신의 주소를 반환

public static void main(String[] args){

	BirthDay day = new BirthDay();
    daysetYear(2000);
.....
}
public Person(String name, int age){
	this.name = name;
    this.age = age;
}

note 위 코드에서 this를 생략하게 되면 name,age는 person(String name, int age)에 있는 파라미터의 name, age를 인식하게된다.

생성자에서 다른 생성자를 호출 하는 this

public Person(){
	this("이름없음",1);
}
public Person(String name, int age){
	this.name = name;
    this.age = age;
}

note this를 이용하여 다른 생성자를 호출할 때는 그 이전에 어떠한 statement를 사용할 수 없다.
위와 같이 생성자가 여러 개 이고 파라미터만 다른 경우 constructor overloading(생성자 오버로딩)이라고 한다.

package thisex;

class Person {
	String name;
	int age;

	public Person() {
//		int i = 0;
		// 그래서 이 앞에는 아무 statement도 못옴!
		this("이름없음", 1);
		// 이렇게 다른 constructor을 호출하여 사용할 때는 앞에 어떠한 statement(문장)도 올 수 없다.! 이 this가 가장 먼저
		// 나오는 statement!
	}
	// 이 디폴트 생성자는 파라미터를 받는 생성자를 상속 받아서 사용할 수 있다. == constructor overloading

	public Person(String name, int age) {

		this.name = name;
		this.age = age;
	}

	public Person returnSelf() {
		return this;
		// 반환하는 것은 현재 인식되어있는 instance의 주소 값

	}

}

public class CallAnotherConst {

	public static void main(String[] args) {

		Person p1 = new Person();
		System.out.println(p1.name);
		System.out.println(p1.returnSelf());
	}
}

2. 객체 간의 협력

학생이 버스나 지하철을 가는 상황을 객체 지향으로 프로그래밍

Taxi,Bus,Subway,Student 클래스를 만들어서 클래스 간 협력이 어떻게 이루어지는지 확인해보자!

Bus Class

package cooperation;

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 + "원 입니다.");

	}

}

Subway Class

package cooperation;

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 + "원 입니다.");

	}

}

Taxi Class

package cooperation;

public class Taxi {
	int taxiNumber;
	int passengerCount;
	int money;

	public Taxi(int taxiNumber) {

		this.taxiNumber = taxiNumber;
	}

	public void take(int money) {
		this.money += money;
		passengerCount++;

	}

	public void showInfo() {

		System.out.println("택시" + taxiNumber + "번의 승객은" + passengerCount + "명이고, 수입은" + money + "원 입니다.");

	}
}

Student Class

package cooperation;

public class Student {

	String studentName;
	int grade;
	int money;

	public Student(String studentName, int money) {

		this.studentName = studentName;
		this.money = money;
	}

	// 객체의 협업이 일어나는 부분
	public void takeBus(Bus bus) {
		bus.take(1000);
		money -= 1000;
	}

	public void takeSubway(Subway subway) {

		subway.take(1500);
		money -= 1500;
	}

	public void takeTaxi(Taxi taxi) {

		taxi.take(3800);
		money -= 3800;
	}

	public void showInfo() {

		System.out.println(studentName + "님의 남은 돈은" + money + "원 입니다.");
	}

}

Cooperation Code

package cooperation;

public class TakeClass {

	public static void main(String[] args) {

		Student lee = new Student("이도영", 50000);
		Student kim = new Student("김건우", 80000);

		Bus bus100 = new Bus(100);
		lee.takeBus(bus100);
		lee.showInfo();
		bus100.showInfo();

		Subway subway2 = new Subway(2);
		kim.takeSubway(subway2);
		kim.showInfo();
		subway2.showInfo();

		Taxi kakao1 = new Taxi(1);
		kim.takeTaxi(kakao1);
		lee.takeTaxi(kakao1);
		kim.showInfo();
		lee.showInfo();
		kakao1.showInfo();

	}

}

< 출력결과 >

이렇게 class간의 method로 서로 협력하여 동작하는 것을 볼 수 있다.
상속개념을 적용한다면, 현재, 운송수단인 Taxi,Subway,Bus 등을 상위 클래스를 통해 만들어서 사용하면 더 좋을 것이고, 공통 Method인 take( )는 추상화 시켜서 사용하면 된다.


3. Static

static 변수의 정의와 사용 방법
static 예약어 + 자료형 + 변수 이름
ex) static int seriaNum;
여러 개의 인스턴스가 같은 메모리의 값을 공유하기 위해 사용!
정적변수
static 변수가 선언되어 저장되는 메모리 == data메모리, 정적 메모리, 상수 메모리라고 한다.
이 메모리는 전체 프로그램이 메모리에 load될 때, 할당 받는 영역이다.(상수,리터럴,static변수가 여기에 들어간다.)
즉, static변수는 인스턴스가 생성될 때마다 다른 메모리를 가지는 것이 아니라 프로그램이 적재(load)될 때 데이터 영역의 메모리에 생성 된다.
따라서, 인스턴스의 생성과 관계없이 클래스 이름으로 직접 참조!
Student.serialNum= 100; //serialNum이 static 변수 or 클래스 변수라고 함
클래스이름Student를 이름으로 직접 참조!! StudentL.serialNum,StudentK.seriealNum으로 참조하는게 아니구~
why? static 메모리는 new를 통해 heap메모리에 생성되는 것과 다르게 프로그램이 load될 때 이미 할당되어있음!
멤버변수는 인스턴스 변수라고 한다.

static변수 예
여러 인스턴스가 하나의 메모리 값을 공유 할 때 필요한데,

  • 학생이 생성될 때마다 학번이 증가해야 하는 경우
  • 기준이 되는 값느 static 변수로 생성하여 유지
    각 학생이 생성될 때 마다 static변수 값을 복사해 와서 하나 증가시킨 값을 생성된 인스턴스의 학번 변수에 저장해 둔다.

    stack memory에 있는 변수 공유
package staticex;

public class Student {

	int studentID;
	String studentNameString;

	public Student() {

		serialNum++;

		studentID = serialNum;
	};

	private static int serialNum = 10000;

	public static int getSerialNum() {

		// static변수안의 변수는 지역변수!! 이 메서드가 호출 될 때 생성되고, 메서드가 종료되면 없어진다.
		int i = 10;

		i++;
		System.out.println(i);

//		studentName = "가나다"; // 멤버변수,인스턴스변수
		// 이렇게 멤버변수를 안에서 사용할 수 없다. 왜냐하면, 생성되지도 않은 인스턴스 변수를 static 메모리 단에서 사용하려고 하니 오류가 날
		// 수 밖에...

		return serialNum; // static변수,클래스 변수
	}

}
  • 정리
  • static method
    • 클래스 method라고도 함
    • 메서드에 static키워드를 사용하여 구현
    • 주로 static 변수를 위한 기능 제공
    • static 메서드에서 인스턴스 변수를 사용할 수 없다!
    • static 메서드도 인스턴스의 생성과 관계 없이 클래스 이름으로 직접 메서드를 호출 한다.
      Student.getSerialNum();
      인스턴스의 변수의 경우 꼭 인스턴스가 먼저 생성되어야 사용할 수 있으므로, static메서드에서는 생성이 불확실한 인스턴스의 변수를 사용할 수 없는 것!_
변수 유형선언 위치사용 범위메모리생성과 소멸
지역변수(로컬변수)함수 내부에 선언함수 내부에서만 사용스택함수가 호출될 때 사용되고 함수가 끝나면 소멸함
멤버변수(인스턴스 변수)클래스 멤버 변수로 선언클래스 내부에서 사용하고 private가 아니면 참조 변수로 다른 클래스에서 사용가능인스턴스가 생성될 때 힙에 생성되고,GB(가비지 컬렉터)가 메모리를 수거할 때 소멸됨
static변수(클래스 변수)static 예약어를 사용하여 클래스 내부에 선언클래스 내부에서 사용하고 private가 아니면 클래스 이름으로 다른 클래스에서 사용 가능데이터 영역프로그램이 처음 시작할 때 상수와 함께 데이터 영역에 생성되고 프로그램이 끝나고 메모리를 해제할 때 소멸됨

4 Static : singleton 패턴

수업에서 사용하는 예로 singleton패턴을 파악해보자!
ex) 자동차 회사가 있고 자동차 회사에는 직원들이 있고 자동차 회사에는 여러 개의 공장들이 있고 생산된 자동차를 운반하는 운반차들이 있다.

  • singleton 패턴 예제 코드
package singletonex;
public class Company {

	// instance라는 인스턴스를 단 하나만 사용하기위해서 static사용
	private static Company instance = new Company();

	// Constructor
	// private를 써서 외부에서 접근 불가
	private Company() {
	}

	// 객체를 생성하지않고 이 메서드 부르는 방법 static
	public static Company getInstance() {

		if (instance == null) {
			instance = new Company();
		}
		return instance;
	};

}
package singletonex;

public class CompanyTest {

	public static void main(String[] args) {

		Company c1 = Company.getInstance();
		Company c2 = Company.getInstance();
		System.out.println(c1);
		System.out.println(c2);
        
        // 얘도 자바 내부에 있는 instance 인데 singleton 패턴으로 되어 있음
		Calendar cal = Calendar.getInstance();
	}

}

  • 결과를 보면, 주소값이 같은 것을 할 수 있다. 왜냐하면, instanse라는 것은 하나만 생성되게 설정했기에....

정리

  • singleton 패턴은 전 시스템에서 단 하나의 인스턴스만이 존재하도록 구현하는 방식
  • 자바는 글로벌 변수가 없다 -> static변수 사용
  • 생성자가 없으면 public default Constructor가 생성된다. -> private constructor를 만든다.
  • 외부에서 생성된 static으로 생성된 객체를 사용할 수 있어야 한다. -> public으로 선언된 static 메서드 제공한다.
    ex)
public static Company getInstance() {

		if (instance == null) {
			instance = new Company();
		}
		return instance;
	};

출처 및 참조

https://www.inflearn.com Do it! 자바 프로그래밍 입문 with 은종쌤

profile
자습서 같은 공부 블로그 만들기!

0개의 댓글