상속
특징
클래스가 다른 클래스의 속성과 행동방식을 물려받아 구현하는 것 |
상속을 받아 새로 만들어지는 클래스는 자식 클래스(sub class)가 되고 멤버들을 상속해주는 클래스를 부모 클래스(super class)라고한다. (Super Class- Sub Class, Parent Class - Child Class, Base Class-Derived Class) |
객체지향 프로그래밍에서 코드의 재사용성과 확장성을 높임으로써 프로그램의 유지보수를 좀 더 쉽게 해준다. |
사용 방법
상속을 하기 위해서는 extends 키워드를 사용 |
상속을 받은 자식 클래스는 부모 클래스에 선언되어 있는 private 접근 제한 을 갖는 필드와 메소드를 제외한 public, protected, default로 선언되어 있는 모든 변수와 메서드를 물려받아 사용할 수 있다. |
부모클래스가 먼저 생성된 후 자식 클래스가 생성된다. |
final 키워드를 가진 클래스는 상속할 수 없다. |
관계
Is-a 관계 | Has-a 관계 |
extends로 상속 받은 경우 is-a 관계가 형성되었다고 한다. 예 ) public class Child extends Parent |
다른 클래스를 가지고 있는 경우 has-a 관계가 형성되었다. 예) FitnessUI 에서 FitnessService 클래스를 가지고 있는 모습 FitnessService service = new FitnessService(); |
형태
public class Child extends Parent {
...
}
SUPER, SUPER()
super | super() |
- super는 부모 클래스의 멤버를 가리키는 참조변수. - super를 이용해 부모 클래스의 private를 제외한 멤버변수나 메소드에 접근할 수 있다. |
- 부모 객체의 생성자 부모 클래스의 생성자를 호출하는 키워드이다. - super()는 자식 생성자 내 최상단에 위치해야 하며 다른 문장보다 뒤에 있으면 오류이다 - 자바는 자식 클래스가 생성되기 전에 부모 클래스부터 생성을 해야 하므로 개발자가 명시적으로 super()를 사용하지 않아도 자식 클래스의 생성자 내에 super()가 자동으로 삽입된다. |
상속 예제
Parent
class Parent{
private int money = 2000;
// 기본 생성자
public Parent() {
super();
System.out.println("Parent: 기본 생성자");
}
// 외부에서 값을 받아 대입하는
public Parent(int money) {
super();
this.money = money;
System.out.println("Parent: 오버로딩 생성자");
}
public int earning() {
return this.money * 2;
}
public void output() {
System.out.println("부모 현재 자산: " + money + ", 투자 수익: " + this.earning());
}
}
Child
class Child extends Parent {
// 메소드 중 public 인 애들이 상속됨
private int property = 1000;
public Child() {
// super();
System.out.println("Child: 기본 생성자");
super.earning(); // = this.earnning();
}
public int gather() {
return property *= 3;
}
public void print() {
System.out.println("자식 현재 자산: " + property + ", 투자 수익: " + this.gather());
}
}
코드 | 의미 |
super(); | 부모의 기본생성자를 호출 // 안 써도 JVM이 넣는다. |
main
public class InheritanceTest01 {
public static void main(String[] args) {
//Parent p = new Parent();
//p.output();
Child c = new Child();
'//Parent: 기본 생성자
//Child: 기본 생성자
c.output();
c.earning();
c.gather();
c.print();
}
코드 | 출력 |
Parent p = new Parent(); p.output(); |
Parent: 기본 생성자 부모 현재 자산: 2000, 투자 수익: 4000 |
Child c = new Child(); c.output(); |
Parent: 기본 생성자 Child: 기본 생성자 부모 현재 자산: 2000, 투자 수익: 4000 |
c.print(); | 자식 현재 자산: 3000, 투자 수익: 9000 |
오버 라이딩 Overriding
- 상속관계에 있는 클래스에서 이미 정의된 메소드를 지식 클래스에서 같은 시그니처를 갖는 메소드로 다시 정의하는 것
- 오버라이딩은 다형성을 지원하는 중요한 기능
같은 예제에서 Parent는 "Parent: 기본생성자 호출" 하는 출력문만 지웠다.
class Child extends Parent {
// 메소드 중 public 인 애들이 상속됨
private int property = 1000;
public Child() {
// super(); // 안 써도 JVM이 넣는다.
// 부모의 기본생성자를 호출
System.out.println("Child: 기본 생성자");
super.earning(); // = this.earnning();
}
public Child(int property) {
super();
this.property = property;
}
public int gather() {
return property *= 3;
}
@Override // 메소드가 상속받은 걸 재정의 했다는 주석
public void output() {
// public void output(int a) { // 오버로드
super.output();
System.out.println("자식 현재 자산: " + property + ", 투자 수익: " + this.gather());
}
// 멤버를 스트링으로 만들어서 반환하는
// 문자열을 무조건 반환하는 메소드
@Override
public String toString() {
return "Child [property=" + property + "]";
}
}
코드 | 의미 |
@Override | 메소드가 상속받은 걸 재정의 했다는 주석 |
public void output() { super.output(); System.out.println("자식 현재 자산: " + property + ", 투자 수익: " + this.gather()); } |
부모 클래스의 메서드를 오버라이딩 한 후 parent 의 output 쓰고 싶으면 이렇게 사용하면 된다. |
@Override public String toString() { return "Child [property=" + property + "]"; } |
최상위에 존재하는 Object 에 존재하는 toString을 오버라이딩 한 것이다. |
오버로딩과 오버라이딩의 차이점
오버로딩 | 오버라이딩 |
public void output(int a){ .. | @Override public void output() {.. |
오버로딩은 매개변수가 달라진다. | 오버라이딩은 매개변수까지 형태가 아예 똑같다. |
추상클래스 Abstract Class
= 객체는 생성하지 않는 상속 전용 클래스
- 하나 이상의 추상메소드를 포함하거나 class 선언부에 abstract 키워드를 갖고있는 클래스.
- 추상 메소드는 선언만 되어 있고 구현이 없는 메소드를 말한다.
- 추상 클래스는 일반 클래스와 달리 단독으로 객체를 생성할 수 없으며,
반드시 추상 클래스를 실제 클래스 통해서만 객체를 생성할 수 있다.
- 일반 클래스와 동일하게 멤버변수, 생성자, 일반 메소드, 추상메소드(메소드의 본체가 없는 메소드) 가 존재한다.
- 추상클래스를 상속받은 자식클래스도 추상클래스가 된다.
때문에 추상 메소드를 오버라이드 하면 일반 클래스가 되어 객체 생성을 할 수 있다.
- 만약 추상 메소드를 가지고 있지 않다면 바로 일반클래스가 되기 때문에 오버라이드를 할 필요는 없다.
용도
공통의 기능을 정의하여 자식클래스에서 상속받아 사용하기 위해 , 다형성을 구현하기 위해
package ticket.vo;
//public class Ticket { (원래)
public abstract class Ticket { //(추상화)
....
//추상메소드
public abstract void myMethod();
// 이제 상속받은 애들도 추상클래스가 됨
}
package ticket.main;
import ticket.vo.AdvanceTicket;
import ticket.vo.WalkupTicket;
public class TicketMain {
public static void main(String[] args) {
..
Ticket t = new Ticket();
}
}
코드 | 의미 |
public class Ticket { | 객체 생성 가능 |
public abstract class Ticket { | 객체 생성 가능 |
public abstract class Ticket { public abstract void myMethod(); |
객체 생성 불가능. 하지만 사용시에 추상 메소드를 오버라이드 하면 일반 클래스가 되어 객체 생성을 할 수 있다. |
abstract -> interface
상속에서 잠깐 나왔던 '클래스 다이어 그램'을 이해하는데 도움이 되었던 티스토리!
https://brownbears.tistory.com/577
[UML] 클래스 다이어그램 (Class Diagram)
클래스 다이어그램은 구조 다이어그램으로 클래스 내부 구성요소 및 클래스 간의 관계를 도식화하여 시스템의 특정 모듈이나 일부 및 전체를 구조화 합니다. 개발 하기 전, 클래스 다이어그램
brownbears.tistory.com
'국비 교육 > 백엔드(Java, Spring)' 카테고리의 다른 글
[자바] 다형성(polymorphism) 예제 - 도형 프로그램 설계 (0) | 2024.01.29 |
---|---|
[자바] 상속, 오버라이딩, 추상화 클래스 예제 - 입장권 판매 (0) | 2024.01.25 |
[자바] 피트니스 관리 프로젝트 - v3 (0) | 2024.01.25 |
[자바] 피트니스 관리 프로젝트 - v2 (0) | 2024.01.24 |