Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

Super Coding Addict

Ch05. 클래스와 객체(2) 본문

JAVA 문법

Ch05. 클래스와 객체(2)

밍응애 2021. 1. 19. 00:02

< 생성자, 생성자 오버로딩 >

* 생성자

- 객체를 생성할 때 new 키워드와 함께 호출

- 인스턴스를 초기화 하는 코드가 구현됨 (주로 멤버변수 초기화)

- 반환값 없음 cf. 메서드

- 상속되지 않음

- 클래스 이름과 항상 동일

 

* 기본생성자  : 매개 변수X, 구현부 X

- 하나의 클래스에는 반드시 하나 이상의 생성자 존재

- 프로그래머가 생성자 구현하지 않으면, 컴파일러가 생성자 코드를 넣어줌 ==> 기본 생성자

 

* 생성자 오버로딩

- 여러 생성자들 매개변수를 달리해서 만들 수 있음

cf. private : 이 클래스 내부에서만 쓰는 변수로 외부에서 참조할 수 없다 --> 생성자로 초기화 가능

 

 

< 참조 자료형 >

* 참조자료형

- 클래스형으로 변수를 선언 ex) String name;

- 기본자료형은 사용하는 메모리가 정해져 있지만, 참조 자료형은 클래스에 따라 다르다

 

- 예제 (Student와 Subject)

 

[ Student클래스 ]

package reference;

public class Student {
	
	int studentID;
	String studentName;
	
	Subject korea;	//참조변수 타입으로 변수 선언
	Subject math;	//객체생성을 해야 쓸 수 있음!
	
	public Student(int id, String name) {
		studentID = id;
		studentName = name;
		
		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 showStudentScore() {
		int total = korea.score + math.score;
		System.out.println(studentName + " 학생의 총점은 " + total + "점 입니다");
	}
}

 

[ Subject 클래스 ]

package reference;

public class Subject {
	
	public String subjectName;
	public int score;
	public int subjectID;

}

[ StudentTest클래스 (메인메서드가 있는 곳) ]

package reference;

public class StudentTest {

	public static void main(String[] args) {
		
		Student studentLee = new Student(100, "Lee");
		studentLee.setKoreaSubject("국어", 100);
		studentLee.setMathSubject("수학", 95);
		
		Student studentKim = new Student(101, "Kim");
		studentKim.setKoreaSubject("국어", 80);
		studentKim.setMathSubject("수학", 99);
		
		studentLee.showStudentScore();
		studentKim.showStudentScore();
		
	}

}

/* 결과 
Lee 학생의 총점은 195점 입니다
Kim 학생의 총점은 179점 입니다
*/

 

< 정보 은닉 >

* 접근 제어자 

- public, private, protected, default

: public - 모두 접근 허용

: private - 클래스 내부에서만 접근 허용

: protected - 같은 클래스 or 상위클래스가 가진 private 변수나 메서드를 하위클래스에 public하게 오픈하고 싶을 때 사용

: default(아무것도 안쓰는 경우) - 같은 패키지 내에서만 접근 허용

 

- private을 사용하면 클래스 외부에서는 접근 불가

 

* 정보 은닉

- 외부에서 클래스 내부 정보에 접근하지 못하게 함

- private 키워드 활용

- private 변수를 외부에서 접근하게 하려면 public 메서드 제공 (ex- getter, setter)

- 클래스 내부 데이터를 잘못 사용하는 오류 방지


- 예제 : 멤버변수인 month, day, year 변수를 private으로 설정하고 setter로 값 설정 / getter로 값 가져오기 ( [source] - [Generate Getters and Setters] )

--> 그러나 여전히 setter로도 유효하지 않은 값을 넣을 수 있는 것 아닌가? --> 유효성 검사를 위한 멤버변수 isValid 선언하고 false일 때 유효하지 않은 값이라고 출력

 

[ MyDate클래스 ]

package hiding;

public class MyDate {
	
	private int day;	//default는 같은 패키지내에서만 접근가능
	private int month;
	private int year;
	
	private boolean isValid;	//boolean은 멤버변수일 때 무조건 기본값은 false
	
	public void setDay(int day) {
		this.day = day;	//멤버변수 이름과 매개변수 이름이 같을 때 this로 구분하기
	}
	
	public int getDay() {
		return day;
	}
	
	
	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		if ( month < 1 || month > 12) {
			isValid = false;
		}
		else
			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("유효하지 않은 날짜입니다.");
		}
	}
}

 

[ MyDateTest 클래스 ]

package hiding;

public class MyDateTest {

	public static void main(String[] args) {
		MyDate date = new MyDate();
		
		date.setDay(19);
		date.setMonth(1);
		date.setYear(2021);
		
		date.showDate();

	}

}

 

< this에 대하여 >

* this의 역할

- 자기 자신의 메모리를 가리킴

- 생성자에서 다른 생성자 호출

public Person(){
	this("이름 없음", 1);	// 다른 생성자 호출
}

public Person(String name, int age){
	this.name = name;
    this.age = age;
}

- 인스턴스 자신의 주소를 반환

- 예제

[ Person 클래스 ]

package thisex;

public class Person {
	String name;
	int age;
	
	public Person() {
		//age = 100; //this로 다른 생성자 호출시 this가 firstStatement여야함!!!
		this("이름없음", 1);
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public void showInfo() {
		System.out.println(name + ", " + age);
	}
	
	public Person getSelf() {	//반환타입은 자신의 클래스
		return this;
	}
}

 

[ PersonTest 클래스 ]

package thisex;

public class PersonTest {

	public static void main(String[] args) {
		Person personNoname = new Person();
		personNoname.showInfo();
		
		Person personLee = new Person("Lee", 20);
		personLee.showInfo();
		System.out.println(personLee);

		Person p = personLee.getSelf();
		System.out.println(p);	//this가 가리키는 것과 참조변수가 가리키는 것이 같다.
	}

}

/*
결과:

이름없음, 1
Lee, 20
thisex.Person@6a5fc7f7
thisex.Person@6a5fc7f7

*/

 

< 객체 간 협력 >

* 객체 간 협력

- 객체 지향 프로그램은 객체를 정의하고 객체간의 협력을 구현한 프로그램

 

- 예제

[ Student 클래스 ]

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);	//bus 인스턴스가 없다면 널포인트익셉션이 떨어질 것임
		this.money -= 1000;
	}
	
	public void takeSubway(Subway subway) {	//객체 협업
		subway.take(1200);
		this.money -= 1200;
	}
	
	public void showInfo() {
		System.out.println(studentName + "님의 남은 돈은 " + money + "원 입니다.");
	}
}

 

[ Bus 클래스 ]

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 showBusInfo() {
		System.out.println(busNumber + "번 버스의 승객은 " + passengerCount + "명 이고, 수입은 " + money + "입니다.");
	}
	
}

 

[ Subway클래스 ]

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 showSubwaysInfo() {
		System.out.println(lineNumber + "번 지하철의 승객은 " + passengerCount + "명 이고, 수입은 " + money + "입니다.");
	}
}


[ TakeTransTest 클래스 ]

package cooperation;

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);
		Bus bus500 = new Bus(500);
		Subway subwayGreen = new Subway(2);
		Subway subwayBlue = new Subway(4);
		
		studentJ.takeBus(bus100);
		studentT.takeSubway(subwayGreen);
		
		studentJ.showInfo();
		studentT.showInfo();
		
		bus100.showBusInfo();
		bus500.showBusInfo();
		
		subwayGreen.showSubwaysInfo();
	}

}

 


< 코딩해보세요 >

1. 정보은닉 - 날짜의 유효성을 검증하는 프로그램 구현하기

 

* 내 코드

[ MyDate 클래스 ]

package date;

public class MyDate {
	private int day;
	private int month;
	private int year;
	public boolean isValid = true;
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		if((year % 4 == 0 && year % 100 != 0) ||
				( year % 4 == 0 && year % 100 == 0 && year % 400 == 0)){//윤년
			switch(month) {
			case 1:	case 3: case 5: case 7: case 8: case 10: case 12:
				if (day < 1 || day > 31) 
					isValid = false;
				break;
			case 2:
				if (day < 1 || day > 29)
					isValid = false;
				break;
			case 4: case 6: case 9: case 11:
				if (day < 1 || day > 30)
					isValid = false;
				break;
			}//switch				
		}else{ //평년
			switch(month) {
			case 1:	case 3: case 5: case 7: case 8: case 10: case 12:
				if (day < 1 || day > 31)
					isValid = false;
				break;
			case 2:
				if (day < 1 || day > 28)
					isValid = false;
				break;
			case 4: case 6: case 9: case 11:
				if (day < 1 || day > 30)
					isValid = false;
				break;
			}
		}//else끝
		
		if(isValid)
			this.day = day;
		
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		if(0 < month && 13 > month)
			this.month = month;
		else
			isValid = false;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	
	public void getMydateInfo() {
		if(isValid)
			System.out.println(year + "년" + month + "월" + day + "일 입니다.");
		else
			System.out.println("유 효 N O ");
	}
	
	
}

[ MyDateTest 클래스 ]

package date;

public class MyDateTest {

	public static void main(String[] args) {
		MyDate mydate = new MyDate();
		mydate.setYear(2021);
		mydate.setMonth(2);
		mydate.setDay(29);
		
		mydate.getMydateInfo();
	}

}

 

* 모범답안 코드

[ MyDate 클래스 ]

package date;

import java.util.Calendar;

public class MyDate {
	private int day;
	private int month;
	private int year;
	private boolean isValid = true;
	
	
	public MyDate(int day, int month, int year) {	//생성자
		setYear(year);
		setMonth(month);
		setDay(day);
	}


	public int getDay() {
		return day;
	}


	public void setDay(int day) {
		switch(month) {
			case 1:	case 3:	case 5: case 7: case 8: case 10: case 12:
				if (day < 0 || day > 31)
					isValid = false;
				else
					this.day = day;
				break;
			case 4: case 6: case 9: case 11:
				if (day < 0 || day > 30)
					isValid = false;
				else
					this.day = day;
				break;
			case 2:
				if( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ) {	//윤년
					if (day < 0 || day > 29)
						isValid = false;
					else
						this.day = day;
				}else {	//평년
					if (day < 0 || day > 28)
						isValid = false;
					else
						this.day = day;
				}
				break;
			default:
				isValid = false;
		}
	}


	public int getMonth() {
		return month;
	}


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


	public int getYear() {
		return year;
	}


	public void setYear(int year) {
		if(year > Calendar.getInstance().get(Calendar.YEAR)) {
			isValid = false;
		}else
			this.year = year;
	}
	
	public String isValid() {
		if(isValid) 
			return "유효한 날짜입니다.";
		else 
			return "유효하지 않은 날짜입니다.";
	}
}

 

[ MyDateTest 클래스 ]

package date;

public class MyDateTest {

	public static void main(String[] args) {
		MyDate date1 = new MyDate(19, 1, 2012);
		System.out.println(date1.isValid());
		MyDate date2 = new MyDate(6, 10, 1992);
		System.out.println(date1.isValid());	
	}

}

 

2. 객체 간 협력 - 출근길 커피 사기

 

* 내 코드

[ Person 클래스 ]

package coffee;

public class Person {
	String personName;
	int money;
	String coffee;
	
	public Person(String personName, int money) {
		this.personName = personName;
		this.money = money;
	}
	
	public void visitStar(StarCoffee star, String coffee) {
		money -= star.buyCoffee(coffee);
		this.coffee = coffee;
	}
	
	public void visitKong(KongCoffee kong, String coffee) {
		money -= kong.buyCoffee(coffee);
		this.coffee = coffee;
	}
	
	public void getPersonCoffeeInfo() {
		System.out.println(personName + "씨가 마신 음료는 " + coffee + "이며, 남은 금액은 " + money + "입니다.");
	}
}

 

[ StarCoffee 클래스 ]

package coffee;

public class StarCoffee {
	int income;
	
	public int buyCoffee(String coffee) {
		if (coffee.equals("아메리카노")) {
			income += 4000;
			return 4000;
		}
		else if(coffee.equals("라떼")) {
			income += 4500;
			return 4500;
		}
		else return 0;
	}
}

 

[ KongCoffee 클래스 ] 

package coffee;

public class KongCoffee {
	int income;
	
	public int buyCoffee(String coffee) {
		if (coffee.equals("아메리카노")) {
			income += 4000;
			return 4000;
		}
		else if(coffee.equals("라떼")) {
			income += 4500;
			return 4500;
		}
		else return 0;
	}
}

 

[ CoffeeTest 클래스 ]

package coffee;

public class CoffeeTest {

	public static void main(String[] args) {
		Person kim = new Person("김졸려", 10000);
		Person Lee = new Person("이피곤", 10000);

		kim.visitStar(new StarCoffee(), "아메리카노");
		Lee.visitStar(new StarCoffee(), "라떼");
	
		kim.getPersonCoffeeInfo();
		Lee.getPersonCoffeeInfo();
	}

}


/*
결과:

김졸려씨가 마신 음료는 아메리카노이며, 남은 금액은 6000입니다.
이피곤씨가 마신 음료는 라떼이며, 남은 금액은 5500입니다.
*/

 

www.fastcampus.co.kr/dev_online_jvweb

'JAVA 문법' 카테고리의 다른 글

Ch07. 상속과 다형성 (1)  (0) 2021.01.22
Ch06. 배열(2)  (0) 2021.01.20
Ch06. 배열(1)  (0) 2021.01.19
Ch05. 클래스와 객체(3)  (0) 2021.01.19
Ch05. 클래스와 객체(1)  (0) 2021.01.18