21.08.31 - 웹 개발 입문 15일차
접근제한 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