상속
상속이란!!!
기본의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.
장점
- 적은 양의 코드로 새로운 클래스 작성이 가능하다.
- 코드를 공통적으로 관리해서 코드의 추가 및 변경이 매우 용이하다.
사용 방법
class [클래스 이름] extends [상속받고자 하는 클래스의 이름]{
...
}
조상 클래스 : 부모 클래스, 상위 클래스, 기반 클래스
자손 클래스 : 자식 클래스, 하위 클래스, 파생된 클래스
조상 클래스의 변화 -> 자손 클래스에게 영향을 준다.
자손 클래스의 변화 -> 조상 클래스에게 영향을 안준다.
특징
- 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
- private 또는 default인 멤버는 상속은 받지만 자손으로부터 접근이 제한된다.
class Phone{
boolean power;
Phone(){
System.out.println("Phone생성자 실행");
power = false;
}
void power(){
power = !power;
System.out.println(power ? "전원이 켜집니다." : "전원이 꺼집니다.");
}
}
class MyPhone extends Phone{
String userName;
MyPhone(String userName){
System.out.println("MyPhone생성자 실행");
this.userName = userName;
}
void printUserName(){System.out.println(userName);}
}
public class Main {
public static void main(String[] args) {
MyPhone myPhone = new MyPhone("김씨");
myPhone.power();
myPhone.printUserName();
myPhone.power();
}
}
이렇게 만든다면 다음과 같은 상속 계층도를 가질 수 있다.
그리고 MyPhone은 pringUserName(), power() 메서드가 사용이 가능하고 Phone는 power()메서드만 사용이 가능하다.
그리고 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.
그러면 우리는 생성자는 상속이 안된다고 했었고 자손은 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다. 그럼 위에서 Phone의 생성자는 실행이 될까?? main문을 실행했을 때 출력값을 한번 생각해보면 좋을 거 같다!!
출력
Phone생성자 실행
MyPhone생성자 실행
전원이 켜집니다.
김씨
전원이 꺼집니다.
두개의 클래스 다 생성자가 실행된다!! 그럼 인스턴스가 두개 만들어지는걸까??
인스턴스가 두개 생성되는게 아니라 자식 클래스가 상속을 받기 위해서 부모클래스의 기본 상태를 알기 위해 부모클래스의 생성자를 실행하는 것이다. 인스턴스를 두개 만드는거는 아니다!!
class MyPhone extends Phone{
String userName;
MyPhone(String userName){
super();
System.out.println("MyPhone생성자 실행");
this.userName = userName;
}
void printUserName(){System.out.println(userName);}
}
따로 추가하지 않는다면 super()라는 키워드를 자동으로 추가해서 생성자를 실행하면서 Phone의 생성자가 실행되는것이다. 물론 부모클래스에서 다른 매개변수를 받은 생성자가 있고, 자식 클래스에서 super(매개변수) 이런 형식으로 실행해도 된다!!
class MyPhone extends Phone{
String userName;
MyPhone(String userName){
Phone();//에러 뜬다!
System.out.println("MyPhone생성자 실행");
this.userName = userName;
}
void printUserName(){System.out.println(userName);}
}
이렇게는 안된다!!
이외에도 포함 관계로 표현도 가능하다.
class Phone{
boolean power;
Phone(){
System.out.println("Phone생성자 실행");
power = false;
}
void power(){
power = !power;
System.out.println(power ? "전원이 켜집니다." : "전원이 꺼집니다.");
}
}
class MyPhone{
String userName;
Phone phone;
MyPhone(String userName){
System.out.println("MyPhone생성자 실행");
this.userName = userName;
this.phone = new Phone();
}
void printUserName(){System.out.println(userName);}
}
이렇게 하면 포함관계로도 생성이 가능한데.
상속과 포함 뭔가 다른데 구분하기 힘들다면??
- 상속관계 : ~은 ~이다.(is-a)
- 포함관계 : ~은 ~을 가지고 있다.(has-a)
이렇게 생각하면 좋을 거 같다!!
위 예제에서
- 상속관계 : 내폰은 폰이다. -> 자연스러운 문장
- 포함관계 : 내폰은 폰을 가지고 있다 -> 뭔가 이상해...
- 포함관계말고 상속관계로 표현하자!
단일 상속(Single inheritance)
자바에서는 단일 상속만 허용한다 다중 상속은 허용하지 않는다.
장점 | 단점 | |
다중상속 | 복합적인 기능을 가진 클래스 쉽게 작성 가능. | 관계가 복잡해짐. |
단일 상속 | 한개씩만 상속이 가능해서 계속 extends로 하나씩 상속을 진행해야함. | 관계가 복잡하지 않다. |
Object클래스
Object클래스는 모든 클래스 상속계층도의 최상위에 있는 조상클래스다.
public static void main(String[] args) {
MyPhone myPhone = new MyPhone("김씨");
myPhone.phone.power();
myPhone.printUserName();
myPhone.phone.power();
System.out.println(myPhone);
}
우리는 다음과 같이 myPhone객체를 println구문에 넣고 실행하면 출력이 가능한데 이거는 왜 이런걸까?? 객체를 출력한다??
바로 Object 덕분이다.
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Object클래스에는 toString이 정의되어 있는데 이게 실행되는 것이다. 근데 우리는 상속도 한적이 없는데 왜 실행되는 걸까??
바로 Phone에 상속되어 있기 때문이다.
class Phone {
...
}
class Phone extends Object{
...
}
컴파일러는 컴파일을 할 때 아무것도 상속되지 않은 클래스에 extends Objects를 추가해서 자동으로 상속해주기 때문에 가능한것이다!!
그래서 Object클래스에 있는 toString()이 자동으로 실행되는 것이다.
'자바(Java)' 카테고리의 다른 글
선택 안됨 [자바][Java Programming Language]객체지향 프로그래밍 -package와 import (0) | 2025.02.08 |
---|---|
[자바][Java Programming Language]객체지향 프로그래밍 - 오버라이딩 (0) | 2025.01.24 |
[자바][Java Programming Language] 객체지향프로그래밍(클래스, 생성자, 매개변수, 메서드) (1) | 2025.01.22 |
[자바][Java Programming Language] 배열(Array) (0) | 2024.12.31 |