Object Oriented programming
추상화 : 프로그램에서 필요한 속성(변수)와 기능(메서드)를 추출하고 불필요한 것을 제거하는 과정
- Tv의 속성 (변수) : 크기 / 전원 / 볼륨 / 채널
- Tv의 기능 (메서드) : 전원 on, off / 볼륨 up, down / 채널 up, down (= 동사)
new 클래스명( );**
package kh.java.func;
public class Tv {
// 속성 : 해당 클래스의 전역변수
int size; //TV 사이즈
boolean power; //전원
int ch; //채널
int vol; //볼륨
// 기능 : 해당 클래스의 메서드
// 현재 power변수의 값을 반대로 변경
// on > off, off > on
public void power() {
power = !power;
if(power) {
System.out.println("전원이 켜졌습니다.");
}else {
System.out.println("전원이 꺼졌습니다.");
}
}
// 현재 ch변수 값을 1증가
// 현재 채널 번호에서 1증가한 번호로 변경
public void chUp() {
ch++;
System.out.println("현재 채널 : "+ch);
}
// 현재 ch변수 값을 1감소
// 현재 채널 번호에서 1감소한 번호로 변경
public void chDown() {
ch--;
System.out.println("현재 채널 : "+ch);
}
// 현재 ch변수 값을 1감소
// 현재 채널 번호에서 1감소한 번호로 변경
public void volUp() {
vol++;
System.out.println("현재 볼륨 : "+vol);
}
// 현재 ch변수 값을 1감소
// 현재 채널 번호에서 1감소한 번호로 변경
public void volDown() {
vol--;
System.out.println("현재 볼륨 : "+vol);
}
}
Tv(클래스)타입의 객체를 생성하여 사용 >
package kh.java.run;
import kh.java.func.Tv;
public class Start {
public static void main(String[] args) {
// 객체 생성하는 방법
// 1) 패키지가 다른 경우 import
// 2) new 클래스명();
// > 클래스 형태대로 메모리에 데이터 생성 후 주소 리턴
// > 주소를 Tv형태의 변수에 저장
Tv tv1 = new Tv();
Tv tv2 = new Tv();
tv1.power();
tv1.volUp();
tv2.power();
System.out.println(tv1.vol);//1
System.out.println(tv2.vol);//0
tv2.chUp();
tv2.chUp();
tv2.chUp();
System.out.println(tv2.ch);//3
System.out.println(tv1.ch);//0
// 인스턴스는 독립적이다
}
}
encapsulation
상속, 다형성과 같이 객체지향 언어의 3요소 중 하나
접근제어지시자를 private로 설정하여 클래스 외부에서 직접접근을 제한하는 것
- 의도치 않은 외부 정보가 들어오지 않도록 정보은닉
- 정보를 확인하고, 바꾸기 위해 getter setter 사용
- getter : 변수의 정보를 얻어오는 것
- setter : 변수의 정보를 바꾸는 것
public class Tv2 {
private int size;
private boolean power;
private int ch;
private int vol;
// Tv2클래스의 전역변수에 외부직접접근을 막기위해
// private 접근제어지시자 사용 > 정보은닉
// 정보은닉을 하게되면 외부에서 변수를 사용할 수 없음
// 변수의 데이터를 대입하고, 값을 가져올 수 있는 메소드를 생성
// > getter, setter
// getter--------------------
// getter변수의 데이터를 보여주는 목적
// get+변수명 < 카멜표기법
// 반환타입은 해당 변수의 타입 그대로
public int getSize() {
return size;
}
public int getVol() {
return vol;
}
public int getCh() {
return ch;
}
public boolean isPower() {
return power;
}
// setter---------------------
// setter는 메서드를 통해 전역변수에 값을 대입
// set+변수명 < 카멜표기법
// 값을 넣어주기만 하기 때문에 반환타입은 없음 = void
// 단, get과 달리 같은 타입의 매개변수 존재
public void setSize(int size) {
this.size = size;
// size만 쓰면 지역변수가 되어버림
// this. 을 붙여 전역변수로 지정
} // setSize를 만들지 않으면 접근할 수 없음
// <캡슐화>
public void setCh(int ch) {
this.ch = ch;
}
public void setVol(int vol) {
this.vol = vol;
}
public void setPower(boolean power) {
this.power = power;
}
constructer
new 연산자를 통해 실행되는 초기화 메서드
생성자의 종류는 기본 생성자와 매개변수가 있는 생성자로 나뉜다
// 생성자
// 전역변수와 getter, setter 사이에 만든다
public Tv2() {
// 리턴에 대한 개념이 없기 때문에 반환타입 자체를 적지 않음
// 객체가 정상적으로 돌아가기 위해 필요한 값을 초기화
this.size = 100;
}
// 생성자 오버로딩
public Tv2(int size) {
this.size = size;
}
※ 자바는 Garbage Collector가 메모리를 자동으로 정리하기 때문에 소멸자가 필요하지 않음
웹개발의 기본
- Create : 데이터를 만들어 저장하는 기능
- Read : 저장되어 있는 데이터를 읽어오는 기능
- Update : 저장되어 있는 데이터를 수정하는 기능
- Delete : 저장되어 있는 데이터를 삭제하는 기능
create
//학생정보를 관리하는 프로그램 (10명)
//학생정보 : 이름, 나이, 주소
//단, 동명이인은 없음 (가정), 데이터는 정상적으로 입력된다
private String[] name;
private int[] age;
private String[] addr;
private Scanner sc;
private int index;
//학생정보추가시 학생정보가 들어갈 배열 위치를 저장할 변수
//생성자
public StudentController() {
name = new String[10];
age = new int[10];
addr = new String[10];
sc = new Scanner(System.in);
index = 0;
}
//create
//학생정보를 입력받아 배열에 저장하는 메서드
public void insertStudent() {
System.out.println("\n------- 학생 정보 등록 -------\n");
System.out.print("학생 이름 입력 : ");
String StudentName = sc.next();
System.out.print("학생 나이 입력 : ");
int studentAge = sc.nextInt();
System.out.print("학생 주소 입력 : ");
sc.nextLine();
String StudentAddr = sc.nextLine();
name[index] = StudentName;
age[index] = studentAge;
addr[index] = StudentAddr;
index++;
}
read
// 배열에 저장된 모든 학생정보를 출력하는 메서드
// 인덱스는 배열에 들어있는 정보에서 1을 추가한 배열을 가리킨다
// 인덱스는 학생수와 동일하다 (등록할 때마다 1이 추가된 상태이기 때문에)
public void printAllStudent() {
System.out.println("\n----- 전체 학생 정보 출력 -----\n");
System.out.println("이름\t나이\t주소");
for(int i=0; i<index; i++) {
System.out.println(name[i]+"\t"+age[i]+"\t"+addr[i]);
}
}
// 이름을 입력받아 조회 후 배열에 저장된 해당 학생정보를 출력하는 메서드
public void printOneStudent() {
System.out.println("\n----- 학생 정보 출력 (이름 검색) -----\n");
System.out.print("조회할 학생 이름 입력 : ");
String searchName = sc.next();
int searchIndex = searchStudent(searchName);
if(searchIndex==-1) {
System.out.println("학생정보를 조회할 수 없습니다");
} else {
System.out.println("학생이름 : "+name[searchIndex]);
System.out.println("학생나이 : "+age[searchIndex]);
System.out.println("학생주소 : "+addr[searchIndex]);
}
}
update
// 매개변수로 받은 이름이 name배열의 몇 번째 존재하는지 index를 돌려주는 메서드
// (조회 실패시 -1 반환)
public int searchStudent(String searchName) {
for(int i=0; i<index; i++) {
if(searchName.equals(name[i])) {
return i;
}
} return -1;
}
// 학생이름을 입력받아 해당 학생의 정보를 수정하는 메서드
public void updateStudent() {
System.out.println("\n------- 학생 정보 수정 -------\n");
System.out.print("정보를 수정할 학생 이름 입력 : ");
String searchName = sc.next();
int searchIndex = searchStudent(searchName);
if(searchIndex==-1) {
System.out.println("학생정보를 조회할 수 없습니다");
} else {
System.out.print("수정할 이름 입력 : ");
name[searchIndex] = sc.next();
System.out.print("수정할 나이 입력 : ");
age[searchIndex] = sc.nextInt();
System.out.print("수정할 주소 입력 : ");
sc.nextLine(); //버퍼에 남은 엔터 제거
addr[searchIndex] = sc.nextLine();
System.out.println("정보 수정 완료 !");
}
}
delete
// 이름을 입력받아 해당 학생을 삭제하는 메서드
public void deleteStudent() {
System.out.println("\n------- 학생 정보 삭제 -------\n");
System.out.print("삭제할 학생 이름 입력 : ");
String searchName = sc.next();
int searchIndex = searchStudent(searchName);
if(searchIndex == -1) {
System.out.println("학생 정보를 찾을 수 없습니다.");
} else {
for(int i=searchIndex; i<index-1; i++) {
name[i] = name[i+1];
age[i] = age[1+1];
addr[i] = addr[i+1];
}
index--; // 마지막 칸을 컨트롤 < 어차피 인덱스만큼 출력하니까
System.out.println("- 삭제 완료 ! -");
// 예를 들면, 회원이 5명 인덱스 번호 0~4번 index : 5개
// 3번회원 삭제 > 2번 인덱스 데이터 삭제
// 3번부터 하나씩 당겨오겠다
// 2번 : 3번 데이터 입력
// 3번 : 4번 데이터 입력
// 한 명 사라졌으니 인덱스 -1
}
}
위 코드를 객체지향으로 변환 >
package kr.or.iei.student.vo;
public class Student {
private String name;
private int age;
private String addr;
// 데이터가 되는 클래스 (VO)
// 1. 기본 생성자
// 2. 모든 변수값을 저장할 수 있는 매개변수 생성자
// 3. getter, setter
//기본생성자
public Student() {
}
//매개변수가 모두 있는 생성자
public Student(String name, int age, String addr) {
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getAddr() {
return addr;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddr(String addr) {
this.addr = addr;
}
}// 클래스 끝
데이터를 운영하는 클래스 : Control Class
컨트롤 클래스에서 엔티티 클래스를 변수로 사용하여 프로그램을 작성
이 경우 컨트롤 클래스가 Entity 클래스를 포함하고 있어 has a관계라고 함
create
public void insertStudent() {
System.out.println("\n-------학생 정보 등록-------\n");
System.out.print("등록할 학생 이름 입력 : ");
String name = sc.next();
System.out.print("등록할 학생 나이 입력 : ");
int age = sc.nextInt();
System.out.print("학생 주소 입력 : ");
sc.nextLine();
String addr = sc.nextLine();
// 1) 기본생성자
/*
Student s = new Student();
// 비어 있는 학생 인스턴스 생성
s.setName(name);
s.setAge(age);
s.setAddr(addr);
*/
// 2) 매개변수 있는 생성자
Student s = new Student(name, age, addr);
students[index++] = s;
System.out.println("학생 정보 등록 완료");
}
read
//모든 학생 정보 불러오기
public void printAllStudent() {
System.out.println("\n-----모든 학생 정보 출력 -----\n");
System.out.println("이름:\t나이:\t주소:\t");
System.out.println("---------------------------");
// students > 배열타입
// Students[인덱스번호] > Student타입
// Students[인덱스번호].getter 호출
for(int i=0; i<index; i++) {
System.out.println(students[i].getName()+"\t"
+students[i].getAge()+"\t"
+students[i].getAddr());
}
}
// 이름을 조회하여 해당 학생 정보 불러오기
public void printOneStudent() {
System.out.println("\n------- 학생 정보 출력 -------\n");
System.out.print("조회할 학생 이름 입력 : ");
String name = sc.next();
int searchIndex = searchStudent(name);
if (searchIndex==-1) {
System.out.println("입력한 학생 정보를 찾을 수 없습니다");
} else {
System.out.println("학생 이름 : "+students[searchIndex].getName());
System.out.println("학생 나이 : "+students[searchIndex].getAge());
System.out.println("학생 주소 : "+students[searchIndex].getAddr());
}
}
getter, setter를 적절하게 사용할 수 있어야 한다
update
public void updateStudent() {
System.out.println("\n------- 학생 정보 수정 -------\n");
System.out.print("변경할 학생 이름 입력 : ");
int searchIndex = searchStudent(sc.next());
if(searchIndex==-1) {
System.out.println("회원을 찾을 수 없습니다");
} else {
System.out.print("변경할 이름 : ");
String updateName = sc.next();
System.out.print("변경할 나이 : ");
int updateAge = sc.nextInt();
System.out.print("변경할 주소 : ");
String updateAddr = sc.next();
Student s = students[searchIndex];
s.setName(updateName);
s.setAge(updateAge);
s.setAddr(updateAddr);
System.out.println("정보 수정 완료 !");
}
}
delete
public void deleteStudent() {
System.out.println("\n------- 학생 정보 삭제 -------\n");
System.out.print("삭제할 학생의 이름을 입력해 주세요 : ");
int searchIndex = searchStudent(sc.next());
if(searchIndex==-1) {
System.out.println("조회한 학생을 찾을 수 없습니다");
} else {
// 인덱스는 학생수 +1을 바라보고 있으므로 -1
for(int i=searchIndex; i<index-1; i++) {
students[i] = students[i+1];
}
index--; // 한 명이 빠졌으므로 인덱스 번호 1 줄여준다
System.out.println("정보 삭제 완료");
}
}
출력/수정/삭제에서 공통으로 사용하는 메서드
public int searchStudent(String searchName) {
for (int i=0; i<index; i++) {
if(searchName.equals(students[i].getName())) {
return i;
}
} return -1;
}