0701 java oop-1

onnbi·2022년 7월 26일
0

java-tutorial

목록 보기
6/13
post-thumbnail

객체지향 프로그래밍

Object Oriented programming

객체

  • 사전적 의미 : 실체 하는 모든 물건
  • 객체지향 언어에서 객체의 개념은 new 연산자를 통해 클래스의 설계대로 데이터를 메모리에 할당한 결과물 = instance

클래스

  • 객체를 정의해 놓은 것
  • 객체의 설계도
  • 사물이나 개념의 공통요소 (속성과 기능)를 용도에 맞게 추상화한 것

    추상화 : 프로그램에서 필요한 속성(변수)와 기능(메서드)를 추출하고 불필요한 것을 제거하는 과정

    • Tv의 속성 (변수) : 크기 / 전원 / 볼륨 / 채널
    • Tv의 기능 (메서드) : 전원 on, off / 볼륨 up, down / 채널 up, down (= 동사)

객체의 생성

  1. 패키지가 다른 경우 import
  2. new 클래스명( );**
    • 클래스 형태대로 메모리에 데이터 생성 후 주소리턴
    • 주소를 클래스 타입의 변수에 저장
    • ex ) Tv tv1 = new Tv( );
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
		// 인스턴스는 독립적이다
	}
}

변수의 종료

  1. 지역변수
    • 메서드 내에서 사용가능한 변수
    • 스텍에서 사용되었다 사라졌다를 반복하기 때문에 사용할 때 초기화하여 사용한다 > 반드시 직접 초기화
  2. 전역변수 (멤버/인스턴스 변수)
    • 해당 클래스 내에서 사용가능한 변수
    • 객체를 생성하면 해당 객체 내에서 사용가능
  3. 정적변수 (Static 변수)
    • 클래스와 관계없이 사용가능한 변수

캡슐화

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 연산자를 통해 실행되는 초기화 메서드
생성자의 종류는 기본 생성자와 매개변수가 있는 생성자로 나뉜다

생성자 규칙

  1. 생성자는 메소드 선언과 유사하지만, 리턴값과 관련이 없다 ( void가 아니라 없음 !)
  2. 생성자의 이름은 일반적으로 클래스명과 동일하다
  3. 생성자를 만들지 않으면 JVM이 기본 생성자를 만들지만, 하나라도 만들면 기본 생성자는 만들어지지 않는다.
	// 생성자
	// 전역변수와 getter, setter 사이에 만든다
public Tv2() {
	// 리턴에 대한 개념이 없기 때문에 반환타입 자체를 적지 않음
	// 객체가 정상적으로 돌아가기 위해 필요한 값을 초기화
	this.size = 100;
}
	
	// 생성자 오버로딩
public Tv2(int size) {
	this.size = size;
}

※ 자바는 Garbage Collector가 메모리를 자동으로 정리하기 때문에 소멸자가 필요하지 않음

CRUD

웹개발의 기본

  • 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
	}
}

위 코드를 객체지향으로 변환 >

CRUD 2

데이터(타입)이 되는 클래스 : VO, Entity Class

  1. 기본생성자
  2. 모든 변수를 매개변수로 갖는 생성자
  3. getter, setter
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;
}
profile
aelatte coding journal

0개의 댓글