자바기반의 웹&앱 응용 SW개발자 양성과정 16일차 -30
1)Is a 상속
전 시간에 has a 상속에 알아봤다면 이번에는 기존클래스를 재사용할수 있는 is a상속에대해 정리를 해볼려고합니다.
has a 상속만으로 프로그램을 구현하기위해서는 원하는 각 부품을 모아서 만드는 방법이있습니다. 부품이 전부 있다면 되겠지만 한부분이 없다면? 직접구현하거나 비슷한 다른 틀을 가져와서 원하는 부품으로 만든뒤 다시 부품을 조립하는 방법이있습니다.
바로 비슷한 틀을 가져와서 원래 목적에맞게 조금만 수정하게되어 사용하게된다면 생산성이 굉장히 높아지고 소요비용도 절감될 수 있습니다. 그틀을 우리는 FrameWork이라고 합니다.
a has a b 관계가 있다는 말은 a제품을 만들 때 b제품을 부품으로 사용했다는말이고
a is a b 관계가 있다는 말은 a제품을 만들 때 b제품을 뼈대로 사용했다는 말이됩니다.
그럼 어떻게 틀을 가져와서 수정을 하게될까요 ?
이전에 작성했던 성적을 입력과 출력하는 프로그램을 틀로써 사용하고 원하는 기능을 추가하는 방법을 알아보겠습니다.
추가적인 성적인 com과목을 추가만해서 틀의 기능을 이용해보겠습니다.
먼저 exam클래스를 프레임워크로 사용하기위해선 extends라는 키워드를 사용합니다.
public class NewlecExam extends Exam{
}
그럼 exam의 기능을 쓸수있는지 NewlecExam클래스에서 exam의 기능을 사용해 보겠습니다.
public class NewlecExam extends Exam {
private int com;
public static void main(String[] args) {
NewlecExam exam = new NewlecExam();
exam.setKor(10);
exam.setEng(10);
exam.setMath(10);
System.out.printf("total is %d \n", exam.total());
System.out.println(exam.avg());
}
출력결과는 30, 10이 나오게됩니다. 구현을 하지않아도 exam에 있는 기능을 상속받아서 사용할수 있는것입니다.
상속 관계를 정의하는 말은 여러가지의 개념이있습니다.
부모 클래스 <-> 자식클래스
상위 클래스 <-> 하위클래스
기반 클래스 <-> 파생클래스
...동일한 말이니까 문맥적으로 파악하시면 될꺼같습니다.
public class NewlecExam extends Exam {
private int com;
public static void main(String[] args) {
NewlecExam exam = new NewlecExam();
exam.setKor(10);
exam.setEng(10);
exam.setMath(10);
exam.setCom(10);
System.out.printf("total is %d \n", exam.total());
System.out.println(exam.avg());
}
이렇게 하면 total();의 값이 40이 나올까요? 그렇지 않습니다. 부모의 total메서드는 kor eng math의 성적에 한해서 총점을 구하기때문입니다. 즉 total메소드를 exam이 구현했기 때문입니다. 그렇다면 어떻게해야할까요.
이때 필요한것이 Override입니다.
내가 원하는데로 total이라는 메소드를 NewlecExam클래스안에서 구현해야합니다. 제가 원하는 com이라는 변수값을 추가해서요
@Override
public int total() {
return super.total() + com;
}
그렇게된다면 원하는 결과를 얻을 수 있습니다.
메소드를 호출할때 자바는 참조형식 대신 객체를 우선순위로 두고 메소드를 실행시키게됩니다.
즉 newlecExam객체를 사용하기때문에 total 메소드를 호출하면 자신의 메소드를 먼저 호출하게됩니다.
만약 total메소드가 없다면 부모의 total메소드를 불러오겠죠 즉 덮어쓴다는 이야기입니다.
여기서 super라는 키워드가 있는데요 this는 자신의 객체 자기 자신을 의미한다면
super는 상위 즉 부모를 의미하게됩니다.
return super.total() + com;
부모의 total메소드를 실행시키고 그뒤에 com이라는 int형 변수값을 더해서 리턴하라는 의미입니다.
만약 부모의 속성에 초기값을 주면서 객체를 생성하고 싶다면 우리는 생성자함수를 사용할 것입니다.
그럼 setter를 이용해서 생성자함수 안에 전부 입력해주어서 객체를 만들어야할까요? 코드가 너무깁니다.
그러면 우리는 super를 이용하는 겁니다.
public NewlecExam() {
super(10, 10, 10);
com = 10;
}
매개변수로 원하는 값을 넣어줄수도 있겟죠.