
import java.util.Arrays;
public class Application1 {
/* 필기.
* 객체지향프로그램(OOP)란?
* OOP(Object Oriented Programming language)
* 추상화, 캡슐화, 상속, 다형성을 적용하여 유지보수성을 고려한 응집력 높고 결합도 낮은
* 객체 위주의 개발 방식을 적용한 프로그래밍을 말한다.
*
* 필기.
* 객체지향의 특징(4대 특징)
* - 추상화(Abstraction)(추상화를 제외한 3대 특징)
* - 캡슐화(Encapsulation)(필드 및 메소드 은닉)
* - 상속(Inheritance)
* - 다양성(Polymorphism)
*
* 필기.
* 정보은닉(imfomation hiding)
* - 필드 및 메소드 은닉
* - 타입 은닉
* - 구현 은닉
* */
public static void main(String[] args) {
/* 수업목표. 클래스가 무엇인기 이해하고 작성할 수 있다. */
/* 설명.
* 회원 정보를 관리하기 위해 회원의 여러 정보(아이디, 비밀번호, 이름, 나이, 성별, 취미)를 취급하여 관리 하려고 한다.
* 이 자료를 취급할 수 있는 방법을 생각해 보자.
* */
/* 목차. 1. 변수를 이용한 회원 데이터 관리 */
String id = "user01";
String pwd = "pass01";
String name = "홍길동";
int age = 20;
char gender = '남';
String[] hobby = new String[]{"축구", "볼링", "테니스"};
System.out.println("id = " + id);
System.out.println("pwd = " + pwd);
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("gender = " + gender);
System.out.println("hobby = " + Arrays.toString(hobby));
/* 필기
* 이렇게 변수들로만 관리할 떄 발생하리 수 있는 문제점
* 1. 많은 변수명들을 관리하기 힘들 수 있다.
* 2. 메소드의 전달인자로 전달 할 값이 너무 많아 회원과 관련된 기능을 호출할 때 매개변수가 많아진다.
* 3. 메소드의 반환형으로 회원이라는 개념을 반환할 수 없다.(메소드의 반환형은 하나여야 하기 떄문에)
* */
Member member = new Member();
Member member2 = new Member();
System.out.println(member.name);
System.out.println(member2.name);
member.name = "김철수";
member2.name = "김영희";
System.out.println(member.name);
System.out.println(member2.name);
/* 설명. 김철수씨만 완성해 보기 */
member.age = 30;
member.gender = '남';
member.hobby = new String[]{"볼링", "하키"};
member.id = "user03";
member.pwd = "pwd03";
/* 설명. 회원 정보를 하나의 전달인자로 전달하고 하나의 매개변수로 받을 수 있다. */
/* 설명. 또한 메소드의 반환형으로 한번에 회원 정보를 반환할 수 있고 반환 받은 곳에서 반횐된 객체에 접근도 가능하다. */
System.out.println(printMember(member).name);
Member renameMember = printMember(member);
System.out.println(renameMember.age);
System.out.println(Arrays.toString(renameMember.hobby));
}
private static Member printMember(Member member) {
System.out.println("개명 시작을 시작합니다.");
member.name = "박길동";
return member;
}
}
/* 설명. 여러가지 타입의 값을 하나의 타입(Member 클래스)으로 묶을 수 있다.(c++의 구조체에 가까움) */
public class Member { // 배열과 다르게 인덱스 대신 변수로 올라가고 그에 대한 값은 다 다름
String id;
String pwd;
String name;
int age;
char gender;
String[] hobby;
}
public class Application {
public static void main(String[] args) {
/* 수업목표. 접근제어자와 캡슐화에 대해 이해하고 직접 필드 접근을 막는 이유를 이해할 수 있다. */
Monster monster = new Monster();
// monster.name = "드라큘라";
// monster.hp = 1000;
/* 설명. 필드에 직접 접근 대신 메소드를 통해 우회하여 접근한다. */
monster.setInfo1("드라큘라");
monster.setInfo2(1000);
/* 필기.
* 캡슐화(encapsulation)란?
* 캡슐화는 유지보수를 증가시키기 위해 필드의 직접 접근을 제한하고
* public 메소드를 이용해서 간접적으로(우회해서) 접근하여 사용할 수 있도록 만든 기술이다.
* 클래스 작성시 특별한 목적이 있지 않다면 캡슐화를 적용하는 것을 기본 원칙으로 하고 있다.
* */
}
}public class Monster { // class의 접근 제어자는 public 또는 default(안 적힘) 두 가지 밖에 없다.
/* 필기. 접근제어자 private을 활용하여 캡슐화를 적용한다.(같은 클래스를 제외한 곳에서는 접근 불가) */
private String name;
private int hp;
public void setInfo1(String info1) {
this.name = info1;
}
public void setInfo2(int info2) {
this.hp = info2;
}
}A. 필드에 올바르지 않는 값이 들어가도 통제가 불가능하다.
B. 필드의 이름이나 자료형을 변경할 때 사용하는 쪽에도 수정 영향을 미친다.
A. 필드에 직접 접근하지 못하도록 private 접근 제어자 사용
| 구분 | 같은 클래스 | 같은 패키지 | 자식 클래스 | 전체 |
|---|---|---|---|---|
| public | O | O | O | O |
| protected | O | O | O | |
| (default) | O | O | ||
| private | O |
B. public 메소드를 이용하여 간접적으로 접근하도록 사용
C. 메소드 내에 값을 검증하는 로직 추가
public class Application {
public static void main(String[] args) {
/* 수업목표. 접근제어자와 캡슐화에 대해 이해하고 직접 필드 접근을 막는 이유를 이해할 수 있다. */
Monster monster = new Monster();
// monster.name = "드라큘라";
// monster.hp = 1000;
/* 설명. 필드에 직접 접근 대신 메소드를 통해 우회하여 접근한다. */
monster.setInfo1("드라큘라");
monster.setInfo2(1000);
/* 필기.
* 캡슐화(encapsulation)란?
* 캡슐화는 유지보수를 증가시키기 위해 필드의 직접 접근을 제한하고
* public 메소드를 이용해서 간접적으로(우회해서) 접근하여 사용할 수 있도록 만든 기술이다.
* 클래스 작성시 특별한 목적이 있지 않다면 캡슐화를 적용하는 것을 기본 원칙으로 하고 있다.
* */
}
}
public class Monster { // class의 접근 제어자는 public 또는 default(안 적힘) 두 가지 밖에 없다.
/* 필기. 접근제어자 private을 활용하여 캡슐화를 적용한다.(같은 클래스를 제외한 곳에서는 접근 불가) */
private String name;
private int hp;
public void setInfo1(String info1) {
this.name = info1;
}
public void setInfo2(int info2) {
this.hp = info2;
}
}
A. 시스템 요구사항
1. 카레이서는 시동걸기, 엑셀레이터 밟기, 브레이크 밟기, 시동 끄기를 할 수 있다.
2. 자동차는 시동걸기, 앞으로가기, 멈추기 , 시동끄기를 할 수 있다.
3. 자동차는 처음에 멈춘 상태로 대기하고 있는다.
4. 카레이서는 먼저 자동차에 시동을 건다. 이미 걸려있는 경우 다시 시동을 걸 수 없다.
5. 카레이서가 엑셀레이터를 밟으면 시동이 걸린 상태일 경우 자동차는 시속이 10km/h 증가하며 앞으로 나간다.
6. 자동차가 달리는 중인 경우 브레이크를 밟으면 자동차의 시속은 0으로 떨어지며 멈춘다.
7. 브레이크를 밟을 때 자동차가 달리는 중이 아니라면 이미 멈춰있는 상태라고 안내한다.
8. 카레이서가 시동을 끄면 더 이상 자동차는 움직이지 않는다.
9. 자동차가 달리는 중이라면 시동을 끌 수 없다.
B. 필요한 객체
카레이서, 자동차
C. 상호작용
- 카레이서가 수신할 수 있는 메세지 (카레이서가 해야 하는 일)
1. 시동을 걸어라
2. 엑셀레이터를 밟아라
3. 브레이크를 밟아라
4. 시동을 꺼라
- 자동차가 수신할 수 있는 메세지 (자동차가 해야 하는 일)
1. 시동을 걸어라
2. 앞으로 가라
3. 멈춰라
4. 시동을 꺼라
1. 시동 걸기
--------- ---------- --------
| 사용자 | ---> 시동을 걸어라 ---> | 카레이서 | ---> 시동을 걸어라 ---> | 자동차 |
--------- <------------------- ---------- <--------------------- ---------
2. 가속 하기
--------- ---------- --------
| 사용자 | ---> 엑셀레이터를 밟아라 ---> | 카레이서 | ---> 앞으로 가라 ---> | 자동차 |
--------- <------------------------ ---------- <-------------------- ---------
3. 정지하기
--------- ---------- --------
| 사용자 | ---> 브레이크를 밟아라 ---> | 카레이서 | ---> 멈춰라 ---> | 자동차 |
--------- <----------------------- ---------- <-------------- ---------
4. 시동 끄기
--------- ---------- --------
| 사용자 | ---> 시동을 꺼라 ---> | 카레이서 | ---> 시동을 꺼라 ---> | 자동차 |
--------- <------------------- ---------- <------------------ ---------
D. 클래스 설계하기
1. 카레이서 클래스
- 속성 : 자동차
- 행위 : 시동을걸어라, 엑셀레이터를 밟아라, 브레이크를 밟아라, 시동을 꺼라.
2. 자동차 클래스
- 속성 : 시동상태, 현재시속
- 메소드 : 시동을걸어라, 앞으로 가라, 멈춰라, 시동을 꺼라
import java.util.Scanner;
public class Application {
public static void main(String[] args) {
/* 수업목표. 객체지향 프로그래밍에 대해 이해하고 객체와 클래스를 설계하여 프로그래밍 할 수 있다. */
/* 필기.
* 추상화란?
* 공통된 부분을 추출하고 공통되지 않고 불필요한 부분을 제거한다는 의미를 가지며, 추상화의 목적은 유연성을 확보하기 위함이다.
* 유연성 확보는 여러 곳에서 적용될 수 있는 유연한 객체를 의미하며, 재사용성이 높아질 수 있게 한다는 의미이다.
* */
/* 필기.
* 프로그램 개요
* 카레이서가 자동차를 운전하는 프로그램
*
* 필기.
* 시스템 요구사항
* 1. 카레이서는 시동걸기, 엑셀레이터 밟기, 브레이크 밟기, 시동 끄기를 할 수 있다.
* 2. 자동차는 시동걸기, 앞으로 가기, 멈추기, 시동끄기를 할 수 있다.
* 3. 자동차는 처음에 멈춘 상태로 대기하고 있는다.
* 4. 카레이서는 먼저 자동차에 시동을 건다. 이미 걸려있는 경우 다시 시동을 걸 수 없다.
* 5. 카레이서가 엑셀레이터를 밟으면 시동이 걸린 상태일 경우 자동차는 시속이 10km/h 증가하며 앞으로 나간다.
* 6. 자동차가 달리는 중인 경우 브레이크를 밟으면 자동차의 시속은 바로 0km/h로 떨어지며 멈춘다.
* 7. 브레이크를 밟을 때 자동차가 달리는 중이 아니면 이미 멈춰있는 상태라고 안내한다.
* 8. 카레이서가 시동을 끄면 더 이상 자동차는 움직이지 않는다.
* 9. 자동차가 달리는 중이라면 시동을 끌 수 없다.
* */
/* 설명. 카레이서 한 명이 등장 */
CarRacer racer = new CarRacer();
Scanner sc = new Scanner(System.in);
/* 설명. 카레이서에게 명령을 하기 위한 메뉴 출력 */
while (true) {
System.out.println("=========== 카레이싱 프로그램 ===========");
System.out.println("1. 시동 걸기");
System.out.println("2. 전진");
System.out.println("3. 정지");
System.out.println("4. 시동 끄기");
System.out.println("9. 프로그램 종료");
System.out.println("메뉴 선택: ");
int input = sc.nextInt();
switch (input) {
case 1: racer.startUp();
break;
case 2: racer.stepAccelator();
break;
case 3: racer.stepBreak();
break;
case 4: racer.turnOff();
break;
case 9: System.out.println("프로그램을 이용해 주셔서 감사합니다.");
break;
default:
System.out.println("잘못된 메뉴를 선택하셨습니다.");
}
if(input == 9) break;
}
}
}
public class CarRacer {
/* 설명. 차 한대(Car 객체 하나)를 필드로 가진다. */
private Car myCar = new Car();
/* 설명. 자신이 보유한 차량에 시동을 건다. */
public void startUp() {
this.myCar.startUp();
}
public void stepAccelator() {
myCar.go();
}
public void stepBreak() {
myCar.stop();
}
public void turnOff() {
myCar.turnOff();
}
}
public class Car {
private boolean isOn = false;
private int speed;
/* 설명. 시동이 걸려있는 상태인 경우에는 할 일이 없고, 시동이 걸려있지 않은 상태인 경우 시동을 건다. */
public void startUp() {
if (isOn) { // 시동이 걸려 있으면
System.out.println("이미 시동이 걸려있습니다.");
} else { // 시동이 걸려 있지 않다면
isOn = true; // isOn 앞에는 this.이 있는 거지만 this.을 생략해도 자동으로 적힌다.
System.out.println("시동을 걸었습니다. 부릉부릉~!");
}
}
/* 설명. 시동이 걸린 상태인 경우에만 호출시 마다 10km/h씩 속도를 증가시킨다. */
public void go() {
if(isOn) { // 시동이 켜져있어 달릴 수 있음
System.out.println("차가 앞으로 움직입니다.");
speed += 10;
System.out.println("현재 차의 시속은 " + speed + "km/h 입니다.");
}else { // 시동이 꺼져있어 달릴 수 없음
System.out.println("차의 시동이 걸려있지 않습니다. 시동을 먼저 걸어주세요.");
}
}
/* 설명. 시동이 걸려있고 달리는 상태인 경우에만 멈출 수 있다. */
public void stop() {
if (isOn) {
if(speed > 0) {
speed = 0;
System.out.println("급 브레이크를 밟았습니다. 차를 멈춥니다.");
}else {
System.out.println("차는 이미 멈춰있는 상태입니다.");
}
} else {
System.out.println("차의 시동이 걸려있지 않습니다. 시동을 먼저 걸어주세요.");
}
}
/* 설명. 시동이 걸려있는 상태인 경우 시동을 끄고, 이미 꺼지 상태라면 끌 수 있고 주행중이라면 끌 수 없다. */
public void turnOff() {
if (isOn) {
if(speed > 0) {
System.out.println("달리는 상태에서 시동을 끌 수 없습니다. 차를 우선 멈춰주세요.");
} else {
isOn =false;
System.out.println("시동을 끕니다. 다시 운행하시려면 시동을 켜주세요.");
}
}else {
System.out.println("이미 시동이 꺼져 있는 상태입니다. 시동 상태를 확인해 주세요.");
}
}
}
User [id=null, pwd=null, name=null, enrollDate=null]
User [id=user01, pwd=pass01, name=홍길동, enrollDate=null]
User [id=user02, pwd=pass02, name=이순신, enrollDate=Sun May 07 15:52:53 KST 2023]
User [id=user02, pwd=pass02, name=이순신, enrollDate=Sun May 07 15:52:53 KST 2023]
오버로딩(overloading) : 같은 클래스 내부에서 메소드를 확장하기 위한 개념
오버라이딩(overriding) : 부모 클래스의 메소드의 동작 방법을 변경(재정의)하여 우선적으로 사용하는 개념



| 변수 | 생성시기 | 소멸시기 |
|---|---|---|
| 클래스 변수 | 프로그램 시작 시 | 프로그램 종료 시 |
| 인스턴스 변수 | 인스턴스 생성 시 | 참조하지 않을 시 |
| (GC 소관) | ||
| 지역 변수 | 메소드 호출 시 | 메소드 종료 시 |


Car[] carArray = new Car[5];
carArray[0] = new Car("페라리", 300);
carArray[1] = new Car("람보르기니", 350);
carArray[2] = new Car("롤스로이스", 250);
carArray[3] = new Car("부가티베이론", 400);
carArray[4] = new Car("포터", 500);
for (int i = 0; i < carArray.length; i++) {
carArray[i].driveMaxSpeed();
}
페라리이(가) 최고시속 300km/h로 달려갑니다.
람보르기니이(가) 최고시속 350km/h로 달려갑니다.
롤스로이스이(가) 최고시속 250km/h로 달려갑니다.
부가티베이론이(가) 최고시속 400km/h로 달려갑니다.
포터이(가) 최고시속 500km/h로 달려갑니다.