Ch02. 객체지향입문 02

하파타카·2022년 8월 21일
0

패캠JAVA, Spring과정

목록 보기
6/20

09.참조 자료형 변수

  • 변수의 자료형은 기본 자료형(int, long, double 등)과 참조 자료형(String, Date, Student 등)이 존재
  • 기본 자료형은 메모리의 크기가 지정되어 있지만 참조 자료형은 사용하는 클래스에 따라 크기가 다름.
  • 참조 자료형은 반드시 해당 변수에 대한 생성을 거친 후 사용한다.
    (단, String클래스는 예외적으로 생성을 생략하고 사용가능)

예를 들어 학생이 수강한 과목들에 대한 점수를 산출하기 위한 경우

학생 클래스

학번
학생이름
국어과목
수학과목

(+)
과목 클래스

과목이름
과목 점수

참조 자료형으로 멤버변수를 사용하는 경우 대부분 생성자에서 생성됨.
반드시 생성자에서 생성해야하는건 아니며, 사용되기 전에만 생성되면 됨.(생성되기 전 사용 시 nullpointerexception에러발생)

예제

-Subject.java-

package ch09;

public class Subject {
	
	String subjectName;
	int score;
	int subjectId;
}

-Student.java-

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 setKoreaSubject(String name, int score) {
		korea.subjectName = name;
		korea.score = score;
	}
	
	public void setMathSubject(String name, int score) {
		math.subjectName = name;
		math.score = score;
	}
	
	public void showScoreInfo() {
		int total = korea.score + math.score;
		System.out.println(studentName + "학생의 총점은 " + total + "점 입니다.");
	}
}

-StudentTest.java-

package ch09;

public class SubjectTest {
	public static void main(String[] args) {
	
		Student studentLee = new Student(100, "Lee");
		studentLee.setKoreaSubject("국어", 100);
		studentLee.setMathSubject("수학", 80);
		
		Student studentKim = new Student(200, "Kim");
		studentLee.setKoreaSubject("국어", 96);
		studentLee.setMathSubject("수학", 75);
		
		studentLee.showScoreInfo();
		studentKim.showScoreInfo();
	}
}


10. 접근 제어 지시자와 정보은닉

접근 제어 지시자(access modifier)와 정보은닉(infomation hiding)

접근 제어 지시자

  • class외부에서 클래스의 멤버변수, 메서드, 생성자의 사용가능여부를 지정하는 키워드
  • 정보은닉 여부와 단계에 따라 필요한 키워드를 선택하여 사용한다

키워드 목록

  • private : 같은 클래스 내에서만 접근가능
  • (default) : 같은 패키지 내에서만 접근가능 (상속관계라도 패키지가 다를 경우 접근불가)
  • protected : 같은 패키지이거나 상속관계의 클래스에서만 접근가능
  • public : 클래스 외부 어디서든 접근가능

default상태에서 다른 패키지에 속해있을 경우 import를 하여 사용함.
예) scanner클래스는 java.util패키지에 속해있으므로 사용하려면 import과정을 거쳐야 함

get() set() 메서드

  • private로 선언된 멤버변수(필드)에 대해 접근, 수정 할 수 있는 메서드를 public으로 제공

=> 멤버변수에 직접 값을 넣을 경우 생기는 데이터의 불필요한 오용을 메서드를 이용해 막을 수 있음.

예제

-BirthDay.java-

package ch10;

public class BirthDay {

	private int day;
	private int month;
	private int year;
	
	private boolean isValid;
	
	public int getDay() {
		return day;
	}
	
	public void setDay(int day) {
		this.day = day;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		if(month < 1 || month > 12) {
			isValid = false;
		} else {
			isValid = true;
			this.month = month;	
		}		
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}
	
	public void showDate() {
		
		if (isValid) {
			System.out.println("생일은 " + year + "년 " + month + "월 " + day + "일 입니다.");
		} else {
			System.out.println("유효하지 않은 날짜입니다.");
		}
	}
}

-BirthDayTest.java-

package ch10;
public class BirthDayTest {

	public static void main(String[] args) {

		BirthDay date = new BirthDay();
		date.setYear(2022);
		date.setMonth(13);
		date.setDay(22);
		
		date.showDate();
		
		date.setMonth(8);
		date.showDate();
		
		//date.month = 100;	// 직접 멤버변수에 값을 넣을 경우 데이터에 대한 제어가 불가능함
	}

}

date.month = 100;(에러발생) => BirthDay클래스에서 private로 멤버변수의 접근제어자를 지정하여 다른 클래스에서 객체를 생성하더라도 멤버변수에 직접 접근하여 값을 지정할 수 없다.
단, 무조건 private키워드를 사용하는것은 바람직하지 않음.
상황에 따라 공개여부 및 단계에 따라 지정해야 함.


이클립스에서 getter setter 자동생성기능을 지원함


11.캡슐화

  • 정보은닉을 목적으로 함.
  • 정보를 감싸 필요한 정보 및 기능만을 외부에 노출하는 개념.
  • 대부분의 멤버 변수, 메서드를 감추고 외부에 통합된 인터페이스만 제공하여 일관될 기능을 구현하게 함.
  • 메서드나 멤버 변수에 접근하여 발생하는 오류를 최소화.

예제

-MakeReport.java-

package ch11;

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();
	}

}

-TestReport.java-

package ch11;

public class TestReport {

	public static void main(String[] args) {

	MakeReport report = new MakeReport();
	String builder = report.getReport();
	
	System.out.println(builder);
	}
}

클라이언트에게는 getReport()메서드만을 제공하여 출력하는 기능만을 사용할 수 있도록 함.
순서를 지정하는 기능 등은 캡슐화하여 사용자에게 기능을 숨김.

어떤 기능 및 객체를 얼마나 공개하고 어떤 정보를 숨기느냐를 설계하는 것이 객체지향 설계에서 매우 중요한 부분임.


12. 객체 자신을 가리키는 this

this

  • 인스턴스 자신의 메모리를 가리킴
  • 생성자에서 또 다른 생성자를 호출할때 사용(이 부분은 상속에서의 super와 동일)
  • 자신의 주소(참조)값을 반환함

상속에서의 super와 유사하므로 반드시 알아두자.

1) 인스턴스 자신의 메모리 주소를 가짐

  • 클래스 내에서 참조변수가 가지는 주소 값과 동일 한 주소 값을 가지는 키워드
public void setYear(int year)
{
    this.year = year;
}

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

  • 클래스에 생성자가 여러 개 인경우, this를 이용하여 생성자에서 다른 생성자를 호출할 수 있음
  • 생성자에서 다른 생성자를 호출하는 경우, 인스턴스의 생성이 완전하지 않은 상태이므로 this() statement 이전에 다른 statement를 쓸 수 없음
    => 인스턴스의 생성이 완료되지 않은 상태에서 다른 코드를 실행할 수 없다는 의미
public class Person {

	String name;
	int age;
	
	public Person() {
    	//name = "이름"; 아직 인스턴스의 생성이 완료되지 않아 에러발생. 생성 후 사용은 가능.
		this("no name", 1);
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void showPerson() {
		System.out.println(name + ", " + age);
	}
	
	public static void main(String[] args) {
		Person person = new Person();
		person.showPerson();
		
	}
}

3) 자신의 주소를 반환하는 this

public class Person {

	String name;
	int age;
	
	public Person() {
		//name = "이름"; 아직 인스턴스의 생성이 완료되지 않아 에러발생. 생성 후 사용은 가능.	
		this("no name", 1);
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void showPerson() {
		System.out.println(name + ", " + age);
	}
	
	public Person getPerson() {
		return this;
	}
	
	public static void main(String[] args) {
		Person person = new Person();
		person.showPerson();
		
		System.out.println(person);
		
		Person person2 = person.getPerson();
		System.out.println(person2);
	}
}


personperson2는 같은 주소값이 반환됨.


13. 객체 간의 협력 (collabration)

  • 객체지향 프로그래밍에서는 객체간의 협력이 필요함
  • 필요한 메시지를 전송하고 처리하는 기능이 구현되어야 함
  • 매개변수로 객체가 전달되는 경우가 발생

객체지향 프로그래밍은 실생활을 잘 반영한 프로그래밍 방식임.


14.실생활 예제로 객체지향프로그래밍 구현해보기

1) 버스와 지하철을 타고 학교를 가는 예제

James와 Tomas는 각각 버스와 지하철을 타고 학교에 갑니다.
James는 5000원을 가지고 있었고, 100번 버스를 타면서 1000원을 지불합니다.
Tomas는 10000원을 가지고 있었고, 초록색 지하철을 타면서 1200원을 지불합니다.

-Student.java-

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(1200);
		this.money -= 1200;
	}
	
	public void showInfo() {
		System.out.println(studentName + "님의 남은 돈은 " + money + "원 입니다.");
	}
}

-Bus.java-

public class Bus {

	int busNum;				// 버스번호
	int passengerCount;		// 승객 수
	int money;				// 수입
	
	public Bus(int busNum) {
		this.busNum = busNum;
	}
	
	public void take(int money) {
		this.money += money;
		passengerCount++;
	}
	
	public void showBusInfo() {
		System.out.println(busNum + "번 버스의 승객 수는 " + passengerCount + "명이고 수입은 " + money + "원 입니다.");
	}
}

-Subway.java-

public class Subway {

	int lineNum;			// 라인번호
	int passengerCount;		// 승객 수
	int money;				// 수입
	
	public Subway(int lineNum) {
		this.lineNum = lineNum;
	}
	
	public void take(int money) {
		this.money += money;
		passengerCount++;
	}
	
	public void showBusInfo() {
		System.out.println(lineNum + "번 지하철의 승객 수는 " + passengerCount + "명이고 수입은 " + money + "원 입니다.");
	}
}

-TakeTransTest.java-

public class TakeTransTest {
	public static void main(String[] args) {
		
		Student studentJ = new Student("제임스", 5000);
		Student studentT = new Student("토마스", 10000);
		
		Bus bus100 = new Bus(100);
		Bus bus200 = new Bus(200);
		
		studentJ.takeBus(bus100);
		studentJ.showInfo();
		
		Subway greenSubway = new Subway(2);
		
		studentT.takeSubway(greenSubway);
		studentT.showInfo();
		
		bus100.showBusInfo();
		greenSubway.showBusInfo();
	}
}


15.객체협력 복습

예제 구현하기

앞의 예제에서 Edward는 지각을 해서 택시를 타야 했습니다. 
20000원을 가지고 있었는데 10000원을 택시비로 사용했습니다.
택시는 '잘나간다 운수' 회사 택시를 탔습니다.

내가푼 답

틀릴 수 있음
택시클래스를 만들어 택시를 타는 메서드를 만듦
고객클래스를 만들어 이름과 총금액을 멤버변수로 생성
고객클래스에서 택시클래스의 택시를 타는 메서드를 호출하여 총금액을 다시계산

-Customer.java-

public class Customer {

	String name;
	int money;
	
	public Customer(String name, int money) {
		this.name = name;
		this.money = money;
	}
	
	public void takeTaxi(Taxi taxi) {
		taxi.take(2000);
		this.money -= 2000;
	}
	
	public void showCustomerInfo() {
		System.out.println(name + "님의 남은 돈은 " + money + "원 입니다.");
		
	}
}

-Taxi.java-

public class Taxi {
	
	String taxiName;
	int money;

	public Taxi(String taxiName) {
		this.taxiName = taxiName;
	}
	
	public void take(int money) {
		this.money += 2000;
	}
	
	public void showTaxiInfo() {
		System.out.println(taxiName + "택시의 수입은 " + money + "원 입니다.");
	}
}

-TakeTaxiTest.java-

public class TakeTaxiTest {
	public static void main(String[] args) {
		
		Customer customer01 = new Customer("에드워드", 10000);

		Taxi taxi01 = new Taxi("잘나간다 운수");
				
		customer01.takeTaxi(taxi01);
		
		customer01.showCustomerInfo();
		taxi01.showTaxiInfo();
		
	}
}

profile
천 리 길도 가나다라부터

0개의 댓글