본문 바로가기
Framwork/Java기초

Chapter 8. 상속

by 김엉배 2023. 8. 6.
728x90
반응형

   목차

1. 상속 기본 개념
2. super 키워드
3. 메소드 오버라이딩(overriding)
4. final 키워드
5. 단일 상속과 다중 상속(multiple inheritance)
6. 다형성(polymorphism) 

 

1.  상속 기본 개념


- 이름 그대로 클래스를 상속받아 새로운 클래스를 만드는 것.

  • ex) 부모: Person  자식: Student
// 부모 클래스
class Person {
  private String name; // 이름
  private String phone; // 전화번호

  Person() {}
  Person(String name, String phone) {
    this.name = name;
    this.phone = phone;
  }

  void printPerson() {
    System.out.println(name + "'s phone number is " + phone);
  }
}

// 부모로 부터 상속 받은 자식 클래스
class Student extends Person { // 클래스 Student는 클래스 Person을 상속받음.
  private int score;
  Student() {}
  Student(String name, String phone, int score) {
    super(name, phone); // super는 부모 생성자를 호출하는 키워드
    this.score = score;
  }
  void printStudent() {
    printPerson(); // 부모 클래스의 printPerson() 메소드를 사용할 수 있다.
    System.out.println("scoe: " + score);
  }
}

public class Code128 {
  public static void main(String[] args)
  {
    Student s = new Student("Alice", "010-111-1111", 90);
    s.printStudent();
  }
}

- 하나의 클래스가 부모 클래스를 갖게 되면 부모 클래스의 멤버들은 모두 자기 것처럼 사용할 수 있다.
   printStudent() 메소드에서 부모의 printPerson()을 사용하고 있다.

 

 

2.  super 키워드


- 객체를 생성하면 우선 부모 생성자 호출 후, 자식 생성자를 호출한다. 적절한 부모 생성자가 제공되어야 에러가 발생하지 않는다.

  • ex) 부모 자식에 모두 디폴트 생성자 있는 경우, 없는 경우 비교
class Parent {
  Parent() {
    System.out.println("parent constructor is called");
  }
  void printParent() {
    System.out.println("I am parent");
  }
}

class Child extends Parent {
  Child() {
    System.out.println("child constructor is called");
  }
  void printChild() {
    System.out.println("I am child");
  }
}

public class code130 {
  public static void main(String[] args) {
    Child c = new Child(); // 부모 생성자 호출 후에 자신의 생성자 호출
    c.printParent();
    c.printChild();
  }
}

class Parent { // 생성자가 하나도 없기 때문에 디폴트 생성자가 제공
  void printParent() {
    System.out.println("I am parent");
  }
}

class Child extends Parent {
  Child() {
    System.out.println("child constructor is called");
  }
  void printChild() {
    System.out.println("I am child");
  }
}

public class code131 {
  public static void main(String[] args) {
    Child c = new Child(); // 여기서 부모 생성자 호출 후에 자식의 생성자 호출
    c.printParent();
    c.printChild();
  }
}

class Parent {
  void printParent() {
    System.out.println("I am parent");
  }
}

class Child extends Parent {
  private int data;

  Child(int data) {
    this.data = data;
  }
  void printChild() {
    System.out.println("data : " +data);
  }
}

public class code132 {
  public static void main(String[] args) {
    Child c = new Child(10);
    c.printParent();
    c.printChild();
  }
}

class Parent {
  private int dataA; // 디폴트 생성자 제공x
  Parent(int dataA) {
    this.dataA = dataA;
  }
}

class Child extends Parent {
  Child() { // 여기서 에러 발생
    System.out.println("child constructor is called");
  }
  
  void printChild() {
    System.out.println("I am child");
  }
}

public class code133 {
  public static void main(String[] args) {
    Child c = new Child();
    c.printChild();
  }
}

 

  • super 키워드를 이용해 부모 생성자 호출
class Parent {
  private int dataA;

  Parent() {}
  Parent(int dataA) {
    this.dataA = dataA;
  }
  void printA() {
    System.out.println("dataA: " + dataA);
  }
}

class Child extends Parent {
  private int dataB;

  Child() {}
  Child(int dataA, int dataB) {
    super(dataA); // super 키워드를 이용해 부모 생성자를 호출
    this.dataB = dataB;
  }
  void printB() {
    System.out.println("dataB: " + dataB);
  }
}

public class code134 {
  public static void main(String[] args) {
    Child c = new Child(10, 20);
    c.printA();
    c.printB();
  }
}
  • super 키워드를 이용하여 부모 멤버에 접근
    - 부모 클래스의 인스턴스 변수에 접근: 부모 클래스에 있는 인스턴스 변수와 같은 이름으로 인스턴스 변수를 갖는 경우 super 키워드 
    - 부모 클래스의 메소드 접근: 자식 클래스에서 얼마든 사용할 수 있으나, 같은 이름 메소드가 양쪽 다 있으면 super키워드로 부모 클래스 명시해야 한다.

 

 

3.  메소드 오버라이딩(overriding)


- 상속 관계에서 부모 클래스가 갖고 있는 메소드와 똑같은 형태의 메소드를 갖는 것

  • 오버로딩: 한 클래스 내에서 메소드명은 같고 매개변수가 다른 것을 말함.
  • 오버라이딩: 자식 클래스에서 부모 클래스에 있는 메소드와 같은 형태를 갖는 것을 말함.

ex) 오버라이딩

class Parent {
  void print() {
    System.out.println("I am parent print");
  }
  void test(int x) {
    System.out.println("Parent - test method");
  }
}

class Child extends Parent {
  void print() {
    super.print();
  }
  void test(int x) {
    super.test(x);
  }
}

public class code142 {
  public static void main(String[] args) {
    Parent p = new Parent();
    p.print(); // Parent클래스의 print() 메소드 호출
    p.test(10); // Parent 클래스의 test() 메소드 호출
    Child c = new Child();
    c.print(); // Child 클래스의 print()메소드 호출
    c.test(20); // Child 클래스의 test() 메소드 호춯
  }
  
}

 

 

4.  final 키워드


- 클래스, 인스턴스 변수, 메소드, 메소드 내의 지역 변수 앞에 사용 가능

final class Data { // final 클래스
	final private int x; // final 인스턴스 변수x
    final void print() { // final 메소드
    		....
    }
    
    void test() {
    	final int data; // final 지역 변수 data
        ....
    }
}

 

  • final 클래스
    - final 클래스는 자식 클래스를 가질 수 없는 class이다. 즉 자신이 마지막 클래스이다.
final class Data {
	pirvate int x;
    Data() {}
    Data(int x) {
    	this.x = x;
    }
}

class ChildData extends Data { // 에러 발생

}

 

  • final 인스턴스 변수
    - 인스턴스 변수 앞에 final 키워드가 붙으면 상수라는 뜻. 즉, 한 번 저장된 값은 바꿀 수 없다는 의미.
class Data {
	final private int x = 100; // final 인스턴스 변수를 초기화
    Data() {}
    Data(int x) {
    	this.x = x; // 에러. 초기화된 final 인스턴스 변수는 생성자를 통해 변경시킬 수 없다.
    }
}

 

  • final 메소드
    - final 메소드는 오버라이딩 x , 자식 클래스에서 오버라이딩 메소드를 가질 수 없다.

  • final 지역 변수
    - 메소드 내의 지역 변수 앞에도 붙을 수 있다. 이 경우에도 한 번 값이 저장되면 변경할 수 없는 상수가 된다.
public class FinalTest {
	public static void main(String[] args) {
    	final int data = 100; // data 지역 변수가 100으로 초기화 되어있다.
        System.out.println("data: " + data);
        data = 200 // 에러. data 변수는 final 변수라서 변경할 수 없다.
    }
}

 

 

5.  단일 상속과 다중 상속(multiple inheritance)


- 단일 상속은 하나의 부모를 갖는 것을 말하고, 다중 상속은 부모가 여럿인 것을 말한다.

  • ex) 
class Parent {
  int a = 10;
  void show() {
    System.out.println("I am parent show");
  }
}

class Child1 extends Parent {
  int b = 20;
  void show1() {
    System.out.println("I am child1 show");
  }
}

class Child2 extends Parent {
  int c = 30;
  void show2() {
    System.out.println("I am child2 show");
  }
}

public class code147 {
  public static void main(String[] args) {
    Child1 c1 = new Child1();
    Child2 c2 = new Child2();
    System.out.println("c1.a: " + c1.a);
    System.out.println("c1.b: " + c1.b);
    System.out.println("c2.a: " + c2.a);
    System.out.println("c2.b: " + c2.c);
    c1.show();
    c1.show1();
    c2.show();
    c2.show2();
  }
}

 

6.  다형성(polymorphism)


- 이름대로 여러 가지 형태를 가질 수 있는 성질, 코드로는 부모 참조 변수에 자식 객체를 생성하는 것

  • ex) 
class Parent {
  void print() {
    System.out.println("parent - print method");
  }
  void test() {
    System.out.println("Parent - test method");
  }
}

class Child extends Parent {
  void print() {
    System.out.println("child - print method");
  }
  void check() {
    System.out.println("child - check method");
  }
}

public class code149 {
  public static void main(String[] args) {
    Parent p = new Parent();
    p.print();
    p.test();
    p.check(); // 에러. Parent 클래스에 check() 메소드 없음

    Child c = new Child();
    c.print();
    c.print();
    c.test();

    Parent x = new Child(); // 다형성 (부모 변수에 자식 객체를 생성함)
    x.print();
    x.test();
    x.check(); // 에러. Parent 클래스에 check()는 없는 메소드임
  }
}

 

728x90
반응형

'Framwork > Java기초' 카테고리의 다른 글

Chapter 10. 추상 클래스와 인터페이스  (16) 2023.08.12
Chapter 9. 패키지와 접근 제어  (7) 2023.08.06
Chapter 7. 클래스와 객체(2)  (0) 2022.11.04
Chapter 7. 클래스와 객체(1)  (0) 2022.10.30
Chapter 6. 메소드  (0) 2022.10.26