자바에서 클래스 상속이란?
: 새로운 클래스를 정의할 때 기존에 정의된 클래스가 갖는 속성과 메소드를 모두 물려받고 자신의 속성과 메소드를 추가로 갖는 것
- 상속은 객체지향 프로그래밍의 가장 큰 특징이다.
- 상속을 사용하면 재사용성과 확장성을 높일 수 있다.
- 재사용성 : 이미 정의된 클래스의 코드를 다시 작성할 필요 없이 자식 클래스에서 사용할 수 있게 해준다. 코드의 중복을 줄이고, 기존 코드를 재활용할 수 있다.
- 확장성 : 기존 클래스를 확장하여 새로운 기능을 추가하거나, 기존기능을 변경하는 것이 매우 쉽다.
클래스의 계층 구조
슈퍼클래스 : 상위의 현존하는 클래스
파생클래스 or 서브 클래스 : 속성과 메소드를 물려받아 새로 정의한 하위의 클래스
자바언어에서 최상위에 Object 클래스를 갖으며 이 클래스가 갖고 있는 속상과 메소드를 상속받아서 하위 클래스를 이루는 구조를 하고 있다. 명시하지 않아도 암묵적으로 Object 클래스를 상속받는다.
Object 클래스의 주요 메서드
toString() : 문자열 표현
equals(Obejct obj) : 두 객체가 동일한지를 비교
hashCode() : 객체의 해시 코드 반환
getClass() : 객체의 런타임 클래스 정보를 반환
clone() : 객체의 복사본을 생성
finalize() : 객체가 가비치 컬렉터에 의해 회수되기 직적에 호출
Object 클래스를 최상위 클래스로 만들어둔 이유
-> 일관성 있는 객체 관리, 재사용성, 유연한 프로그래밍 모델 제공
상속 구현
Adam 클래스
public class Adams {
public String adam = "나는 동물이다.";
}
Adam 클래스를 상속받은 Mams 클래스
public class Mams extends Adams{
String mam = "나는 포유류이다.";
}
Mams 클래스를 상속받은 Dogs, Cows, Horses 클래스
public class Dogs extends Mams{
public String dog = "나는 강아지이다.";
}
public class Cows extends Mams{
public String cow = "나는 젖소이다.";
}
public class Horses extends Mams{
public String horse = "나는 망아지이다.";
}
상속 테스트 코드
public class InheritanceTest_01 {
public static void main(String[] args) {
// Adams 클래스로부터 adams 객체를 생성
Adams adams = new Adams();
System.out.println(adams.adam);
System.out.println();
// Mams 클래스는 Adams 클래스를 상속받아서 mams 객체를 생성
Mams mams = new Mams();
System.out.println(mams.adam);
System.out.println(mams.mam);
System.out.println();
// Dogs 클래스는 Mams 클래스를 상속받아서 dogs 객체를 생성
Dogs dogs = new Dogs();
System.out.println(dogs.adam);
System.out.println(dogs.mam);
System.out.println(dogs.dog);
System.out.println();
// Cows 클래스는 Mams 클래스를 상속받아서 cows 객체를 생성
Cows cows = new Cows();
System.out.println(cows.adam);
System.out.println(cows.mam);
System.out.println(cows.cow);
System.out.println();
// Horses 클래스는 Mams 클래스를 상속받아서 horses 객체를 생성
Horses horses = new Horses();
System.out.println(horses.adam);
System.out.println(horses.mam);
System.out.println(horses.horse);
}
}
-> 자신보다 상위 클래스들의 멤버변수를 사용할 수 있다. (접근 제어자에 따라 차이가 있음)
super와 super() 메소드
super : 서브 클래스에서 슈퍼클래스의 멤버변수나 메소드를 접근해야 하는 경우에 사용
예시
부모 클래스
public class Parents {
String parentName = "붕몽닝";
int parentAge = 99;
public void parentInfo() {
System.out.printf("부모 이름은 %s이고, 나이는 %d세 이다. \n",parentName,parentAge);
}
}
자식 클래스
public class Childs extends Parents{
String childName = "유진이";
int childAge = 25;
public void childInfo() {
// 상위 클래스의 멤버변수에 값을 할당 시 super. 멤버변수 사용
super.parentName = "우리엄마";
super.parentAge = 52;
// 상위 클래스의 patentInfo() 메소드를 사용 시 super.메소드이름() 사용하여 Overriding
super.parentInfo();
System.out.printf("나의 이름은 %s이고, 나이는 %d살 이다.\n",childName,childAge);
}
}
테스트 코드
public class SuperTest_01 {
public static void main(String[] args) {
// Parents 클래스로부터 parents 객체 생성
Parents parents = new Parents();
parents.parentInfo();
System.out.println();
// Parents 클래스로부터 상속 받아서 childs 객체 생성
Childs childs = new Childs();
childs.childInfo(); // 위의 parents 객체의 parent 정보까지 바뀌는건 아님
}
}
-> super.parentName 같은 형식으로 부모클래스의 멤버변수에 접근할 수 있다.
super() 메소드 : 슈퍼클래스의 생성자를 호출할 때 사용
* 서브클래스의 생성자에서 가장 첫 줄에 작성해야함
사용 예시
상위 클래스 Employee
public class Employee {
public String name;
public int age;
// 생성자로 멤버변수를 초기화
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
// 결과 출력
public void employeeInfo() {
System.out.printf("선수: 이름 = %s, 나이 = %d세\n",name,age);
}
}
하위 클래스 Manager
public class Manager extends Employee{
public String address;
// 슈퍼 클래스의 생성자 호출 시 super()를 사용하여 명시적으로 호출
public Manager(String name, int age, String address) {
// 부모 생성자 호출하여 이름과 나이를 부모 생성자에게 전달
super(name,age);
// 멤버변수에 값을 할당
this.address = address;
}
public void managerInfo() {
System.out.printf("감독 : 이름 = %s, 나이 = %d세, 주소 = %s\n",name,age,address);
}
}
테스트 코드
public class SuperTest_02 {
public static void main(String[] args) {
// Employee 클래스로부터 e 객체 생성
Employee e = new Employee("손흥민",25);
e.employeeInfo();
Manager m = new Manager("슈틸리게",50,"서울");
m.managerInfo();
}
}
-> 하위 클래스 생성자에 super(name,age) 로 상위 클래스의 생성자를 호출하여 이름과 나이를 전해주었다.