[JAVA] TIL 010 - 23.07.25

유진·2023년 7월 25일

06_OOP

package edu.kh.oop.cls.model.vo;

public class User {

	// 속성 ( == 필드 )
	// 아이디, 비밀번호, 이름, 나이, 성별 ( 추상화 진행 )
	// 데이터 직접접근 불가원칙 -> 필드는 기본적으로 모두 private ( 캡슐화 진행 )
	private String userId;
	private String userPw;
	private String userName;
	private int userAge;
	private char userGender;
	
	
	
	// 기능 ( == 생성자 + 메서드 )
	
	// 생성자 : new 연산자를 통해서 객체가 생성될 때
	//       생성된 객체의 필드값 초기화 + 기능 수행 역할.
	
	
	// 기본생성자
	public User() {
		// 기능
		System.out.println("기본 생성자로 User 객체 생성");
		
		// 필드 초기화
		userId = "user01";
		userPw = "pass01";
		userName = "홍길동";
		userAge = 20;
		userGender = '남';
		
		// 기본 생성자를 이용해서 User객체를 만들면
		// 그 객체는 프린터 구문을 수행하고,
		// 필드 초기화구문을 거쳐서 홍길동 하나가 만들어짐
		
	}
	
	
	// 매개변수 생성자
	// ** 사용되는 기술 , 변수 : 매개변수, Overloading(오버로딩), this
	
	// ** 매개변수 : 생성자나 메서드 호출 시 ()안에 작성되어
	//              전달되어지는 값을 저장하는 변수
	// -> 전달 받은 값을 저장하고 있는 매개체(지니고있는) 역할의 변수
	public User( String userId , String userPw ) {
		
		System.out.println("매개변수 생성자를 이용해서 User 객체 생성");
		System.out.println(userId + "/" + userPw);
		
		this.userId = userId;
		this.userPw = userPw;
		// 필드     = 매개변수
		
		// 매개변수로 전달받은 값을 필드에 초기화 (this 참조 변수)
		// *** this 참조변수 ***
		// - 객체가 자기 자신을 참조할 수 있도록 하는 변수
		// - 모든 객체 내부에 숨겨져있다.
		// 왜 사용?
		// -> 필드명과 매개변수명이 같을경우
		//  이를 구분하기 위해서 사용한다.
		// 개발자들이 지켜야할 룰: 매개변수명과 필드변수명 동일하게!
		
	}
	
	
	// 필드를 전부 초기화 하는 목적의 매개변수 생성자
	public User( String userId, String userPw, String userName,
			int userAge, char userGender ) {
		
//		System.out.println();
		
		// this() 생성자
		// 같은 클래스의 다른 생성자를 호출할 때 사용
		// 생성자 내에서 반드시 첫번째 줄에 작성되어야한다! 위에 다른코드쓰면 에러
		//Constructor call must be the first statement in a constructor
		// -> 생성자 호출은 반드시 첫번째 줄에 작성해야만 한다!
		// 왜 사용하는가?
		// 중복 코드 제거, 코드 길이 감소, 재사용성 증가
		// 가독성이 좀 어려운 경우가 생길 수 있어서 많이 사용되지 않음.
		
		this(userId, userPw);
		//this.userId = userId;
		//this.userPw = userPw;
		this.userName = userName;
		this.userAge = userAge;
		this.userGender = userGender;
	}
	
	
	// 자바는 기본적으로 필드명, 생성자명, 메소드명, 변수명의
	// 중복을 허용하지 않음.
	//private String userId; // Duplicate field User.userId
	//public User() {} // Duplicate method User() in type User
	
	
	// ** 오버로딩 (Over loading) ** 오버라이딩이랑 면접에서 많이 물어봄..~~
	// - 클래스 내에 동일한 이름의 메서드(생성자도 포함)를
	// 여러개 작성하는 기법
	
	// -> 하나의 이름으로 여러 기능을 수행할 수 있게 하는 것
	
	// [오버로딩 조건]
	// 1) 메서드의 이름이 동일
	// 2) 매개변수의 개수, 타입, 순서 중 1개라도 달라야 함.
	
	//public User() {} // 기본 생성자가 이미 작성되어 있어서 중복
	
	public User(String userId) {} // 매개변수의 개수 같은 생성자 없음
									// 오버로딩 성립
	
	public User(int userAge) {} // 매개변수의 개수는 같지만 타입이 다름
									// 오버로딩 성립
	
	public User(String userId, int userAge) {}
	// 매개변수의 개수와 동일한것은 있으나 하나의 타입이 다름
	
	public User(int userAge, String userId) {}
	// 매개변수의 개수, 타입은 같지만 순서가 다름
	
	//public User(int userAge, String userName) {} // 에러
	// 매개변수의 개수, 타입, 순서가 모두 같아서 오버로딩 불가
	// -> 변수명은 신경쓰지 않는다!


	// 캡슐화로 인한 간접 접근 기능 (getter/setter)
	public String getUserId() {
		return userId;
	}



	public void setUserId(String userId) {
		this.userId = userId;
	}



	public String getUserPw() {
		return userPw;
	}



	public void setUserPw(String userPw) {
		this.userPw = userPw;
	}



	public String getUserName() {
		return userName;
	}



	public void setUserName(String userName) {
		this.userName = userName;
	}



	public int getUserAge() {
		return userAge;
	}



	public void setUserAge(int userAge) {
		this.userAge = userAge;
	}



	public char getUserGender() {
		return userGender;
	}



	public void setUserGender(char userGender) {
		this.userGender = userGender;
	}
	
}
package edu.kh.oop.cls.model.service;

import edu.kh.oop.cls.model.vo.Student;
import edu.kh.oop.cls.model.vo.User;
//import edu.kh.oop.cls.model.vo.TestVO;
// The type edu.kh.oop.cls.model.vo.TestVO is not visible

public class ClsService /*extends Student*/{
					  // 부모 Student를 상속받음

	public void ex1() {
		
		// 클래스 접근 제한자 확인하기
		
		Student std = new Student();
		// public class인 Student는 import 가능
		
		//TestVo test = new TestVo();
		// (default) class인 TestVO는 import 불가(다른패키지)
		
		System.out.println( std.v1 );
		// 다른 패키지에서도 접근 가능한 public 만 에러 X
		
//		System.out.println( std.v2 );
//		System.out.println( std.v3 );
//		System.out.println( std.v4 );
		
		
		// 상속 관계에서 직접 접근 가능 범위
//		System.out.println( v1 ); // public
//		System.out.println( v2 ); // protected
//		System.out.println( v3 ); // default
//		System.out.println( v4 ); // private
		
	}
	
	public void ex2() {
		
		// static 필드 확인 예제
		
		// 학생 객체 2개 생성
		Student std1 = new Student();
		Student std2 = new Student();
		
		// 학생 객체에 name 세팅
		std1.setName("홍길동");
		std2.setName("김영희");
		
		// 정보 출력
		System.out.println(std1.schoolName); // public 이기 때문에 직접 접근 가능 // KH고등학교
		
		// schoolName에 노란줄이 뜨는 이유 -> 제대로 작성을 안해서
		
		// *** static이 붙은 필드(변수)는 '클래스명.변수명' 으로 사용함 ***
		System.out.println(Student.schoolName); // KH고등학교
		
		Student.schoolName = "KH";
		System.out.println("변경후 : " + Student.schoolName); // 변경후 : KH
		
		/* static
		 * 
		 * 1) 공유 메모리 영역(또는 정적 메모리 영역) 이라고 함.
		 * 
		 * why? 프로그램 시작 시 static이 붙은 코드들이 모두
		 * static 영역에 생성되고,
		 * 프로그램이 종료될 때 까지 사라지지 않음 (정적)
		 * 그리고, static 영역에 생성된 변수는 어디서든지 공유 가능(공유)
		 * 
		 * 2) 사용 방법 : 클래스명.변수명
		 * 
		 */

	}
	
	public void ex3() {
		
		// 생성자 확인 테스트
		
		// Student 객체를 기본 생성자를 이용해 생성하고 이를 참조하는 참조변수 s1에 대입
		Student s1 = new Student(); // 기본 생성자에 의해서 Student 객체가 생성됨
						// 기본 생성자
		
		
		// User 기본 생성자를 이용해서 객체 생성
		User u1 = new User(); // 기본 생성자로 User 객체 생성
		
		// User 객체 필드 초기화 확인
		System.out.println( u1.getUserId() ); // user01
		System.out.println( u1.getUserPw() ); // pass01
		System.out.println( u1.getUserName() ); // 홍길동
		System.out.println( u1.getUserAge() ); // 20
		System.out.println( u1.getUserGender() ); // 남
		
		User u2 = new User();
		
		System.out.println( u2.getUserId() ); // user01
		System.out.println( u2.getUserPw() ); // pass01
		System.out.println( u2.getUserName() ); // 홍길동
		System.out.println( u2.getUserAge() ); // 20
		System.out.println( u2.getUserGender() ); // 남
		
		
		// 문제점 : u1이 참조하고 있는 User 객체와
		//          u2가 참조하고 있는 User 객체의 필드 값이 모두 동일함
		//          왜? 같은 기본 생성자로 User 객체를 생성했기 때문에
		
		System.out.println("----------------------------------");
		// 해결 방법 1: setter를 이용해서 새로운 값 대입
		
		u2.setUserId("asdf12345");
		u2.setUserPw("1w2e3e");
		u2.setUserName("김영희");
		u2.setUserAge(19);
		u2.setUserGender('여');
		
		System.out.println( u2.getUserId() ); // asdf12345
		System.out.println( u2.getUserPw() ); // 1w2e3e
		System.out.println( u2.getUserName() ); // 김영희
		System.out.println( u2.getUserAge() ); // 19
		System.out.println( u2.getUserGender() ); // 여
		
		// 해결방법 2: 매개변수 생성자를 이용해서
		//            객체가 생성될 때 부터 다른값으로 필드를 초기화
		
		User u3 = new User("test3", "password333"); // 매개변수 생성자 // test3/password333
		           // 생성자 수행 시 전달할 값을 작성(순서 꼭 지켜야됨!) 
		
		System.out.println( u3.getUserId() );
		System.out.println( u3.getUserPw() );
	}
	
	public void ex4() { // 매개변수 생성자 예제
		
		User u1 = new User(); // 기본생성자
		User u2 = new User("user02", "pass02"); // 매개변수 2개 생성자
		User u3 = new User("user03", "pass03", "김용기", 30, '남');// 매개변수 5개 생성자
		
		System.out.printf("u1 : %s / %s / %s / %d / %c\n",
					u1.getUserId(), u1.getUserPw(), u1.getUserName(),
					u1.getUserAge(), u1.getUserGender()
				); // u1 : user01 / pass01 / 홍길동 / 20 / 남
		
		System.out.printf("u2 : %s / %s / %s / %d / %c\n",
				u2.getUserId(), u2.getUserPw(), u2.getUserName(),
				u2.getUserAge(), u2.getUserGender()
			); // u2 : user02 / pass02 / null / 0 / 
		
		System.out.printf("u3 : %s / %s / %s / %d / %c\n",
				u3.getUserId(), u3.getUserPw(), u3.getUserName(),
				u3.getUserAge(), u3.getUserGender()
			); // u3 : user03 / pass03 / 김용기 / 30 / 남
		
	}
}
package edu.kh.oop.cls.run;

import edu.kh.oop.cls.model.service.ClsService;

public class ClsRun {
	
	public static void main(String[] args) {
		
		ClsService service = new ClsService();
		// 매개변수 아무것도 없는 생성자는 기본 생성자라고 한다.
		// ClsService의 기본 생성자가 작성되어 있지 않지만
		// 문제 없이 사용 가능하다.
		// 왜??
		// 컴파일러가 코드를 번역할 때
		// 클래스 내부에 생성자가 하나도 없다면
		// 자동으로 기본 생성자를 추가해줌(우리 눈엔 안보임)
		
		
		//service.ex2();
		//service.ex3();
		service.ex4();
		
	}

}

06_OOP

메소드 : 객체가 가지고 있는 기능 (ex. 밥을 먹다)
어떤 값(전달 값) = 매개변수
결과값 = return

package edu.kh.oop.method.model.vo;

public class Member {
	
	// 필드
	
	private String memberId; // 아이디
	private String memberPw; // 비밀번호
	private String memberName; // 이름
	private int memberAge; // 나이
	
	
	// 기본 생성자
	// 생성자 규칙 : 반환형이 없고, 클래스와 이름이 같아야한다.
	public Member() {}
	
	// 매개변수 생성자( 필드 모두 초기화 )
	public Member( String memberId, String memberPw, String memberName, int memberAge ) {
		// 오버로딩 적용(매개변수의 개수가 다름)
		
		// 매개변수로 전달받은 값을 필드로 대입시키기.
		this.memberId = memberId;
		this.memberPw = memberPw;
		this.memberName = memberName;
		this.memberAge = memberAge;
	}
	
	// 메서드 (getter/setter 포함)
	// alt + shift + s => r
	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}
	
	public String getMemberId() {
		return memberId;
	}
	
	public void setMemberPw(String memberPw) {
		this.memberPw = memberPw;
	}
	
	public String getMemberPw() {
		return memberPw;
	}
	
	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}
	
	public String getMemberName() {
		return memberName;
	}
	
	public void setMemberAge(int memberAge) {
		this.memberAge = memberAge;
	}
	
	public int getMemberAge() {
		return memberAge;
	}
}
package edu.kh.oop.method.model.service;

import java.util.Scanner;

import edu.kh.oop.method.model.vo.Member;

public class MemberService {
	
	// 속성(필드)
	private Scanner sc = new Scanner(System.in);
	
	private Member memberInfo = null; // 가입한 회원의 정보를 저장할 변수
	private Member loginMember = null; // 로그인한 회원의 정보를 저장할 변수
	
	// 기능(생성자, 메서드)
	
	// 메뉴 화면 출력 기능
	public void displayMenu() {
		// 반환형
		
		int menuNum = 0; // 메뉴 선택용 변수
		
		// 무조건 한번은 반복
		do {
			
			System.out.println("=====회원 정보 관리 프로그램=====");
			System.out.println("1. 회원 가입");
			System.out.println("2. 로그인");
			System.out.println("3. 회원 정보 조회");
			System.out.println("4. 회원 정보 수정");
			System.out.println("0. 프로그램 종료");
			
			System.out.print("메뉴 입력 : ");
			menuNum = sc.nextInt();
			sc.nextLine(); // 입력 버퍼에 남은 개행문자 제거용
			
			switch(menuNum) {
			
			case 1 : System.out.println( signUp() ); break;
			case 2 : System.out.println( login() ); break;
			case 3 : System.out.println( selectMember() ); break;
			case 4 : 
				
				int result = updateMember();
				
				if(result == -1) {
					System.out.println("로그인 후 이용해주세요.");
					
				} else if(result == 0) {
					System.out.println("회원 정보 수정 실패 (비밀번호 불일치)");
					
				} else { // result == 1
					System.out.println("회원 정보가 수정되었습니다.");
					
				}
				
				break;
			case 0 : System.out.println("프로그램 종료.."); break;
			default : System.out.println("잘못 입력하셨습니다.. 다시 입력해주세요");
			
			}
			
		} while(menuNum != 0); // menuNum 0 이면 반복 종료
	}
	
	// 회원 가입 기능
	public String signUp() {
		// (반환형)
		// 해당 메소드가 끝나고 호출한 곳으로 돌아갈 때
		// String 자료형 값을 가지고 돌아간다.
		
		System.out.println("\n ***** 회원가입 *****");
		
		System.out.print("아이디 : ");
		String memberId = sc.next();
		
		System.out.print("비밀번호 : ");
		String memberPw = sc.next();
		
		System.out.print("비밀번호 확인 : ");
		String memberPw2 = sc.next();
		
		System.out.print("이름 : ");
		String memberName = sc.next();
		
		System.out.print("나이 : ");
		int memberAge = sc.nextInt();
		
		
		// 비밀번호, 비밀번호 확인이 일치하면 회원가입
		// 일치하지 않으면 회원가입 실패
		if( memberPw.equals(memberPw2) ) { // 일치하는 경우
			
			// 입력받은 정보를 이용해서 Member 객체 생성한 후
			// 생성된 객체의 주소를 필드에있는 memberInfo에 대입
			memberInfo = new Member(memberId, memberPw, memberName, memberAge);
			
			
			
			
			return "회원가입 성공!!";
			/* 출력 구문 메소드를 호출한곳에서 한번만 쓰고,
			 * return을 이용해 전달할 값을 작성
			 * */
			
			// return : 현재 메소드를 종료하고 호출한 곳으로 돌아감
			// return 아래에 코드 작성 못함, return이 가장 마지막 코드여야 함
			// return 값; : 호출한 곳으로 돌아갈 때 값을 가지고 감.
			
		} else { // 일치하지 않는 경우

			return "회원가입 실패!! (비밀번호 불일치)";
			
		}
	}
	
	
	// 로그인 메서드
	public String login() {
		
		System.out.println("\n*******로그인*******");
		
		// 회원가입을 했는지 부터 확인
		// == memberInfo가 객체를 참조하고 있는지 확인
		
		if(memberInfo == null) { // 회원가입을 먼저 안한 경우
			// null : 아무것도 참조하고 있지 않음
			return "회원 가입부터 진행 해주세요.";
		}
		
		
		System.out.print("아이디 입력 : ");
		String memberId = sc.next();
		
		System.out.print("비밀번호 입력 : ");
		String memberPw = sc.next();
		
		// 회원 가입 정보(memberInfo가 참조하는 Member 객체)에서
		// 저장된 아이디, 비밀번호가
		// 입력된 아이디, 비밀번호와 같으면 "로그인 성공"
		// 아니면 "아이디 또는 비밀번호가 일치하지 않습니다"
		
		// 아이디, 비밀번호가 모두 일치할 경우
		if(memberId.equals(memberInfo.getMemberId()) &&
				memberPw.equals(memberInfo.getMemberPw()) ) {
			// 입력받은 memberId와
			// memberInfo 필드에서 참조중인 Member 객체의 memberId가 같은지 확인
			loginMember = memberInfo;
			// 참조형   = Member객체 주소 (얕은 복사)
			
			// 회원가입정보를 loginMember에 대입하여
			// 어떤 회원이 로그인 했는지를 구분할 수 있게 함.
			
			return loginMember.getMemberName() + "님 환영합니다.";
			
		} else {
			
			return "아이디 또는 비밀번호 일치하지 않습니다.";
			
		}

		
	}
	
	// 회원 정보 조회 기능
	public String selectMember() {
		
		System.out.println("\n***** 회원 정보 조회 *****");
		
		// 1) 로그인 여부 확인
		// 로그인 안했을때 "로그인 후 이용해주세요"
		if(loginMember == null) {
			// loginMember가 참조하는 객체가 없을 경우
			
			return "로그인 후 이용해주세요";
		}
		
		
		// 2) 로그인이 되어있는 경우
		// 회원 정보를 출력할 문자열을 만들어서 반환(return)
		// 단, 비밀번호는 제외
		
		// 이름 : 홍길동
		// 아이디 : user01
		// 나이 : 25세
		String str = "이름 : " + loginMember.getMemberName();
		str += "\n아이디 : " + loginMember.getMemberId();
		str += "\n나이 : " + loginMember.getMemberAge() + "세";
		
		return str;
		
	}
	
	
	// 회원 정보 수정 기능
	public int updateMember() {
		
		System.out.println("\n******회원 정보 수정******");
		
		// 1) 로그인 여부 판별
		// 로그인이 되어있지 않으면 -1 반환
		if(loginMember == null) {
			return -1;
		}
		
		
		// 2) 로그인이 되어있을때
		// 2-1) 수정할 회원 정보 입력 받기 (이름, 나이)
		System.out.print("수정할 이름 입력 : ");
		String inputName = sc.next();
		
		System.out.print("수정할 나이 입력 : ");
		int inputAge = sc.nextInt();
		
		// 2-2) 비밀번호를 입력받아서 로그인한 회원의 비밀번호와 일치하는지 확인
		System.out.print("비밀번호 입력 : ");
		String inputPw = sc.next();
		
		if( inputPw.equals(loginMember.getMemberPw()) ) {
			// -> 비밀번호가 같을 경우
			//      로그인한 회원의 이름, 나이 정보를 입력받은 값으로 변경 후
			// 		1 반환
			
			loginMember.setMemberName( inputName );
			loginMember.setMemberAge( inputAge );
			
			return 1;
		} else {
			// -> 비밀번호가 다를 경우 0 반환
			return 0;
		}
		
	}
	

}
package edu.kh.oop.method.run;

import edu.kh.oop.method.model.service.MemberService;

public class MemberRun {
	
	public       static   void    main(String[] args) {
// [접근제한자] [예약어]  반환형 메서드명([매개변수])	
		// => 대괄호 안에있는건 생략 가능
		
		MemberService service = new MemberService();
		
		// MemberService의 기본생성자가 작성되어있지 않지만
		// 컴파일러가 코드를 번역할 때
		// 클래스 내부에 생성자가 하나도 없다면
		// 자동으로 기본 생성자를 추가해주기 때문에
		// 문제없이 사용 가능!!!
		// *** 주의사항 ***
		// 만약에 생성자가 하나라도 있으면 자동생성 안해준다!
		
		service.displayMenu(); // 메서드 호출
	}

}

0개의 댓글