지난 시간 복습
static : 메모리에 바로 올라가 있다
=> 객체 생성하지 않아도 바로 사용할 수 있다.
extends : 클래스에서 상속받을 때 사용
자식클래스에서 공통 부분은 빼고 이 클래스에서만의 코드를 표현한다면 부모 코드의 중복 코드를 줄일 수 있다.
상속받는 자식 클래스가 1개일 때는 거의 효과가 없지만, 상속받는 클래스가 2개 이상일 때는 효과가 크다.
상속을 사용하면 관리하기가 편하다.
상속 개념을 배운 후에는 접근 지정자 중 default 와 protected 의 쓰임이 이해가 된다.
자식 클래스에서도 부모 클래스의 method를 똑같이 정의 할 수 있다
=> method가 본인의 class 안에 있다면 그걸 먼저 출력하고, 없다면 부모 class에서 찾아서 출력, 둘 다 없다면 error
=> 이걸 override, 재정의 라고 한다.
재정의가 필요한 이유
상속을 사용할 때에 상속받는 입장에서 여러 번 사용할 때, 10번 중 8번은 그냥 사용해도 문제가 없으나 2번은 문제가 생길 때, 해당 class 안에서 재정의해서 사용
처음 만들었을 때는 문제가 없었으나 나중에 다른 부분을 추가할 때, 기존의 부모 class를 함부로 변형시키면 어느 자식 class 에서 오류가 발생할 지 모르므로 필요한 class 에서만 재정의해서 사용.
객체를 배우고 나서는 program 이 진행되는 '흐름' 이 중요함
super : 부모 class 를 의미함.
=> superCall 안의 super.doStudy(); 에서 부모 class 의 doStudy를 불러오고, this.doStudy(); 에서 본인의 doStudy를 불러오게 되어서 위와 같은 결과가 출력된다.
이름
점수 : 국어, 영어, 수학
누구의 총점은 300
누구의 평균은 100
계산은 Score에서 처리 리턴
메인에서 출력
package com.tech.gt006.score2;
public class ScoreTest {
public static void main(String[] args) {
// 이름
// 점수 : 국어, 영어, 수학
// 누구의 총점은 300이다
// 누구의 평균은 100이다
// 계산은 Score에서 처리 리턴
// 메인에서 출력
Score sc=new Score();
sc.sendScores(100,100,100);
sc.sendName("홍길동");
System.out.println(sc.getName()+"총점 : "+sc.getTotal());
System.out.println(sc.getName()+"평균 : "+sc.getAvg());
}
}
ScoreTest class (main)
package com.tech.gt006.score;
public class Score {
private int kor;
private int eng;
private int math;
private String name;
// 필드에 값 전달
public void sendScores(int k, int e, int m) {
kor=k;
eng=e;
math=m;
}
// 필드에 값 전달
public void sendName(String n) {
name=n;
}
public int getTotal() {
int total=kor+eng+math;
return total;
}
public float getAvg() {
float avg=(kor+eng+math)/3.0f;
return avg;
}
public String getName() {
return name;
}
}
Score class
결과
홍길동총점 : 300
홍길동평균 : 100.0
생성자 활용
생성자는 return 타입이 없고, 이름은 대문자로 시작
package com.tech.gt006.score2;
public class ScoreTest {
public static void main(String[] args) {
// 이름
// 점수 : 국어, 영어, 수학
// 누구의 총점은 300이다
// 누구의 평균은 100이다
// 계산은 Score에서 처리 리턴
// 메인에서 출력
// 생성자 활용
Score sc1=new Score(100,100,100);
Score sc2=new Score("홍길동");
System.out.println(sc2.getName()+"총점 : "+sc1.getTotal());
System.out.println(sc2.getName()+"평균 : "+sc1.getAvg());
}
}
ScoreTest class (main)
package com.tech.gt006.score2;
public class Score {
private int kor;
private int eng;
private int math;
private String name;
// 생성자를 통한 필드로의 값 전달
public Score(int kor, int eng, int math) {
this.kor=kor;
this.eng=eng;
this.math=math;
}
// 생성자를 통한 필드로의 값 전달
public Score(String name) {
this.name=name;
}
public int getTotal() {
int total=kor+eng+math;
return total;
}
public float getAvg() {
float avg=(kor+eng+math)/3.0f;
return avg;
}
public String getName() {
return name;
}
}
Score class
결과
홍길동총점 : 300
홍길동평균 : 100.0
생성자 한번에 쓰기
package com.tech.gt006.score3;
public class ScoreTest {
public static void main(String[] args) {
// 이름
// 점수 : 국어, 영어, 수학
// 누구의 총점은 300이다
// 누구의 평균은 100이다
// 계산은 Score에서 처리 리턴
// 메인에서 출력
// 생성자 활용
Score sc1=new Score("홍길동",100,100,100);
System.out.println(sc1.getName()+"총점 : "+sc1.getTotal());
System.out.println(sc1.getName()+"평균 : "+sc1.getAvg());
}
}
ScoreTest.java (main)
package com.tech.gt006.score3;
public class Score {
private int kor;
private int eng;
private int math;
private String name;
// 생성자를 통한 필드로의 값 전달
public Score(String name, int kor, int eng, int math) {
this.name=name;
this.kor=kor;
this.eng=eng;
this.math=math;
}
public int getTotal() {
int total=kor+eng+math;
return total;
}
public float getAvg() {
float avg=(kor+eng+math)/3.0f;
return avg;
}
public String getName() {
return name;
}
}
Score.java
결과
홍길동총점 : 300
홍길동평균 : 100.0
생성자 연습
package com.tech.constructor;
public class ConstructClass {
public static void main(String[] args) {
ConstructClass ct=new ConstructClass(); // 기본 생성자
ConstructClass ct2=new ConstructClass("홍길동"); // 사용자 생성자
ConstructClass ct3=new ConstructClass("홍길동",100); // 사용자 생성자
}
public ConstructClass() { // 기본 생성자
System.out.println("기본생성자");
}
public ConstructClass(String name) { // 사용자 생성자
System.out.println("사용자생성자");
}
public ConstructClass(String name, int score) { // 사용자 생성자
System.out.println("사용자생성자2 "+score);
}
}
결과
기본생성자
사용자생성자
사용자생성자2 100
추상 method 는 일반 method 에서 {} 부분이 없는 형태를 가진다.
method 이름만 정해져 있고, 기능은 정해져 있지 않은 형태.
=> abstract keyword가 들어가야 한다.
class 안에 1개 이상의 추상 method 가 들어가게 되면 추상 class가 된다.
package com.tech.one.abs;
public abstract class Employee { // 추상클래스
public abstract void getMonthPay(); // 추상메소드
}
package com.tech.one.abs;
public class RegularEmployee extends Employee{
@Override
public void getMonthPay() {
// TODO Auto-generated method stub
System.out.println("급여계산");
}
}
팀 project 등을 할 때, 통일성을 주기 위해 method 이름을 통일시키는 경우, 상위 그룹에서 하달하는 method 이름은 통일시키고, 하위 그룹에서 작업 할 때는 상속받아서 override 해서 사용한다.
또는
ex) 동물은 각자 다른 소리를 내기 때문에 sound() 라는 method 를 선언하고, 각 동물마다 상속해서 ovrride 해서 각 동물의 소리를 출력하는 등으로 사용한다.
더 진화된 기능으로 interface 가 있는데, 개념은 추상 method와 같다.
Overloading (오버로딩) : 과적
Overriding (오버라이딩) : 재정의
이 두가지를 구분해서 설명할 수 있어야 함.
면접에서 들어올 수 있는 질문
method overloading : 메소드 이름은 같되, 매개변수의 타입, 개수, 순서가 다른 method 를 여러 개 선언하는 것을 말한다.
method overriding : 상속된 method 를 자식 class 에서 재정의하는 것을 말한다. method overriding 된다면 해당 부모 method 는 숨겨지고, 자식 method 가 우선적으로 사용된다.
주의사항
1. 부모 method 의 선언부 (return type, method 이름, 매개변수) 와 동일해야 한다.
2. 접근 제한을 더 강하게 overriding 할 수 없다.
3. 새로운 예외를 throws 할 수 없다.
package com.tech.gt002;
public class EployeeTest {
public static void main(String[] args) {
Employee[] emps=new Employee[4]; // 배열선언
emps[0]=new RegularEmployee("E001","홍길동",3000,500);
emps[1]=new PartTimeEmployee("E002","임꺽정",4000,0);
emps[2]=new TempEmployee("E003","황진이",6000,10);
emps[3]=new RegularEmployee("E004","임꺽정3",5000,1500);
// 사번, 이름, 페이, 보너스
for (int i = 0; i < emps.length; i++) {
printPay(emps[i]);
}
}
private static void printPay(Employee emp) {
System.out.println("===================");
System.out.println(emp);
System.out.println(emp.getMonthPay());
System.out.println("===================");
}
}
EmployTest.java (main)
package com.tech.gt002;
public abstract class Employee {
private String empno;
private String name;
protected int pay;
public Employee(String empno, String name, int pay) {
this.empno=empno;
this.name=name;
this.pay=pay;
}
public abstract double getMonthPay(); // 추상메소드
@Override
public String toString() {
return empno+":"+name+":"+pay;
}
}
Employ.java
package com.tech.gt002;
public class RegularEmployee extends Employee{
private int bonus;
public RegularEmployee(String empno, String name, int pay, int bonus) {
super(empno,name,pay);
this.bonus=bonus;
}
@Override
public double getMonthPay() {
// 페이 계산
return (pay/(double)12) +(bonus/(double)12);
}
}
RegularEmployee.java
package com.tech.gt002;
public class PartTimeEmployee extends Employee {
private int workDay;
public PartTimeEmployee(String empno, String name, int pay, int workDay) {
super(empno, name, pay);
this.workDay=workDay;
}
@Override
public double getMonthPay() {
return (pay/(double)12);
}
}
PartTimeEmployee.java
package com.tech.gt002;
public class TempEmployee extends Employee {
private int hireyear;
public TempEmployee(String empno, String name, int pay, int hireyear) {
super(empno, name, pay);
this.hireyear=hireyear;
}
@Override
public double getMonthPay() {
return (pay/(double)12);
}
}
TempEmployee.java
결과
===================
E001:홍길동:3000
291.6666666666667
===================
===================
E002:임꺽정:4000
333.3333333333333
===================
===================
E003:황진이:6000
500.0
===================
===================
E004:임꺽정3:5000
541.6666666666667
===================
미션
점심메뉴를 가지고 위와 같은 프로그램를 만들어 보세요
fname : 음식 이름
fprice : 음식 단가
fperson : 인원수
getTotal : 추상메소드
package com.tech.gt003.lunch;
public class LunchTest {
public static void main(String[] args) {
Lunch[] lch=new Lunch[3];
lch[0]=new ChinaLunch("짜장면",6000,2);
lch[1]=new OrientLunch("쌀국수",8000,4);
lch[2]=new WestLunch("파스타",12000,3);
for (int i = 0; i < lch.length; i++) {
printLch(lch[i]);
}
}
private static void printLch(Lunch order) {
System.out.println("================");
System.out.println(order);
System.out.println("총금액:"+order.getTotal());
System.out.println("================");
}
}
LunchTest.java (main)
package com.tech.gt003.lunch;
public abstract class Lunch {
// fname : 음식 이름
// fprice : 음식 단가
// fperson : 인원수
// 추상메소드 getTotal
private String fname;
private int fprice;
private int fperson;
public Lunch(String fname, int fprice, int fperson) {
this.fname=fname;
this.fprice=fprice;
this.fperson=fperson;
}
public abstract int getTotal();
@Override
public String toString() {
return "메뉴:"+fname+","+"가격:"+fprice+","+"인원수:"+fperson;
}
}
Lunch.java
package com.tech.gt003.lunch;
public class ChinaLunch extends Lunch {
private int sum;
public ChinaLunch(String fname, int fprice, int fperson) {
super(fname,fprice,fperson);
this.sum=fprice*fperson;
}
public int getTotal() {
return sum;
}
}
ChinaLunch.java
package com.tech.gt003.lunch;
public class OrientLunch extends Lunch {
private int sum;
public OrientLunch(String fname, int fprice, int fperson) {
super(fname,fprice,fperson);
this.sum=fprice*fperson;
}
public int getTotal() {
return sum;
}
}
OrientLunch.java
package com.tech.gt003.lunch;
public class WestLunch extends Lunch {
private int sum;
public WestLunch(String fname, int fprice, int fperson) {
super(fname,fprice,fperson);
this.sum=fprice*fperson;
}
public int getTotal() {
return sum;
}
}
WestLunch.java
결과
================
메뉴:짜장면,가격:6000,인원수:2
총금액:12000
================
================
메뉴:쌀국수,가격:8000,인원수:4
총금액:32000
================
================
메뉴:파스타,가격:12000,인원수:3
총금액:36000
================