본문 바로가기

국비지원_핀테크

12일차_ [java] 상속 ( Inheritance )

 

 

 

 

 

상속 ( Inheritance )

상속 ( Inheritance )

 

 

package inheritance;

import java.util.ArrayList;

class TestClass03 extends ArrayList<String>{
	// ArrayList 를 상속받은 TestClass03
	
	// 부모 클래스의 get 메소드를 오버라이딩
	@Override
	public String get(int index) {
		System.out.println("데이터를 가져오는 기능");
		return super.get(index);
	}
	
	// 부모 클래스의 add 메소드를 오버라이딩
	@Override
	public boolean add(String e) {
		System.out.println("데이터를 추가했습니다.");
		return super.add(e);
	} 
	
}

public class MainClass03 {
	public static void main(String[] args) {
		TestClass03 tc = new TestClass03();
		tc.add("aaa");
		// 데이터를 추가했습니다.
		
		System.out.println(tc.get(0));
		// 데이터를 가져오는 기능
		// aaa
	}
}

상속과 오버라이딩

상속 - extends 를 사용

오버라이딩 - Alt + Shift + S 후 Override/Implement Methods... 클릭

Override / Implement Methods....

 

상속을 사용한 경우와 사용하지 않은 경우의 코드 차이점 ( 상속을 사용한 경우가 더 간결한 코드로 작성이 가능하다 )

 

상속을 사용하는 이유

- 이미 만들어져 있는 클래스를 재사용하기 때문에 효율적이고 중복된 코드가 줄어든다

- 유지보수가 쉽다

- 확장성이 용이하다

- 재사용이 가능하다

- 코드가 간결해진다

 

 

 

 

 

super

package inheritance;

class Test06 {
	public void test() {
		System.out.println("부모 test 메소드");
	}
}

class TestClass06 extends Test06 {
	public void test() {
		System.out.println("자식 test 메소드");
	}
	public void display() {
		// test 메소드를 실행했을때 자기 자신에게 test 메소드가 없고
		// 부모 클래스에 test 메소드가 있다면 부모의 test 메소드를 실행한다
		
		test(); // 자식 test 메소드 출력
		this.test(); // 자식 test 메소드 출력
		super.test(); // 부모 test 메소드 출력
		
		// super : 부모 클래스를 의미
		// this  : 자기 자신 클래스를 의미
	}
}

public class MainClass06 {
	public static void main(String[] args) {
		TestClass06 tc = new TestClass06();
		tc.display();
	}
}

super 와 this

 

package inheritance;

class Test07{
	public Test07() {
		System.out.println("부모 생성자 실행");
	}
}

class TestClass07 extends Test07{
	public TestClass07() {
		System.out.println("자식 생성자 실행");
	}
}

public class MainClass07 {
	public static void main(String[] args) {
		TestClass07 tc = new TestClass07();
		// 부모 생성자 실행
		// 자식 생성자 실행
		
		// 자식을 객체화 했을때 상속받은 부모의 생성자부터 실행되며
		// 부모의 생성자가 실행된 이후 자식의 생성자가 실행된다
	}
}

상속 받을 경우 생성자의 실행 순서 ( 부모 -> 자식 )

 

package inheritance;

class Test08{
	public Test08(String s) {
		System.out.println(s + "부모 생성자 실행!!!");
	}
}

class TestClass08 extends Test08{
	public TestClass08() {
		// 부모 클래스의 생성자가 문자열을 필요로하기 때문에
		// super(); 안에 문자열을 적어 부모 클래스 생성자를
		// 호출할때 해당 값을 전달한다
		// 이때, 사용하는 super(); 는 무조건 생성자의 맨 첫 줄에
		// 적어야 한다!!!!
		super("값 전달\n");
		System.out.println("자식 생성자 실행!!!");
	}
}

public class MainClass08 {
	public static void main(String[] args) {
		TestClass08 tc = new TestClass08();
		// 값 전달
		// 부모 생성자 실행!!!
		// 자식 생성자 실행!!!
	}
}

부모 클래스의 생성자가 매개변수를 필요로 하는 경우

 

package inheritance;

class Test09{
	public Test09() {
		System.out.println("부모 기본 생성자");
	}
	public Test09(String s) {
		System.out.println(s + " : 부모 생성자");
	}
}

class TestClass09 extends Test09{
	public TestClass09() {
		System.out.println("자식 기본생성자");
	}
	public TestClass09(String s) {
		super(s);
		System.out.println(s + " : 자식 생성자");
	}
}

public class MainClass09 {
	public static void main(String[] args) {
		TestClass09 tc = new TestClass09("전달");
		// 자식 클래스로 이동 > 부모 클래스로 이동
		// super(); 를 통해 부모 클래스로 값을 전달했기 때문에
		// ( 만약 super 를 사용하지 않았다면 부모의 기본 생성자가 실행된다 )
		// 부모 클래스의 매개변수를 필요로 하는 생성자 실행 >
		// 자식 클래스의 매개변수를 필요로 하는 생성자 실행
		
		TestClass09 tc2 = new TestClass09();
		// 자식 클래스로 이동 > 부모 클래스로 이동
		// 부모 클래스의 기본 생성자 실행 > 자식 클래스의 기본 생성자 실행
		// ( 매개변수가 없기 때문에 둘 다 기본 생성자가 실행되었음 )
	}
}

부모 클래스의 매개변수를 전달하는 방법 : super();

 

 

 

 

 

private, protected

package inheritance;

class Test10{
	// 상속을 받든지 말든지 자기 자신을 제외한 모든 접근을 차단
//	private int num = 1000;
	
	// 상속받은 자식 클래스는 접근을 허용
	protected int num = 1000;
}

class TestClass10 extends Test10{
	public int num = 12345;
	public void test() {
		System.out.println("num : " + num);
		
		// 자기 자신의 변수 num 을 출력 후 없다면 부모 클래스의 num 탐색
		System.out.println("this.num : " + this.num);
		
		// 부모 클래스의 변수 num 을 탐색 -> 만약 num 변수가 없다면 컴파일 오류 발생
		System.out.println("super.num : " + super.num);
	}
}

public class MainClass10 {
	public static void main(String[] args) {
		TestClass10 tc = new TestClass10();
		tc.test();
	}
}

private 과 protected 의 차이점

 

 

 

 

 

다중 상속

package inheritance;

class A{
	public void a() {
		System.out.println("a 메소드 실행");
	}
}
class B extends A{
	// A 를 상속
	public void b() {
		System.out.println("bbbb 메소드 실행");
	}
}
class C extends B{
	// A 를 상속한 B 를 상속
	public void c() {
		System.out.println("cccccccc 메소드 실행");
	}
}

public class MainClass11 {
	public static void main(String[] args) {
		// A 를 상속한 B 를 상속한 C 를 객체로 생성
		C c = new C();
		
		// 다중 상속을 통해 A, B, C 의 모든 메소드를 사용할 수 있다
		c.a();
		c.b();
		c.c();
	}
}

중복으로 상속하는 것은 class 에서는 불가능하기 때문에 여러번에 거쳐서 상속을 진행

 

 

 

 

 

 

 

 

 

 

실습 예제

실습 예제

이전에 만들었던 로그인 프로그램을 찾지 못하는 연유로 처음부터 코딩.....

 

package inheritance;

public class MainLogIn {
	public static void main(String[] args) {
		
		LogInService ls = new LogInService();
		while(true) {
			ls.mainPrint();
		}
	}
}

MainLogIn 클래스

 

package inheritance;

import java.text.SimpleDateFormat;
import java.util.Scanner;

public class LogInService extends java.util.Date {
	Scanner sc = new Scanner(System.in);
	LogInDTO DTO = new LogInDTO();
	
	// 메인 메뉴
	public void mainPrint() {
		System.out.println("1. 로그인");
		System.out.println("2. 회원가입");
		System.out.println("3. 탈퇴");
		System.out.print(">>> : ");
		int choice = sc.nextInt();
		
		switch(choice) {
		case 1 : logIn(); break;
		case 2 : createId(); break;
		case 3 : removeId(); useTime(); break;
		default :
			System.out.println("입력 오류!!!");
			break;
		}
	}
	
	// 로그인
	private void logIn() {
		if(DTO.getId() == null) {
			System.out.println("회원 등록부터 진행하세요!");
		}
		else {
			System.out.print("아이디를 입력 : ");
			String id = sc.next();
			System.out.print("비밀번호를 입력 : ");
			String pwd = sc.next();
			
			checkId(id, pwd);
		}
	}
	
	// 로그인 시 아이디 검증
	private void checkId(String id, String pwd) {
		if(DTO.getId().equals(id) && DTO.getPwd().equals(pwd)) {
			System.out.println("!!! " + id + "님 로그인 완료 !!!");
			// 로그인 완료 시 시간 저장
			DTO.setStartTime(System.currentTimeMillis());
		}
		else System.out.println("회원정보가 올바르지 않습니다");
	}
	
	// 회원 생성
	private void createId() {
		if(DTO.getId() == null) {
			System.out.print("아이디 입력 : ");
			String id = sc.next();
			System.out.print("비밀번호 입력 : ");
			String pwd = sc.next();
			
			DTO.setId(id);
			DTO.setPwd(pwd);
			System.out.println("회원가입이 완료되었습니다!");
		}else {
			System.out.println("이미 회원이 존재합니다. 삭제 후 진행하세요");
		}
	}
	
	// 회원 삭제
	private void removeId() {
		DTO.setId(null);
		DTO.setPwd(null);
		System.out.println("회원 탈퇴가 완료되었습니다!!!");
		
		// 회원 삭제 시간 저장
		DTO.setEndTime(System.currentTimeMillis());
	}
	
	// 로그인 시간, 탈퇴 시간, 사용 시간 출력
	private void useTime() {
		SimpleDateFormat si = new SimpleDateFormat("yyyy년 MM월 dd일 aa hh시 mm분 ss초");
		System.out.println("시작 시간 : " + si.format(DTO.getStartTime()));
		System.out.println("종료 시간 : " + si.format(DTO.getEndTime()));
		System.out.println("사용 시간 : " + ((DTO.getEndTime()-DTO.getStartTime()) / 1000) + "초");
	}
}

LogInService 클래스

( java.util.Date 클래스를 상속받아 사용 날짜에 대한 정보를 저장 및 출력 )

 

package inheritance;

public class LogInDTO {
	private long startTime, endTime;
	private String id, pwd;
	
	// getter / setter
	public long getStartTime() {
		return startTime;
	}
	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}
	public long getEndTime() {
		return endTime;
	}
	public void setEndTime(long endTime) {
		this.endTime = endTime;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
}

LogInDTO 클래스

 

 

 

 

 

 

코드 실행
728x90