Java 웹 개발

21.08.31 - 웹 개발 입문 15일차

개발이란 2021. 8. 31. 20:04

접근제한 private 알아보기

- 외부 접근 차단 키워드 = 은닉화

package day0831oop.modifier1;

public class Student {

	private String name;
	private int score;

	void setName(String name) {
		this.name = name;
	}
	void setScore(int score) {
		if(score < 0 || score > 100) {
			return;
		}
		this.score = score;
	}
	String getName() {
		return this.name;
	}
	int getScore() {
		return this.score;
	}

	void init(String name, int score) {
		this.setName(name);
		this.setScore(score);
	}

	void showInfo() {
//		System.out.println(this.name);
//		System.out.println(this.score);

		System.out.println(this.getName());
		System.out.println(this.getScore());
	}
}
package day0831oop.modifier1;

public class Test02 {

	public static void main(String[] args) {
		Student s = new Student();

		s.init("피카츄", 75);
//		s.score = -75;//응 안돼
		s.setScore(-75);

		s.showInfo();
	}
}

 

 

Q. 다음 요구사항에 맞게 데이터를 구성하세요

기종 통신사 약정기간 할부원금
갤럭시폴드3 SKT 24개월 200만원
아이폰12 KT 24개월 180만원
갤럭시21s LGuplus 30개월 155만원

- 통신사는 `SKT`, `KT`, `LGuplus`, `알뜰폰` 중 하나만 가능
- 약정기간은 24개월, 30개월, 36개월 중에서만 선택 가능
- 할부원금은 절대로 음수가 될 수 없습니다

 

package oop.modifier2;

public class Phone {

	private String name;
	private String service;
	private int period;
	private int money;

	// 세터 메소드

	void setName(String name) {
		this.name = name;
	}

	void setService(String service) {
		switch (service) {
		case "SKT":
		case "KT":
		case "LGuplus":
		case "알뜰폰":
			this.service = service;
		}
	}

	void setPeriod(int period) {
		if (!(period == 24 || period == 30 || period == 36)) {
			return;
		}
		this.period = period;
	}

	void setMoney(int money) {
		if (money < 0) {
			return;
		}
		this.money = money;
	}

	// 게터 메소드
	String getName() {
		return this.name;
	}

	String getService() {
		return this.service;
	}

	int getPeriod() {
		return this.period;
	}

	int getMoney() {
		return this.money;
	}

	public void init(String name, String service, int period, int money) {
		this.setName(name);
		this.setService(service);
		this.setPeriod(period);
		this.setMoney(money);
	}

	// 출력
	public void showInfo() {
		System.out.println("<휴대폰 정보>");
		System.out.println("기종 : " + this.name);
		System.out.println("통신사 : " + this.service);
		System.out.println("약정기간 : " + this.getPeriod() + "개월");
		System.out.println("할부원금 : " + this.getMoney() + "원");
	}

}
package oop.modifier2;

public class Test01 {

	public static void main(String[] args) {

		Phone a = new Phone();
		Phone b = new Phone();
		Phone c = new Phone();

		// 초기화
		a.init("갤럭시폴드3", "SKT", 24, 2000000);
		b.init("아이폰12", "KT", 24, 1800000);
		c.init("갤럭시21s", "LGuplus", 30, 1550000);

		// 출력
		a.showInfo();
		b.showInfo();
		c.showInfo();

	}

}

- 정답

<휴대폰 정보>
기종 : 갤럭시폴드3
통신사 : SKT
약정기간 : 24개월
할부원금 : 2000000원
<휴대폰 정보>
기종 : 아이폰12
통신사 : KT
약정기간 : 24개월
할부원금 : 1800000원
<휴대폰 정보>
기종 : 갤럭시21s
통신사 : LGuplus
약정기간 : 30개월
할부원금 : 1550000원

 

 

다른 패키지에 있는 Phone의 객체를 만들 수 있을까?

package oop.modifier3;

import oop.modifier2.Phone;

public class Test01 {

	public static void main(String[] args) {

		Phone a = new Phone();

		a.init("갤럭시 폴드3", "SKT", 24, 2000000);

		a.showInfo();
	}
}

= 자바는 모든 파일을 패키지 단위로 구분한다
= 접근제한에 대한 설명이 없으면 "같은 패키지"에서만 사용이 가능
= 다른 패키지에서도 접근을 허용하고 싶으면 "접근 허용" 키워드를 사용해야함

= public 키워드를 추가하면 import가 가능해진다

 

 

 

 

 

생성자(Contstructor) 알아보기
= 객체의 생성방식을 결정하는 구문
= 없으면 기본 생성방식을 지원
= 메소드의 변형(메소드와 형태가 다름)
= 객체 생성 시 딱 한 번만 실행
= 클래스랑 이름이 반드시 같아야 함
= 반환형을 적을 수 없고 오로지 초기화만 가능

 

ex) 예제1

package oop.constructor1;

public class Student {
	private String name;
	private int score;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public Student(String name, int score) {
		this.setName(name);
		this.setScore(score);
	}
	
	public void showInfo() {
		System.out.println(this.name);
		System.out.println(this.score);
	}
	
}
package oop.constructor1;

public class Test01 {

	public static void main(String[] args) {
		//객체 생성
		Student a = new Student("마리오",80);
			
		//출력
		a.showInfo();

	}

}

 

ex) 예제2

Q : 책을 만드는 방법은 총 몇가지인가?
A : 4가지 = 제목+지은이 / 제목+지은이+출판사 / 제목+지은이+가격 / 제목+지은이+출판사+가격
생성자가 4개 있으면 완벽하게 구현이 가능

package oop.constructor2;

public class Book {
	private String title;			//반드시 존재해야 하는 필수 항목
	private String publisher;	//없을 수도 있고, 있을 수도 있는 선택 항목
	private String writer;		//반드시 존재해야 하는 필수 항목
	private int price;				//없을 수도 있고, 있을 수도 있는 선택 항목

	//기본 생성자 : 아무런 초기화도 수행하지 않는 생성자
	//public Book() {}

	public Book(String title, String writer) {//생성방법 1 : 제목 + 지은이
		this.title = title;
		this.writer = writer;
	}

	public Book(String title, String writer, String publisher) {//생성방법 2 : 제목 + 지은이 + 출판사
		this.title = title;
		this.writer = writer;
		this.publisher = publisher;
	}

	public Book(String title, String writer, int price) {//생성방법 3 : 제목 + 지은이 + 가격
		this.title = title;
		this.writer = writer;
		this.price = price;
	}

	public Book(String title, String writer, String publisher, int price) {//생성방법 4 : 모든정보
		this.title = title;
		this.writer = writer;
		this.publisher = publisher;
		this.price = price;
	}
}
package oop.constructor2;

public class Test01 {

	public static void main(String[] args) {
		// Book 객체 생성
		// Book a = new Book();//불가능. 허락하지 않는 생성방식
		Book a = new Book("생각을 바꾸는 생각들", "비카스 샤");// 제목 + 지은이
		Book b = new Book("소크라테스 익스프레스", "에릭 와이너", 16200);// 제목 + 지은이 + 가격
		Book c = new Book("전기차 상식사전", "정우덕", "넥서스 BOOKS");// 제목 + 지은이 + 출판사
		Book d = new Book("전기기능사 필기", "김영언, 박진영", "모아팩토리", 22500);// 제목 + 지은이 + 출판사 + 가격

	}
}

 

 

Q. 다음 데이터를 요구사항에 맞게 구조화하세요

아이디 직업 레벨 소지금
뽀로로 전사 50 50000
크롱 마법사 35 20000
루피 전사 1 0

- 아이디와 직업은 최초 캐릭터 생성시에 정해야 만들 수 있습니다.
- 레벨을 설정하지 않으면 1로 설정해야 합니다
- 소지금을 설정하지 않으면 0으로 설정합니다
- 필요하다면 운영진에서 캐릭터를 임의의 레벨과 소지금으로 생성할 수 있도록 해야합니다
- 레벨은 1이상만 설정이 가능합니다
- 소지금은 0이상만 설정이 가능합니다
- 직업은 "전사", "마법사", "궁수" 중에서만 설정이 가능합니다

 

package oop.constructor3;

public class User {

	// 멤버 변수
	private String id;
	private String job;
	private int level;
	private int gold;

	// 세터 & 게터
	public void setId(String id) {
		this.id = id;
	}

	public void setJob(String job) {
		switch (job) {
		case "전사":
		case "마법사":
		case "궁수":
			this.job = job;
		}
	}

	public void setLevel(int level) {
		if (level < 1) {
			return;
		}
		this.level = level;
	}

	public void setGold(int gold) {
		if (gold < 0) {
			return;
		}
		this.gold = gold;
	}

	public String getId() {
		return this.id;
	}

	public String getJob() {
		return this.job;
	}

	public int getLevel() {
		return this.level;
	}

	public int getGold() {
		return this.gold;
	}

	// 생성자
	// [1] 아이디와 직업만 설정하는 생성자. 이 때 레벨은 1, 소지금은 0Gold
	// [2] 아이디, 직업, 레벨, 소지금을 설정할 수 있는 생성자
	public User(String id, String job) {
		this.setId(id);
		this.setJob(job);
		this.setLevel(1);
//		this.setGold(0);
	}

	public User(String id, String job, int level, int gold) {
		this.setId(id);
		this.setJob(job);
		this.setLevel(level);
		this.setGold(gold);
	}

	public void showInfo() {
		System.out.println("<캐릭터 정보>");
		System.out.println("아이디 : " + this.id);
		System.out.println("직   업 : " + this.job);
		System.out.println("레   벨 : " + this.level + " Lv");
		System.out.println("소지금 : " + this.gold + " Gold");
	}

}
package oop.constructor3;

public class Test01 {

	public static void main(String[] args) {

		User a = new User("뽀로로", "전사", 50, 50000);
		User b = new User("크롱", "마법사", 35, 20000);
		User c = new User("루피", "전사");

		a.showInfo();
		b.showInfo();
		c.showInfo();

		// Getter가 없으면 풀 수 없는 상황
		// a와 b의 레벨 차이를 구하여 출력하세요
		// System.out.println(a.level - b.level);
		System.out.println(a.getLevel() - b.getLevel());
	}
}

- 정답

<캐릭터 정보>
아이디 : 뽀로로
직   업 : 전사
레   벨 : 50 Lv
소지금 : 50000 Gold
<캐릭터 정보>
아이디 : 크롱
직   업 : 마법사
레   벨 : 35 Lv
소지금 : 20000 Gold
<캐릭터 정보>
아이디 : 루피
직   업 : 전사
레   벨 : 1 Lv
소지금 : 0 Gold
15

 

 

 

 

Q. 다음 데이터를 요구사항에 맞게 구조화하세요

객실명 이용인원 비수기요금 준성수기요금 성수기요금
스탠다드룸 4 10만원 20만원 25만원
슈페리어룸 4 15만원 25만원 30만원
디럭스룸 6 30만원 45만원 55만원
프리미엄룸 8 100만원 - -

- 인원수는 2명 이상으로 설정해야 합니다.
- 모든 요금은 0 이상이어야 합니다.
- 요금이 하나만 설정될 경우 비수기요금으로 간주합니다.
- 요금이 하나만 설정될 경우 준성수기요금과 성수기요금도 비수기요금과 동일하게 설정됩니다.
- 요금이 두 개 설정될 경우 비수기요금과 성수기요금으로 간주합니다.
- 요금이 두 개 설정될 경우 준성수기요금은 성수기요금과 동일하게 설정됩니다.

 

 

package oop.constructor4;

public class Room {

	//멤버 변수
	private String name;
	private int numberOfPeople;
	private int lowSeasonPrice;
	private int semiPeakSeasonPrice;
	private int peakSeasonPrice;

	//멤버 메소드
	public void setName(String name) {
		this.name = name;
	}
	public void setNumberOfPeople(int numberOfPeople) {
		//2명 미만일 경우 2명으로 설정하기 위한 코드
		if(numberOfPeople < 2) {
			numberOfPeople = 2;
		}
		this.numberOfPeople = numberOfPeople;
	}
	public void setLowSeasonPrice(int lowSeasonPrice) {
		if(lowSeasonPrice < 0) {
			return;
		}
		this.lowSeasonPrice = lowSeasonPrice;
	}
	public void setSemiPeakSeasonPrice(int semiPeakSeasonPrice) {
		if(semiPeakSeasonPrice < 0) {
			return;
		}
		this.semiPeakSeasonPrice = semiPeakSeasonPrice;
	}
	public void setPeakSeasonPrice(int peakSeasonPrice) {
		if(peakSeasonPrice < 0) {
			return;
		}
		this.peakSeasonPrice = peakSeasonPrice;
	}

	public String getName() {
		return this.name;
	}
	public int getNumberOfPeople() {
		return this.numberOfPeople;
	}
	public int getLowSeasonPrice() {
		return this.lowSeasonPrice;
	}
	public int getSemiPeakSeasonPrice() {
		return this.semiPeakSeasonPrice;
	}
	public int getPeakSeasonPrice() {
		return this.peakSeasonPrice;
	}

	//생성자
	//[1] 이름 + 인원수 + 비성수기요금 
	//[2] 이름 + 인원수 + 비성수기요금 + 성수기요금
	//[3] 이름 + 인원수 + 비성수기요금 + 준성수기요금 + 성수기요금
	public Room(String name, int numberOfPeople, int lowSeasonPrice) {
		this.setName(name);
		this.setNumberOfPeople(numberOfPeople);
		this.setLowSeasonPrice(lowSeasonPrice);
		this.setSemiPeakSeasonPrice(lowSeasonPrice);
		this.setPeakSeasonPrice(lowSeasonPrice);
	}

	public Room(String name, int numberOfPeople, int lowSeasonPrice, int peakSeasonPrice) {
		this.setName(name);
		this.setNumberOfPeople(numberOfPeople);
		this.setLowSeasonPrice(lowSeasonPrice);
		this.setSemiPeakSeasonPrice(peakSeasonPrice);
		this.setPeakSeasonPrice(peakSeasonPrice);
	}

	public Room(String name, int nuberOfPeople, int lowSeasonPrice, 
										int semiPeakSeasonPrice, int peakSeasonPrice) {
		this.setName(name);
		this.setNumberOfPeople(nuberOfPeople);
		this.setLowSeasonPrice(lowSeasonPrice);
		this.setSemiPeakSeasonPrice(semiPeakSeasonPrice);
		this.setPeakSeasonPrice(peakSeasonPrice);
	}

	public void showInfo() {
		System.out.println("<객실 정보>");
		System.out.println("객실명 : "+this.name);//this.getName()
		System.out.println("이용인원 : "+this.numberOfPeople+"명");//this.getNumberOfPeople()
		System.out.println("비수기 : "+this.lowSeasonPrice+"원");//this.getLowSeasonPrice()
		System.out.println("준성수기 : "+this.semiPeakSeasonPrice+"원");//this.getSemiSeasonPrice()
		System.out.println("성수기 : "+this.peakSeasonPrice+"원");//this.getPeakSeasonPrice()
	}
}
package oop.constructor4;

public class Test01 {

	public static void main(String[] args) {
		Room a = new Room("스탠드다드룸", 4, 100000, 200000, 250000);
		Room b = new Room("슈페리어룸", 4, 150000, 250000, 300000);
		Room c = new Room("디럭스룸", 6, 300000, 450000, 550000);
		Room d = new Room("프리미엄룸", 8, 1000000);

		a.showInfo();
		b.showInfo();
		c.showInfo();
		d.showInfo();

	}
}

- 정답

<객실 정보>
객실명 : 스탠드다드룸
이용인원 : 4명
비수기 : 100000원
준성수기 : 200000원
성수기 : 250000원
<객실 정보>
객실명 : 슈페리어룸
이용인원 : 4명
비수기 : 150000원
준성수기 : 250000원
성수기 : 300000원
<객실 정보>
객실명 : 디럭스룸
이용인원 : 6명
비수기 : 300000원
준성수기 : 450000원
성수기 : 550000원
<객실 정보>
객실명 : 프리미엄룸
이용인원 : 8명
비수기 : 1000000원
준성수기 : 1000000원
성수기 : 1000000원

 

- 위에 문제를 배열로 풀어보기

package oop.constructor4;

public class Test02 {
	public static void main(String[] args) {
		// Test01을 배열로 풀이

		// int[] arr = new int[4];
		Room[] arr = new Room[4];

		arr[0] = new Room("스탠다드룸", 4, 100000, 200000, 250000);
		arr[1] = new Room("슈페리어룸", 4, 150000, 250000, 300000);
		arr[2] = new Room("디럭스룸", 6, 300000, 550000);
		arr[3] = new Room("프리미엄룸", 8, 1000000);

		arr[0].showInfo();
		arr[1].showInfo();
		arr[2].showInfo();
		arr[3].showInfo();
	}
}

 

 

 

 

Q. 다음 데이터를 요구사항에 맞게 구조화하세요

- 사용자가 입력한 정보를 이용하여 회원 정보 객체를 생성하는 프로그램을 구현
- 관리되는 회원 정보
- 아이디, 비밀번호, 닉네임, 포인트, 등급
- 사용자는 아이디, 비밀번호, 닉네임을 입력한다.
- 신규 생성된 회원에게는 100포인트를 지급한다
- 신규 생성된 회원의 등급은 "준회원"으로 설정한다
- 회원가입이 완료된 후 가입한 회원의 정보를 "비밀번호는 제외"하고 출력한다

 

package oop.total1;

public class User {
	// 멤버 변수
	private String id; // 사용자 입력(필수)
	private String password; // 사용자 입력(필수)
	private String nickname; // 사용자 입력(필수)
	private int point; // 사용자 미입력(기본값 100포인트)
	private String grade; // 사용자 미입력(기본값 준회원)

	public void setId(String id) {
		this.id = id;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public void setPoint(int point) {
		if (point < 0) {
			return;
		}
		this.point = point;
	}

	public void setGrade(String grade) {
		switch (grade) {
		case "준회원":
		case "정회원":
		case "우수회원":
		case "특별회원":
		case "VVIP":
		case "관리자":
			this.grade = grade;
		}
	}

	public String getId() {
		return this.id;
	}

	public String getPassword() {
		return this.password;
	}

	public String getNickname() {
		return this.nickname;
	}

	public int getPoint() {
		return this.point;
	}

	public String getGrade() {
		return this.grade;
	}

	// 생성자
	public User(String id, String password, String nickname) {
		this.setId(id);
		this.setPassword(password);
		this.setNickname(nickname);
		this.setPoint(100);
		this.setGrade("준회원");
	}

	public void showInfo() {
		System.out.println("<회원 정보>");
		System.out.println("아이디 : " + this.id);
		System.out.println("닉네임 : " + this.nickname);
		System.out.println("포인트 : " + this.point + " point");
		System.out.println("등   급 : " + this.grade);
	}
}
package oop.total1;

import java.util.Scanner;

public class Test01 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		System.out.print("아이디 입력 : ");
		String id = sc.next();
		System.out.print("비밀번호 입력 : ");
		String password = sc.next();
		System.out.print("닉네임 입력 : ");
		String nickname = sc.next();
		sc.close();

		User a = new User(id, password, nickname);
		a.showInfo();
	}
}

- 정답

아이디 입력 : asd
비밀번호 입력 : 123
닉네임 입력 : aaa
<회원 정보>
아이디 : asd
닉네임 : aaa
포인트 : 100 point
등   급 : 준회원

 

 

 

final 키워드 알아보기

목표 : "이름"은 단 한번만 설정 가능하도록 구현
= 세터 메소드를 생성하지 말아야 하며
= 생성자에서 초기화를 반드시 수행
-> 프로그래밍 배치 등으로 구현하기는 어렵고
-> final 이라는 키워드를 사용하면 구현 가능!
-> final 변수는 "생성자"에서 반드시 초기화가 이루어져야 한다.

= final 멤버 변수는 setter 메소드를 가질 수 없다

package oop.keyword1;


	public class Student {
//		private final String name = "피카츄";
		private final String name;
		private int score;

		public Student(String name) {
			this.name = name;
		}
		public Student(String name, int score) {
			this.name = name;
			this.score = score;
		}

//		final 멤버변수는 setter 메소드를 가질 수 없다
//		public void setName(String name) {
//			this.name = name;
//		}
		public void setScore(int score) {
			this.score = score;
		}

		public String getName() {
			return this.name;
		}
		public int getScore() {
			return this.score;
		}

		public void showInfo() {
			System.out.println(this.name);
			System.out.println(this.score);
		}
	}
package oop.keyword1;

public class Test01 {

	public static void main(String[] args) {
		Student s = new Student("손오공", 90);

//		s.setName("저팔계");//불가능(안만들어짐)
		s.setScore(50);

		s.showInfo();
	}
}

 

<잠깐 개념 , 차이점 알아두기!>

오버로딩 : 같은 클래스에서 작성되며, 메서드의 이름이 같지만 매개변수의 타입, 개수가 다른 경우
오버라이딩 : 상속받은 상위클래스의 함수를 자식 클래스에서 재정의하여 사용하는 경우

 

 

 

Q. 다음 요구사항에 맞게 클래스를 구성하고 객체를 생성하세요
<요구사항>
- 사용자에게 제목과 폭, 높이를 입력받는다
- 사용자에게 입력받은 정보를 토대로 화면 객체를 생성한다.
- 제목은 언제든지 수정이 가능하다
- 폭과 높이는 디자인적인 문제로 인해 한 번 정해지면 변경하지 말아야 한다.
- 만들어진 화면 객체의 정보를 출력하면 제목, 폭, 높이가 얼마인지 각각 출력되어야 한다.

 

 

package oop.keyword2;

public class Screen {

	// 멤버 변수
	private String title; // 사용자 입력(필수)
	private final int width; // 사용자 입력(필수)
	private final int height; // 사용자 입력(필수)

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	// 생성옵션 1 : 아무것도 설정하지 않고 설정
	public Screen() { //기본 생성자 : 외부에서 어떠한 값도 받지 않는 생성자
		this.setTitle("Untitle");
		this.width = 600;
		this.height = 400;
	}

	// 생성옵션 2 : 제목만 설정
	public Screen(String title) {
		this.setTitle(title);
		this.width = 600;
		this.height = 400;
	}

	// 생성옵션 3 : 크기만 설정
	public Screen(int width, int height) {
		this.setTitle("Untitle");
		this.width = width;
		this.height = height;
	}

	// 생성옵션 4 : 제목, 크기 설정
	public Screen(String title, int width, int height) {
		this.setTitle(title);
		this.width = width;
		this.height = height;
	}
package oop.keyword2;

import java.util.Scanner;

public class Test01 {
	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		System.out.print("제목을 입력하세요 : ");
		String title = sc.next();
		System.out.print("폭을 입력하세요 : ");
		int width = sc.nextInt();
		System.out.print("높이를 입력하세요 : ");
		int height = sc.nextInt();
		sc.close();

		Screen a = new Screen(title, width, height);
		a.showInfo();

	}
}

- 정답

제목을 입력하세요 : 테스트
폭을 입력하세요 : 500
높이를 입력하세요 : 300
<화면 정보>
제목 : 테스트
폭 : 500
높이 : 300