미니멜로디

자바 객체지향 프로그래밍 - 상속, 다형성 본문

프로그래밍/자바

자바 객체지향 프로그래밍 - 상속, 다형성

미니멜로디 2018.02.25 16:34

상속

A is a B : A 는 B 다 - A는 B를 상속받아 결국 A는 B의 것을 가지게 된다
객체지향 프로그래밍에서는 상속이라는 개념 사용


상속 받은 필드가 private 이라면?
자식 클래스에서는 상속 받은 필드가 private 되어 있으면 직접적인 접근은 불가능하나,
상속 받은 필드에 접근하기 필요성이 있을때에는 크게 3가지 방법을 통해 접근할 수 있다


1. 필드는 private으로 선언하지 않고 protected로 선언
2. 부모의 setter를 이용
3. 자식 생성자에서 사용할 수 있는 super 키워드로 부모 생성자 호출


다형성

상속을 이용한 기술로 상속 관계에 있는 부모, 자식 클래스 간에 부모 타입은 모든 후손 타입을 받아 줄 수 있다
부모 클래스 타입의 레퍼런스가 후손 객체의 주소를 저장할 수 있다는 뜻 (후손 객체 안에 부모 멤버가 포함되어 있기 때문에 가능)
부모 레퍼런스를 통해 객체의 접근시 부모가 가지고 있는 메소드만 사용 가능 (부모레퍼런스이지만 자식의 메소드를 호출하려면 다운캐스팅)


메소드 오버라이딩
부모 클래스의 메소드를 상속받지 않고 자신이 재정의 할때 사용하는 것
- Annotation (애너테이션, 어노테이션)
자바 소스코드에 추가하여 사용할 수 있는 메타데이터의 일종
'@' 기호를 붙여 사용하며 가상 머신에게 해당 문법에 대해 알려준다
메소드 오버라이딩시에는 @Override를 명시하여 오버라이드 된 메소드임을 JVM에게 알려준다 (생략하여도 자동으로 @Override가 명시)


abstract (추상화)
추상이라는 의미를 가지고 있는 키워드
메소드를 abstract로 만들경우 부모 클래스는 자신을 상속 받는 자식들에게 해당 메소드를 강제적으로 생성하라는 의미
(부모는 기능이 없는 메소드를 만든것이고 해당 기능을 가진 메소드를 자신을 상속 받은 자식들이 오버라이딩해서 정의하라는 의미)
abstract 메소드를 포함하고 있는 클래스는 불완전한 클래스 (기능이 없는 메소드를 가지고 있는 클래스가 객체화 되면 안된다)
그렇기 때문에 abstract 메소드를 포함하고 있는 클래스는 객체화 할 수 없도록 클래스 명 앞에 abstract 키워드를 붙여서 추상클래스로 선언 
(추상 클래스는 객체화 할 수 없는 클래스를 의미)


추상 클래스 (미완성된 클래스) : 객체 생성을 막아놓은 클래스 (추상 메소드가 없어도 명시할 수 있다)


public abstract class 클래스명 { }


클래스 안에 추상 메소드를 가지고 있으면 해당 클래스는 반드시 추상 클래스가 되어야 한다
추상 클래스를 상속받은 후손 클래스는 반드시 부모의 추상 메소드를 완성시켜야 하는 강제성이 부여되어,
후손은 추상 메소드를 반드시 오버라이딩 해서 선언 해두어야 한다


추상 메소드 (미완성된 메소드) : 메소드의 헤드(Head)만 있고, 몸체(Body : 내용)가 없는 메소드


public abstract 반환자료형 메소드명([자료형 매개변수]);


표준화된 인터페이스를 제공할 목적으로 추상메소드를 사용한다
메소드 사용의 통일성을 확보하고 메소드 제작을 강제화 한다



문제. 급여관리 시스템 제작하기

요구사항

1. has a 포함관계 is a 상속관계를 구현할것 !

2. VO 클래스와 controller 클래스를 나눌것 !

3. 확장성을 고려할것 ! (다형성)

4. 첫번째 VO 클래스 이름 : Permanent (정규직) - kh.java.pay.model.vo

5. Permanent 의 멤버필드 : 이름 , 분류, 급여 (3가지)

6. 멤버메소드 : setter, getter, 생성자 

7. 두번째 VO 클래스 이름 : PartTime (시간직) - kh.java.pay.model.vo

8. Parttime 의 멤버필드 : 이름 , 분류 , 시급, 일한시간 (4가지)

9. 자식 클래스들의 멤버메소드 : setter, getter, 생성자 , 급여getter 추가로 만들어야함

10. controller 클래스  이름 : PayMgr (급여매니저) - kh.java.pay.controller

11. Paymgr 의 멤버필드 : 직원10명관리할수 있는 객체 배열!!, 인덱스 

12 Paymgr 의 멤버메소드 : insertData, printData, 생성자 

13. 실행형 클래스에서 아래와 같이 실행 - kh.java.pay.run.TestMain

PayMgr p = new PayMgr();

p.insertData(new Permanent("홍길동","정규직",2000000));

p.insertData(new PartTime("김말똥","시간직",6000,200));

< < = = = = = = 출력결과 = = = = = = = > >

이름 분류 급여

길똥이 정규직 2000000

개똥이 시간직 1200000

만족 할때쯤 점검 !! 인턴직을 추가 해본다. 그때 컨트롤 클래스에 손이 가면 

다형성이 실패한것이다. (인터직은 급여 * 80 % )  

멤버변수는 정규직과 같다. 다만 급여*80%

p.insertData(new intern("김인턴","인턴직",2000000); // 김인턴 인턴직 1600000  이 출력


PayMgr p = new PayMgr();

p.insertData(new Permanent("홍길동","정규직",2000000));

p.insertData(new PartTime("김말똥","시간직",6000,120));

p.insertData(new Intern("삼국지","인턴직",2000000));

p.printData();


Permanent, PartTime, Intern의 부모 클래스

package kh.java.pay.model.vo;


public abstract class Job {

private String name;

private String job;

public Job() {}

public Job(String name, String job

{

this.name = name;

this.job = job;

}

public void setName(String name) {this.name = name;}

public void setJob(String job) {this.job = job;}

public String getName() {return name;}

public String getJob() {return job;}

public abstract int getPay();

}


Permanent.java

package kh.java.pay.model.vo;


public class Permanent extends Job{

private int pay;

public Permanent() {}

public Permanent(String name, String job,int pay)

{

super(name,job);

this.pay = pay;

}

@Override

public int getPay() 

{

return pay;

}

}


PartTime.java

package kh.java.pay.model.vo;


public class PartTime extends Job{

private int payHour;

private int payWork;

public PartTime() {}

public PartTime(String name, String job, int payHour, int payWork)

{

super(name,job);

this.payHour = payHour;

this.payWork = payWork;

}

@Override

public int getPay() {

return payHour * payWork;

}

}


Intern.java

package kh.java.pay.model.vo;


public class Intern extends Job{

private int pay;

public Intern() {}

public Intern(String name, String job, int pay)

{

super(name, job);

this.pay = pay;

}

@Override

public int getPay() {

return (int)(pay*0.8);

}

}


PayMgr.java

package kh.java.pay.controller;


import kh.java.pay.model.vo.*;


public class PayMgr {

private Job [] j = new Job [10];

private int index = 0;

public PayMgr() {}

public void insertData(Job j)

{

this.j[index++] = j;

}

public void printData()

{

System.out.println("<<====== 출력결과 ======>>");

System.out.printf("%-15s %-15s %-15s \n", "이름","분류","급여");

for(int i=0;i<index;i++)

{

System.out.printf("%-13s %-13s %-15d \n", j[i].getName(),j[i].getJob(),j[i].getPay());

}

}

}


TestMain.java

package kh.java.pay.run;


import kh.java.pay.controller.PayMgr;

import kh.java.pay.model.vo.*;


public class TestMain {

public static void main(String[] args) {

PayMgr p = new PayMgr();

p.insertData(new Permanent("홍길동","정규직",2000000));

p.insertData(new PartTime("김말똥","시간직",6000,200));

p.insertData(new Intern("삼국지","인턴직",2000000));

p.printData();

}

}



0 Comments
댓글쓰기 폼