티스토리 뷰

JAVA

상속(Inheritance)

Y.일월 2019. 9. 17. 11:54

상속(Inheritance)


일상생활에서 상속은 부모가 자식에게 무언가를 물려주는 행위를 말한다.

객체 지향 프로그램에서도 그 의미는 같다.

객체 지향 프로그램에서는 부모클래스가 자식클래스에게 멤버(필드, 메소드)들을 물려주는 것을 뜻한다.


상속을 사용하게 되면, 부모클래스에 있는 필드와 메소드를 자식클래스에 똑같이 쓸 필요가없다.

그러므로, 중복된 코드 방지하고, 개발 시간을 줄여준다.


상속에는 몇가지 주의할 점이 있다.

자바는 다중 상속을 허용하지 않으므로, 단 하나의 부모 클래스만 상속할 수 있다.

부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속대상에서 제외된다.

부모클래스와 자식클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외된다.



클래스를 상속하는 방법은 다음과 같다.


자식클래스 extends 부모클래스 {


//필드

//생성자

//메소드


}


다음은 클래스 상속의 예시 코드이다.


ParentPerson.java

public class ParentPerson {


  //부모클래스

String name;

boolean female;

void wake(int time) {System.out.println(time+"시에 일어납니다.");}

void walk() {System.out.println("걷고 있습니다.");}

void eat(String food) {System.out.println(food+"을(를) 먹고 있습니다.");}

void sleep() {System.out.println("자고 있습니다.");}

}


ChildPerson.java
public class ChildPerson extends ParentPerson {
  //자식 클래스
public ChildPerson(String name, boolean female) {
// TODO Auto-generated constructor stub
this.name = name;
this.female = female;
}
boolean isFemale() {
return female;
}
String getName() {
return name;
}
}

InheritanceEx.java
public class InheritanceEx {

public static void main(String[] args) {
// TODO Auto-generated method stub
ParentPerson parent = new ParentPerson();
ChildPerson child = new ChildPerson("일월", true);
parent.wake(7);
parent.eat("밥");
parent.walk();
parent.sleep();
System.out.println();

System.out.println("이름은 "+child.getName()+ " 입니다.");
System.out.println("여자입니까? "+child.isFemale());
child.wake(8);
child.eat("빵");
child.walk();
child.sleep();
}
}




생성자 오버로딩


모든 객체는 클래스의 생성자를 호출하여 필드를 초기화 시켜야한다.

부모 객체 또한 마찬가지이다.


자식클래스에서 부모 객체를 생성하기 위해서 부모 생성자를 호출할 때는 super() 를 사용한다.

super()는 부모의 기본 생성자를 호출한다.


다음은 생성자 오버로딩의 예시 코드이다.



ParentPerson.java

public class ParentPerson {

String name;

boolean female;

public ParentPerson(String name, boolean female) {

// TODO Auto-generated constructor stub

this.name = name;

this.female = female;

}


boolean isFemale() {

return female;

}

String getName() {

return name;

}

}




ChildPerson.java

public class ChildPerson extends ParentPerson {

int studentNo;

public ChildPerson(String name, boolean female, int studnetNo) {

// TODO Auto-generated constructor stub

super(name, female);

this.studentNo = studnetNo;

}

int getStudentNo() {

return studentNo;

}


}



InheritanceEx.java

public class InheritanceEx {


public static void main(String[] args) {

// TODO Auto-generated method stub

ParentPerson parent = new ParentPerson("아빠",false);

ChildPerson child = new ChildPerson("일월", true, 165);

System.out.println("이름은 "+parent.getName()+ " 입니다.");

System.out.println("여자입니까? "+parent.isFemale());

System.out.println();


System.out.println("이름은 "+child.getName()+ " 입니다.");

System.out.println("여자입니까? "+child.isFemale());

System.out.println("학번은? "+child.getStudentNo());

}

}




메소드 오버라이딩


부모클래스에 있는 메소드들은 자식클래스에 상속된다.

하지만, 자식클래스에서는 부모클래스에 있는 메소드들을 수정해서 사용해야 하는 경우가 있다.


예를 들어. 필드의 정보를 리턴해주는 toString()이라는 메소드가 존재한다고 하자.

부모의 toString()메소드에서는 이름과 성별을 리턴해준다.

하지만, 자식클래스에는 toString()메소드에 학번또한 포함시키고 싶다.

그럴경우 메소드 오버라이딩을 사용한다.


다음은 메소드 오버라이딩의 예시 코드이다.


ParentPerson.java

public class ParentPerson {

String name;

boolean female;

//생성자

public ParentPerson(String name, boolean female) {

// TODO Auto-generated constructor stub

this.name = name;

this.female = female;

}


//메소드

boolean isFemale() {

return female;

}

String getName() {

return name;

}


public String toString() {

return "ParentPerson [name=" + name + ", female=" + female + "]";

}

}



ChildPerson.java

public class ChildPerson extends ParentPerson {

int studentNo;

boolean isStudent = false;

//생성자

public ChildPerson(String name, boolean female) {

super(name, female);

}

public ChildPerson(String name, boolean female, int studentNo) {

super(name, female);

this.studentNo = studentNo;

isStudent = true;

}

//메소드

int getStudentNo() {

return studentNo;

}


@Override //메소드 오버라이딩

public String toString() {

if(isStudent == true)

return "ChildPerson  [name=" + name + ", female=" + female + ", studentNo=" + studentNo + ", isStudent=" + isStudent + "]";

else

return super.toString(); //부모 클래스의 toString() 메소드 호출

}

}



InheritanceEx.java

public class InheritanceEx {


public static void main(String[] args) {

// TODO Auto-generated method stub

ParentPerson parent = new ParentPerson("아빠",false);

ChildPerson child1 = new ChildPerson("일월", true, 165);

ChildPerson child2 = new ChildPerson("이월", false);

System.out.println(parent.toString());

System.out.println(child1.toString());

System.out.println(child2.toString());

}

}



메소드를 오버라이딩할 때는 다음 규칙을 유의해야한다.


1. 부모의 메소드와 동일한 시그너처(리턴 타입, 메소드 이름, 매개 변수 리스트)를 가져야 한다.

2. 접근 제한을 더 강하게 오버라이딩 할 수 없다. 

즉, 부모클래스에서 메소드가 public일 경우, 자식클래스에서 오버라이딩한 메소드가 default, private으로 수정될 수 없다.

3. 새로운 예외는 throws할 수 없다. (뒤에서 학습)

'JAVA' 카테고리의 다른 글

타입변환과 다형성  (0) 2019.09.18
final 클래스와 메소드  (0) 2019.09.17
Getter와 Setter  (0) 2019.09.17
final 그리고, 상수(Static final)  (0) 2019.09.16
접근제한자(Access Modifier)  (0) 2019.09.16
공지사항
최근에 올라온 글