[JAVA] 상속

XXXX·2024년 1월 9일
0
post-thumbnail

상속 (Inheritance)

  • 기존 클래스에 기능 추가 및 재정의하여 새로운 클래스를 정의

    부모 클래스: 상속 대상이 되는 기존 클래스 = 상위 클래스, 기초 클래스
    자식 클래스 : 기존 클래스를 상속하는 클래스 = 하위 클래스, 파생 클래스

  • 부모 클래스의 필드와 메소드가 상속됨 (생성자, 초기화 블록은 상속되지 않음)

  • 다중 상속은 불가능
  • private, default 멤버는 자식 클래스에서 접근 불가
    (private 경우, 어디서나 접근이 불가능하므로 자식 클래스에서도 접근 불가하다. default의 경우, 같은 패키지의 자식 클래스는 접근 가능)


super, super()

  • super : 부모 클래스와 자식 클래스의 멤버 이름이 같을 때 구분하는 키워드
  • super() : 부모 클래스의 생성자 호출

오버라이딩 (Overriding)

  • 오버로딩과 다른 개념!
  • 부모 클래스의 메소드를 자식 클래스에서 재정의
  • 오버라이딩 조건
  1. 메소드의 선언부는 부모 클래스의 메소드와 동일해야 함

  2. 반환 타입에 한해, 부모 클래스의 반환 타입으로 형 변환할 수 있는 타입으로 변경 가능

  3. 부모 클래스의 메소드보다 접근제어자를 더 좁은 범위로 변경 불가

  4. 부모 클래스의 메소드보다 더 큰 범위의 예외 선언 불가



// Java 프로그래밍 - 상속

class Person {
    String name;
    int age;
    public int a1;
    private int a2;

    Person() {} // 기본 생성자
    Person(String name, int age) { // 초기화를 위해 만들어 준 오버라이딩 생성자
        this.name = name;
        this.age = age;
    }

    public void printInfo() {
        System.out.println("Person.printInfo");
        System.out.println("name: " + name);
        System.out.println("age: " + age);
    }
}

// Student 클래스 - Person 상속, 접근제어자 확인
class Student extends Person {
    Student() {
        a1 = 1;
//        a2 = 1; -> private 이므로 상속을 받았지만, 다른 클래스라 적용이 안된다.
    }

}

// Student 클래스 - Person 상속, super 사용, 오버라이딩
class Student2 extends Person {
    String name;
    int stdId;

    Student2(String name, int age, int stdId) { // 생성자
//        this.name = name; // 자기 객체의 name
//        super.name = name; // 부모 객체 쪽의 변수 name
        super(name, age); // 두 데이터를 부모 클래스 쪽으로 넘겨서 부모 클래스에서 초기화가 될 수 있도록 함
        this.age = age; // 상속 받은 age (부모 클래스에만 존재하므로)
        this.stdId = stdId; // 자기 객체의 stdId (부모 클래스에 없다.)
    }

    public void printInfo() {
        System.out.println("Student2.printInfo");
        System.out.println("name: " + name); // 기본적으로 자기 객체의 name을 받아서 쓴다. (but 자기 객체의 name에는 아무 값도 할당 되어있지 않다. 왜냐하면 super()을 통해 부모 클래스 쪽으로 name을 넘겼기 때문)
        System.out.println("age: " + age);
        System.out.println("stdId: " + stdId);
    }
}



public class Main {

    public static void main(String[] args) {

//      Test code
//      1. 상속
        System.out.println("=============");
        Student s1 = new Student();
        s1.name = "a";
        s1.age = 25;
        s1.printInfo();


//      2. super, super(), 오버라이딩
        System.out.println("=============");
        Student2 s2 = new Student2("b",32, 1);
        s2.printInfo();

    }
}

// Practice1
// 아래의 클래스 및 상속 관계에서 Test code를 수정하지 않고
// Cat 클래스 내에서 super 또는 super()를 이용하여
// "고양이 입니다." 가 출력될 수 있도록 변경해보세요.

class Animal {
    String desc;
    Animal() {
        this.desc = "동물 클래스 입니다.";
    }

    Animal(String desc) {
        this.desc = desc;
    }

    public void printInfo() {
        System.out.println(this.desc);
    }
}

class Cat extends Animal { // Animal 상속
    String desc;
    Cat() {
		super.desc = "고양이 입니다."; // super 이용    
        super("고양이 입니다."); // super() 이용
    }
}

public class Practice1 {
    public static void main(String[] args) {
        // Test code
        Cat cat = new Cat();
        cat.printInfo();

    }
}

// Practice2
// 아래 클래스와 상속 관계에서
// Test code를 수정하지 않고, 아래와 같이 출력될 수 있도록 오버라이딩 해보세요.
// 빵빵!
// 위이잉!
// 빵빵!
// 삐뽀삐보!

class Car {
    Car(){}
    public void horn() {
        System.out.println("빵빵!");
    }
}

class FireTruck extends Car {
    public void horn() {
        super.horn(); // "빵빵!" 출력 (부모클래스 출력)
        System.out.println("위이잉!");

    }
}

class Ambulance extends Car {
    public void horn() {
        super.horn(); // "빵빵!" 출력 (부모클래스 출력)
        System.out.println("삐뽀삐보!");
    }
}

public class Practice2 {
    public static void main(String[] args) {
        // Test code
        FireTruck truck = new FireTruck();
        truck.horn();

        Ambulance amb = new Ambulance();
        amb.horn();
    }
}

0개의 댓글