TIL - 10. OOP2 [230725]

송원철·2023년 7월 25일

항상 기억이 나지 않는 아이디와 비밀번호.

인터넷을 사용한다면 항상 따라붙는 로그인.
그 중에서도 자주 만나는 이 화면의 모습을
코딩으로 만들어 보았다.
공인인증서가 그립..진 않았다.

오버로딩

한 클래스 내에 동일한 이름의 메소드를 여러 개 작성하는 기법

오버로딩 조건

  1. 같은 메소드 이름
  2. 다른 매개변수의 개수 또는 다른 매개변수 타입, 순서

this

모든 인스턴스의 메소드에 숨겨진 채 존재하는 레퍼런스로, 할당된 객체를 가리킴
함수 실행 시 전달되는 객체의 주소를 자동으로 받음

 public class Academy{
	    private String name;
	    public Academy() { }
	    public Academy(String name) { this.name = name;  }
    }
    
위와 같이 매개변수를 가지는 생성자에서 매개변수 명이 필드명과 같은 경우 
   매개변수의 변수명이 우선이므로 this 객체를 이용하여 대입되는 변수가 필드라는 것을 구분해줌

메소드

수학의 함수와 비슷하며 호출을 통해 사용, 전달 값이 없는 상태로 호출을 하거나
어떤 값을 전달하여 호출을 하며, 함수 내에 작성된 연산 수행
수행 후 반환 값 / 결과 값은 있거나 없을 수 있음

[접근제한자] [예약어] 반환형 메소드명( [매개변수] ) {
	//  기능 정의
}

public void information() {
	System.out.println(studentNo);
}

메소드 접근제한자

메소드 예약어

메소드 반환형

메소드 매개변수

getter와 setter 메소드

getter

필드에 기록된 값을 읽어서 요청한 쪽으로 읽은 값을 넘기는 메소드

[접근제한자] [예약어] 반환형 get필드명() {
	 return 필드명;
}

public int getStudentNo() {
	return studentNo;
}

setter

필드에 변경할 값을 전달 받아서 필드 값을 변경하는 메소드

[접근제한자] [예약어] void set필드명(자료형 변수명) {
	(this.)필드명 = 자료형 변수명;
}

public void setStudentNo(int studentNo) {
	this.studentNo = studentNo;
}

매개변수 생성자

객체 생성 시 전달받은 값으로 객체를 초기화 하기 위해 사용
매개변수 생성자 작성 시 컴파일러가 기본 생성자를 자동으로 생성해주지 않음
상속에서 사용 시 반드시 기본 생성자를 작성
오버로딩을 이용하여 작성


	// 매개변수 생성자
	// ** 사용되는 기술, 변수 : 매개변수, 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) {} // 에러
	// 매개변수의 개수, 타입, 순서가 모두 같아서 오버로딩 불가
	// -> 변수명은 신경쓰지 않는다!

생성자 확인

		// 문제점 : u1이 참조하고 있는 User 객체와
		// 			u2가 참조하고 있는 User 객체의 필드 값이 모두 동일함
		// 			왜? 같은 기본 생성자로 User 객체를 생성했기 때문에
		
		System.out.println("--------------------------------");
		// 해결 방법 1 : setter를 이용해서 새로운 값 대입
		
		u2.setUserId("asdf12345");
		u2.setUserPw("1q2w3e");
		u2.setUserName("김영희");
		u2.setUserAge(19);
		u2.setUserGender('여');
		
		System.out.println( u2.getUserId() );
		System.out.println( u2.getUserPw() );
		System.out.println( u2.getUserName() );
		System.out.println( u2.getUserAge() );
		System.out.println( u2.getUserGender() );
		
		System.out.println( u1.getUserId() );
		System.out.println( u1.getUserPw() );
		System.out.println( u1.getUserName() );
		System.out.println( u1.getUserAge() );
		System.out.println( u1.getUserGender() );
		
		
		// 해결 방법 2 : 매개변수 생성자를 이용하여
		//				 객체가 생성될 때부터 다른 값으로 필드를 초기화
		
		User u3 = new User("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()
							);
		System.out.printf("u2 : %s / %s / %s / %d / %c\n",
				u2.getUserId(), u2.getUserPw(), u2.getUserName(),
				u2.getUserAge(), u2.getUserGender()
				);
		System.out.printf("u3 : %s / %s / %s / %d / %c\n",
				u3.getUserId(), u3.getUserPw(), u3.getUserName(),
				u3.getUserAge(), u3.getUserGender()
				);
	}

Member

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

public class Member {

	// 필드
	
	// 아이디
	private String memberId;
	// 비밀번호
	private String memberPw;
	// 이름
	private String memberName;
	// 나이
	private int memberAge;
	
	// 기본 생성자
	// 생성자 규칙 : 반환형이 없고, 클래스와 이름이 같아야 한다.
	public Member() {}
	
	//매개변수 생성자 ( 필드 모두 초기화 )
	// constructor 자동완성
		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 String getMemberId() {
			return memberId;
		}
		public void setMemberId(String memberId) {
			this.memberId = memberId;
		}
		public String getMemberPw() {
			return memberPw;
		}
		public void setMemberPw(String memberPw) {
			this.memberPw = memberPw;
		}
	
		public String getMemberName() {
			return memberName;
		}
		public void setMemberName(String memberName) {
			this.memberName = memberName;
		}
		public int getMemberAge() {
			return memberAge;
		}
		public void setMemberAge(int memberAge) {
			this.memberAge = memberAge;
		}
	
	
}

MemberService

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

MemberRun

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(); // 메서드 호출
		service.signUp();
		service.login();
		service.selectMember();
		service.updateMember();
		
		
		
		
		
	}
}
profile
초보자

0개의 댓글