Skip to the content.

목표:자바의 상속에 대해 학습하세요.

자바 상속의 특징(출처)

public class Parent {
    //부모클래스
}

class Son extends Parent {
    //부모클래스한테 상속받은 아들클래스
}

자바에서 상속이란 부모 클래스에서 정의된 필드와 메소드를 자식 클래스가 물려받은것이다

여기서 객체지향에서 상속이 필요한 이유는

1.공통된 특징을 가지는 클래스 사이의 멤버(필드,메소드) 선언이 불필요하다

2.부모 클래스의 멤버(필드,메소드)를 재사용함으로써 자식 클래스는 코드에대해 간결해진다

3.클래스간 계층적 분류 및 관리가 쉬워진다

상속의 특징

1.자바에서는 다중상속을 지원하지 않는다 따라서 extends 뒤에는 단 하나의 부모 클래스만 올수 있다

2.자바에서는 상속의 횟수에는 제한을 두지 않는다

3.자바의 최상위 클래스는 Object클래스이다 그뜻은 자바의 모든 클래스들은 Object 클래스의 자손이라도 보면 된다

상속의 종류

super 키워드(출처)

super

super키워드는 부모 클래스로 부터 상속받은 필드나 메소드를 자식 클래스에서 참조하는데 사용하는 참조 변수이다

예를 들어 인스턴스 변수의 이름과 지역변수의 이름이 같을 경우 인스턴스 변수 앞에 this 키워드를 사용하여 구분할수 있었다

마찬가지로 부모 클래스의 멤버와 자식 클래스의 멤버 이름이 같을 경우 super키워드를 사용하여 구별한다

class Parent {
    int a = 10;
}

class Child extends Parent {
    int a = 20;

    void display() {
        System.out.println(a);
        System.out.println(this.a);
        System.out.println(super.a);
    }
}
public class _Super {
    public static void main(String[] args) {
        Child c = new Child();
        c.display();
    }
}

결과
20
20
10

위의 코드는 지역변수와 this 참조 변수는 자식 클래스에서 대입된 값을 출력하며

super 참조 변수만이 부모 클래스에서 대입된 값을 출력한다

super() 메소드

예를 들어 this()메소드가 같은 클래스의 다른 생성자를 호출할 때 사용된다면 super()메소드는 부모 클래스의 생성자를 호출 할 때 사용한다

자식 클래스의 인스턴스를 생성하면 해당 인스턴스에는 자식 클래스의 고유멤버뿐만 아니라 부모클래스의 모든 멤버까지도 포함되어 있다

따라서 부모 클래스의 멤버를 초기화 하기 위해서는 자식 클래스의 생성자에서 부모 클래스의 생성자까지 호출해야만 한다

이렇게 하다보면 Object 클래스까지 계속 거슬러 올라가며 수행한다

결국 super()메소드로 부모 클래스의 멤버를 초기화할 수 있게 해준다

class Parent1 {
    int a;//파라메터

    Parent1() {//생성자
        a = 10;
    }

    Parent1(int n) {//메서드
        a = n;
    }
}

class Child1 extends Parent1 {
    int b;

    Child1() {
        super(40);//이부분을 주석처리하면 이전에 부모클래스에 있는 생성자에 있던 값이 출력된다
        b = 20;
    }

    void display() {
        System.out.println(a);
        System.out.println(b);
    }
}
public class __super {
    public static void main(String[] args) {
        Child1 c = new Child1();
        c.display();
    }
}

출력
40--->super()부분을 주석처리하면 10
20

메소드 오버라이딩(출처)

@Override

먼저 필자는 메소드 오버라이딩과 오버로딩이 헷갈려서 찾아봤다

먼저 오버로딩은 4주차에서 설명했듯이 같은 이름의 메서드 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 하는 방법이다

오버라이딩은 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 방법이다

쉽게말해 메서드의 이름이 서로 같고 매개변수가 같고 반환형이 같을 경우에 상속 받은 메서드를 덮어쓴다고 생각하면 된다

부모 클래스의 메서드는 무시하고 자식 클래스의 메서드 기능을 사용하겠다 이말이다

다이나믹 메소드 디스패치 (Dynamic Method Dispatch)

//보수중

추상 클래스(참조)

추상 클래스(abstract class)란 하나 이상의 추상 메소드를 포함하는 클래스이다

단도직입적으로 말하자면 속빈 강정인 셈이다

메소드가 추상인 상태라면 그 해당 클래스에도 abstract 키워드를 삽입해야 한다

abstract class Tool {
    public String tName;//일반 멤버 상수

    public void use() {//일반 메소드
        System.out.println("손에 들고");
    }

    abstract void structure();//추상 메소드
}

class Hammer extends Tool {
    public void use() {
        System.out.println("망치는 내리친다");
    }

    @Override//즉 비유적으로 표현하면 아버지의 물건을 그대로 쓰지 않고 자기입맛에 맞게 고치기위해서 먼저 나이거 고칠게
//    라고 Java에게 가르쳐주는 것이다.
    void structure() {
        System.out.println("망치는 뚝딱뚝딱");
    }
}

class Driver extends Tool {
    public void use() {
        System.out.println("드라이버는 돌린다");
    }

    @Override
    void structure() {
        System.out.println("드라이버는 끼익끼익");
    }
}

public class 추상클래스 {
    public static void main(String[] args) {

        Hammer h = new Hammer();
        Driver d = new Driver();

        h.use();
        h.structure();

        d.use();
        d.structure();

    }
}

결과

망치는 내리친다
망치는 뚝딱뚝딱
드라이버는 돌린다
드라이버는 끼익끼익

추상 클래스 자체로는 클래스로의 역할을 하지 못하며 객체를 생성할 수 없지만 새로운 클래스를 작성하는데 있어서 부모 클래스로서 중요한 역할을 갖는다

Tool클래스는 직접 객체를 생성하지 못하고 이를 상속받는 자식 클래스에서는 추상 메소드의 구체적인 본체를 가질수 있다

그리고 추상 메소드는 접근 제한자로 private는 사용할수 없는데 이는 자식클래스가 상속을 받지 못하기 때문이다

또한 어떤 추상클래스를 상속 받은 자식 클래스에서 추상 메소드를 구현하지 않았다면 자식 클래스도 추상 클래스가 되어야 한다

final 키워드(참조)

final은 말 그대로 변경할수 없는 마지막을 뜻한다.

즉 변수나 메서드나 클래스 앞에 붙으면 해당 개체들은 수정이 불가능하다는 것이다.

그리고 변수명을 지을때는 모두 대문자를 표기하되,두 단어로 이루어진 이름이라면 중간에 _언더바를 포함하여 이름을 지어준다

상수 final

public class _Final01 {
    public static void main(String[] args) {
        final String MESSAGE = "JAVA";
        MESSAGE = "C++";

        System.out.println(MESSAGE);

    }
}

결과
java: cannot assign a value to final variable MESSAGE//에러가 뜬다

클래스 final(출처)

public final class Parents{//final 클래스 선언
}
public class Child extends Parents{//상속 불가!
}

메서드 final

class Parents {
    public void m() {

    }

    public final void f() {

    }
}

public class _Final02 extends Parent {
    public void m() {//Parents 클래스의 m을 상속

    }

    public void f() {//오버라이딩, 즉 상속받은 메서드를 수정할 수 없다
        
    }
}

번외로 final 변수의 짝꿍인 static을 배워보겠다

먼저 static는 변수나 함수에 붙는 키워드인데 어디서 선언하는지에 따라 조금씩 다른 의미를 가진다

일반적인 의미로는

static을 붙이면 메모리에 딱 한번만 할당되어 메모리를 효율적으로 사용할 수 있다

메모리에 딱 한번만 할당한다는건 곧 같은 주소값을 공유한다는 것이다

그러므로 여기저기에 변수 하나로 공유할 수 있다는 장점이 있다

지금까지 정리하자면

static ≒ final

이것으로 둘의 궁합을보면

어짜피 같은 값을 쓸거 계속 메모리 낭비할 거 없이 하나로 쭉 써도 되는점에서

둘이 같이 쓰면 효율성이 높아 자주 쓰인다고 한다

Object 클래스(출처)

자바 API의 모든 클래스와 사용자와 정의한 모든 클래스의 최상위 클래스이다

즉 모든 자바 클래스들은 Object 클래스를 상속받는다

   
메소드 용도
boolean equals(object obj) 두 개의 객체가 같은지 비교한다.반환형은 boolean(true/false)
String toString() 현재 객체의 문자열을 반환한다 (오버라이딩을 사용하려 현재 객체의 초기화된 멤버변수를 알수 있다)
Object clone() 객체를 복사한다
Class getClass() 객체의 클래스형을 반환한다
void finalize() GC 직전에 객체의 리소스를 정리할 때 호출
int hashCode() 객체의 해쉬코드값을 반환한다

추가적인 API는 링크

(tmi지만 new연산자로 만든 String객체와 “ “로 만든 문자열의 비교글이 있다.)