상속, 부모클래스와 자식클래스
- 상속: 클래스의 멤버를 물려준다
- 부모 클래스: 물려주는 클래스
- 자식 클래스: 물려받는 클래스
public class Main { public static void main(String[] args) { Parent p = new Parent(); Child c = new Child(); p.print(); c.print(); } } // Parent 클래스 정의 class Parent { public int iInt; public void print() { System.out.println("Parent Class"); } } // Child 클래스 정의 class Child extends Parent{ } // > Parent Class // Parent Class
- 14~21번째 줄: Parent라는 클래스 정의. 클래스 멤버는 iInt라는 변수와 print라는 메소드로 구성
- 23~26번째 줄: Child라는 클래스 정의. extends 구문을 통해 상속을 나타냄
- 클래스를 정의할 때 클래스 이름 옆에 extends 구문을 붙여준 후 부모 클래스 이름을 적어주면 자식 클래스는 부모 클래스를 상속하게 됨
- 자식 클래스는 부모 클래스의 private 멤버를 제외한 나머지 멤버를 본인의 멤버처럼 사용 가능
- 위 예제에서 Child 클래스 내부에 아무것도 적지 않았지만 상속받았으므로 iInt변수와 print() 메소드를 Child 클래스의 멤버로 사용할 수 있음
- main함수를 보면, Child 클래스의 객체 c에서 print 메소드를 사용한걸 확인 할 수 있음 → Child 클래스에도 print 메소드가 정의되어 있으며 사용까지 가능하다
- 상속
- 자식 클래스는 부모 클래스로부터 물려받은 멤버 외에 다른 멤버를 추가로 가질 수 있음
- 자식 클래스에서 정의된 멤버는 부모클래스 객체에서는 사용할 수 없음
- 자식 클래스 객체가 생성될 때는 부모클래스의 생성자가 무조건 콜 됨 콜 순서는 부모클래스 생성자, 자식클래스 생성자 순
접근제한자: protected

- 부모 클래스에서 protected로 선언된 멤버는 자식 클래스에서 상속 받아 public처럼 사용할 수 있음.
- 단, 본인 클래스 혹은 자식 클래스 외의 장소에서 사용할 경우 해당 멤버는 private과 동일하게 동작함
- 부모 클래스에서 private로 선언된 멤버는 자식 클래스에서도 사용 불가능
오버라이딩(overriding)
- 부모 클래스의 멤버를 자식 클래스에서 재정의하여 사용하는 것
public class Main { public static void main(String[] args) { Parent p = new Parent(); Child c = new Child(); p.print(); c.print(); } } // 부모 클래스 정의 class Parent { public int iInt; public void print() { System.out.println("Parent Class"); } } // 자식 클래스 정의 class Child extends Parent{ public void print() { System.out.println("Child Class"); } }
- 앞서 다룬 예제에서는 Child 클래스에 어떤 내용도 존재하지 않았음. 위 코드에스는 print 메소드를 정의함
- 자식 클래스에서 부모 클래스에 정의된 메소드를 재정의함
- 부모 클래스의 멤버를 상속 받았지만, 자식 클래스에서 해당 멤버의 내용을 수정했으므로 자식 클래스 객체에서는 바뀐 내용이 적용됨
- 부모 클래스에는 영향x

추상화 & 추상클래스
- 추상화는 상속에서만 사용될 수 있는 개념
- 부모 클래스에서 추상적으로 메소드를 만들어 놓으면, 자식 클래스에서 해당 메소드를 구체화 함
public class Main { public static void main(String[] args) { //Animal animal = new Animal("동물"); 불가능합니다. Lion lion = new Lion("사자"); lion.Growl(); Cat cat = new Cat("고양이"); cat.Growl(); } } abstract class Animal { String Name; public Animal(String name) { Name = name; } abstract public void Growl(); } class Lion extends Animal { public Lion(String name) { super(name); } public void Growl() { System.out.println("어흥"); } } class Cat extends Animal { public Cat(String name) { super(name); } public void Growl() { System.out.println("야옹"); } }
- Animal 클래스는 생성자와 Growl 메소드를 가진 클래스인데, Growl 메소드에 abstract 라는 문구가 붙음
- abstract 가 명시된 메소드를 추상화 메소드라하며, 추상화 메소드는 내용을 정의하지 않음 → 껍데기만 존재하는 메소드, 상속된 후 자식 클래스에서 정의하여 사용 가능
- 추상화 메소드를 가진 클래스를 추상 클래스라 함. 추상 클래스에도 abstract 를 명시해야 함. 추상 클래스는 객체화 할 수 없음
- 부모 클래스에서 Growl 메소드를 정의하지 않았으므로, 자식클래스에서 오버라이딩해야함 → 오버라이딩 안하면 자식 클래스도 abstract 클래스가 됨
- 28번째 줄, 38번째 줄: super 는 부모 클래스를 지칭하는 문구. 위 예제에서는 super(name)이 Animai(name)과 동일
- 부모 클래스에서 추상화를 통해 클래스 구조의 뼈대만 구성해두고 자식 클래스에서 목적에 맞게 오버라이딩하여 사용 → 좀 더 구조화된 프로그램을 만들 수 있음
interface
- Java에서는 다른 프로그래밍 언어에서 사용할 수 있는 다중 상속 기능을 제한함 ⇒ extends 뒤에 작성할 수 있는 클래스는 단 하나
- 하지만 상황에 따라 다중 상속이 필요함 ⇒ interface 기능
- interface: 추상화 클래스보다 좀 더 추상화된 클래스
interface Example { public static final int iVariable; // int iVariable만 써도 동일함. abstract public void method(); // void method()만 써도 동일함. }
- class와 비슷한데 class 대신 interface라는 구문을 사용하며, 멤버 변수는 public static final 형태만 사용할 수 있고, 메소드도 abstract public 형태만 가능
- public static final과 abstract public은 interface 내에서 생략 가능
- 알맹이 하나 없이 뼈대만 세워진 클래스
public class Main { public static void main(String[] args) { MP3Player_Ver1 mp3_ver1 = new MP3Player_Ver1(); mp3_ver1.Play(); mp3_ver1.Stop(); //mp3_ver2.Next(); 불가능 합니다. //mp3_ver2.Prev(); 불가능 합니다. MP3Player_Ver2 mp3_ver2 = new MP3Player_Ver2(); mp3_ver2.Play(); mp3_ver2.Stop(); mp3_ver2.Next(); mp3_ver2.Prev(); } } class MP3Player_Ver1 implements PlayFunction, StopFunction { public void Play() { System.out.println("Play_Ver1!"); } public void Stop() { System.out.println("Stop_Ver1!"); } } class MP3Player_Ver2 implements PlayFunction, StopFunction, NextFunction, PrevFunction { public void Play() { System.out.println("Play_Ver2!"); } public void Stop() { System.out.println("Stop!_Ver2"); } public void Next() { System.out.println("Next!_Ver2"); } public void Prev() { System.out.println("Prev!_Ver2"); } } interface PlayFunction { abstract public void Play(); } interface StopFunction { abstract public void Stop(); } interface NextFunction { abstract public void Next(); } interface PrevFunction { abstract public void Prev(); }
- interface로부터 상속받을 시, extends를 사용하지 않고 implements를 사용함
- MP3Player_Ver1 클래스는 PlayFunction과 StopFunction, 총 두 개의 interface를 상속 받음. interface에 정의된 메소드는 모두 abstract형이므로, 17~25번째 줄에서 두 메소드를 모두 오버라이딩 함
- main 함수 내에서 MP3Player_Ver1 및 MP3Player_Ver2 사용 시, MP3Player_Ver1의 객체에서는 Next와 Prev 메소드는 정의되지 않으므로 사용 불가능
추상 클래스는 일부 멤버만 추상화할 수 있지만 1개의 클래스만 상속할 수 있고, interface는 모든 멤버 메소드가 추상 메소드여야 하지만 여러 개를 동시에 상속할 수 있음상속, 부모클래스와 자식클래스
바로 실행해보면서 배우는 java'를 학습하며 정리한 문서
'Java' 카테고리의 다른 글
Java 문법(11)끝 - 예외처리 (try-catch, Exception) (0) | 2022.02.08 |
---|---|
Java 문법(10) - 다형성 (0) | 2022.02.08 |
Java 문법(8) - 이차원배열, 클래스배열 (0) | 2022.02.08 |
Java 문법(7) - 데이터 입출력 (0) | 2022.02.07 |
Java 문법(6) - 클래스와 객체, 접근제한자 (0) | 2022.02.07 |