상속의 정의와 장점
상속 : 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
장점 : 양적으로 적은 양을 통해 코드로 새로운 클래스를 작성할 수 있으며 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 유용하다.
class child extends parent{
...
}
조상 클래스 : 부모(parent)클래스, 상위(super)클래스, 기반(base)클래스
자손 클래스 : 자식(child)클래스, 하위(sub)클래스, 파생된(derived)클래스
상속의 키워드가 extend인 이유
- 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
package object_oriented_programming2;
class Tv {
boolean power;
int channel;
void power() {power = !power;}
void channelUp() {++channel;}
void channelDown() {--channel;}
}
class CaptionTv extends Tv{
boolean caption;
void displayCaption(String text){
if(caption) { //캡션상태가 on일 경우에만 text를 보여준다.
System.out.println(text);
}
}
}
public class CaptionTvTest {
public static void main(String[] args) {
CaptionTv ctv = new CaptionTv();
ctv.channel = 10;
ctv.channelUp();
System.out.println(ctv.channel);
ctv.displayCaption("Hello World");
ctv.caption = true;
ctv.displayCaption("Hello World");
}
}
//결과
11
Hello World
자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.
클래스 간의 관계 - 포함관계
클래스 간의 '포함(composite)'관계를 맺어주는 것이다. 클래스 간의 포함관계를 맺어 주는 것은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻한다.
class Circle{
int x;
int y;
int r;
}
class Circle{
Point c = new Point();
int r;
}
클래스간의 관계 결정하기
클래스를 작성하는데 있어서 상속 관계를 맺어 줄 것인지 포함 관계를 맺어 줄 것인지 결정하기 애매한 경우가 종종 존재한다 그럴 경우에는, '~은 ~이다(is-a)'와 '~은 ~을 가지고 있다(has-a)'를 넣어서 문자을 만들어 보면 클래스 간의 관계가 보다 명확해진다.
원은 점이다.(Circle is a Point), 원은 점을 가지고있다.(Circle has a Point)
→원은 반지름으로 구성되므로 첫번째보다 두번째 문장이 더 옳다는 것을 알 수 있다.
package object_oriented_programming2;
public class DrawShape {
public static void main(String[] args) {
Point [] p = { new Point(100, 100),
new Point(140, 50),
new Point(200, 100)
};
Triangle t = new Triangle(p);
Circle c = new Circle(new Point(150,150),50);
t.draw();
c.draw();
}
}
class Shape{
String color = "black";
void draw() {
System.out.printf("[color=%s]%n", color);
}
}
class Point {
int x;
int y;
Point(int x, int y){
this.x = x;
this.y = y;
}
Point(){
this(0,0);
}
String getXY() {
return "("+x+", "+y+")";
}
}
class Circle extends Shape{
Point center;
int r;
Circle(){
this(new Point(0,0),100);
}
Circle(Point center, int r) {
this.center = center;
this.r = r;
}
void draw() {
System.out.printf("[center = (%d, %d), r=%d, color=%s] %n", center.x, center.y, r,color);
}
}
class Triangle extends Shape{
Point[] p = new Point[3];
Triangle(Point[] p) {
this.p = p;
}
void draw() {
System.out.printf("[p1=%s, p2=%s, p3=%s, color=%s]%n", p[0].getXY(),p[1].getXY(),p[2].getXY(),color);
}
}
//결과
[p1=(100, 100), p2=(140, 50), p3=(200, 100), color=black]
[center = (150, 150), r=50, color=black]
A Circle is a shape. → 원은 도형이다.
A Circle is a shape. → 원은 점이다?
A Circle has a shape. → 원은 도형을 가지고 있다?
A Circle has a Point. → 원은 점을 가지고있다.
카드뽑기
package object_oriented_programming2;
public class DeckTest {
public static void main(String[] args) {
Deck d = new Deck();
Card c = d.pick(0);
System.out.println(c);
d.shuffle();
c = d.pick(0);
System.out.println(c);
}
}
class Deck{
final int CARD_NUM = 52;
Card cardArr[] = new Card[CARD_NUM];
Deck() {
int i = 0;
for(int k=Card.KIND_MAX; k>0; k--)
for(int n=0; n<Card.NUM_MAX; n++)
cardArr[i++] = new Card(k, n+1);
}
Card pick(int index) {
return cardArr[index];
}
Card pick() {
int index = (int)(Math.random() * CARD_NUM);
return pick(index);
}
void shuffle() {
for(int i=0; i<cardArr.length; i++) {
int r = (int)(Math.random() * CARD_NUM);
Card temp = cardArr[i];
cardArr[i] = cardArr[r];
cardArr[r] = temp;
}
}
}
class Card{
static final int KIND_MAX = 4;
static final int NUM_MAX = 13;
static final int SPADE = 4;
static final int DIAMOND = 3;
static final int HEART = 2;
static final int CLOVER = 1;
int kind;
int number;
Card(){
this(SPADE, 1);
}
Card(int kind, int number){
this.kind = kind;
this.number = number;
}
public String toString() {
String[] kinds = {"","CLOVER","HEART","DIAMOND","SPADE"};
String number = "0123456789XJQK";
return "kind : "+kinds[this.kind]+", number : "+number.charAt(this.number);
}
}
//결과
kind : SPADE, number : 1
kind : CLOVER, number : Q
단일상속(single inheritance)
자바는 단일상속만을 허용하고 c++과는 다르게 다중상속을 허용하지 않음.
package object_oriented_programming2;
class Tv2{
boolean power;
int channel;
void power() {power = !power;}
void channelUp() {++channel;}
void channelDown() {--channel;}
}
class VCR {
boolean power;
int counter = 0;
void power() {}
void play() {}
void stop() {}
void rew() {}
void ff() {}
}
class TVCR extends Tv2{
VCR vcr = new VCR();
void play() {
vcr.play();
}
void stop() {
vcr.stop();
}
void rew() {
vcr.rew();
}
void ff() {
vcr.ff();
}
}
Object클래스 - 모든 클래스의 조상
class Tv extends Object {
...
}
출처 : JAVA의 정석 - (남궁성지음)