럿고의 개발 노트
[프로그래머스] 자바 입문 > Part7. 상속 본문
[프로그래머스] 자바 입문
Part7. 상속
1. 상속
상속
부모가 가진 것을 자식에게 물려주는 것
is a 관계나 kind of 관계를 생각하면 됨
클래스 이름 뒤애ㅔ extends 키워드를 적고 부모클래스 이름을 적으면 부모 클래스가 가지고 있는 것을 상속 받을 수 있음
부모가 가지고 있는 메소드외에 추기로 메소드를 선언하는 것을 확장하였다고 표현
public class Car {
public void run() {
System.out.println("run");
}
}
public class Bus extends Car { // Car Class를 상속받은 Bus Class
// public class 클래스명 extends 부모클래스명
// 상속이란, 부모가 가지고 있는걸 자식이 물려 받는것
// 즉, 부모가 가지고 있는 것을 자식이 사용할수 있는 것
public void ppangppang() { // 메소드 생성
System.out.println("빵빵");
}
}
public class BusExam {
public static void main(String[] args) {
Bus bus = new Bus();
bus.run(); // Bus Class에서는 run 메소드가 없었지만, Car Class에 있던 메소드를 상속 받았기 때문에 사용 가능
bus.ppangppang(); // Bus Class에서 정의한 메소드
Car car = new Car();
car.run(); // Car Class가 가지고 있는 메소드
//car.ppangppang();, 부모클래스는 자식클래스가 가지고 있는 것은 사용 못함!
}
}
2. 접근제한자
접근제한자
클래스 내에서 멤버의 접근을 제한하는 역할
접근제한자의 종류
- public : 어떤 클래스든 접근
- protected : 자기 자신, 같은 패키지, 다른 패키지는 상속받은 자식 클래스에서 접근 가능
- private : 자기 자신만 접근 가능
- default : 접근제한자를 적지 않은 것으로 자기 자신과 같은 패키지에서만 접근 가능
public class AccessObj {
// 클래스 = 필드 + 메소드
// 그러나 클래스가 아무거나 가지고 있으면 안됨, 예를 들면 수학과 관련된 Class면 수학과 관련된 것을 가지고 있어야 함
// 이런 정의를 캡슐화라고 함. 즉, 관련된 내용을 모아서 가지고 있는 것
// 필드와 메소드 중에 외부에 노출하지 않고 감추고 싶은 것이 있을 것
// 그걸 가능하게 하는 것이 접근제한자. 즉, 클래스 내에서 멤버의 접근을 제한하는 역할을 하는 것
/* 접근제한자 종류
* public : 누구나 사용 가능 / 가장 넓은 의미
* protected : 같은 패키지인 경우 접근 허용, 다른 패키지라도 상속받은 경우 접근 허용
* private : 자기 자신만 접근 가능
* default : 아무것도 쓰지 않은 경우, 자기 자신과 같은 패키지 내에서만 접근 허용
*/
public int p = 3;
protected int p2 = 4;
private int p3 = 5;
int p4 = 2; // default
}
public class AccessObjExam {
public static void main(String[] args) {
AccessObj obj = new AccessObj();
System.out.println(obj.p); // public
System.out.println(obj.p2); // protected
// System.out.println(obj.p3); // private / 사용 불가
System.out.println(obj.p4); // default
}
}
public class AccessObjExam extends AccessObj { // 상속
public static void main(String[] args) {
AccessObjExam obj = new AccessObjExam();
System.out.println(obj.p); // public
System.out.println(obj.p2); // protected (자식 클래스가 사용 가능)
// System.out.println(obj.p3); // private 사용 불가
// System.out.println(obj.p4); // default 사용 불가(같은 패키지에 없어서 사용 불가)
}
}
3. 추상클래스
추상클래스
구체적이지 않은 클래스로 예를 들어 독수리, 타조는 구체적인 새를 지칭하는데 포유류 같은 것은 구체적이지 않음.
위와 같은 예제를 구현한 클래스를 추상 클래스라고 함.ㅣ
추상 클래스 정의하기
- 추상 클래스는 클래스 앞에 abstract 키워드를 이용해서 정의
- 추상 클래스는 미완성의 추상 메소드를 포함할 수 있음
- 추상 메소드란, 내용이 없는(구현되지 않은) 메소드
- 추상 메소드는 리턴 타입 앞에 abstract라는 키워드를 붙임
- 추상 클래스는 인스턴스를 생성할 수 없음
추상 클래스를 상속받는 클래스 생성하기
- 추상 클래스를 상속받은 클래스는 추상 클래스가 가지고 있는 추상 메소드를 반드시 구현해야 함
- 추상 클래스를 상속받고, 추상 클래스가 갖고 있는 추상 메소드를 구현하지 않으면 해당 클래스도 추상 클래스가 됨
public abstract class Bird {
// 추상클래스 : 구체적이지 않은 클래스
public abstract void sing(); // 추상메소드
// 하나라도 추상메소드가 있다면, class도 추상클래스가 되어여 함
// 추상클래스 내부에는 일반 메소드가 구현 가능
public void fly() {
System.out.println("날다");
}
}
public class Duck extends Bird {
@Override
public void sing() { // 추상메소드였기때문에, 상속받을때 메소드를 정의해줘어 함.
System.out.println("꽥꽥!");
}
}
public class DuckExam {
public static void main(String[] args) {
Duck duck = new Duck();
duck.sing();
duck.fly();
// Bird bird = new Bird(); 추상클래스를 생성할수는 없음
// 즉, 객체로 생성이 되지 않음
}
}
4. super와 부모생성자
super와 부모 생성자
class가 인스턴스화 될 때 생성자가 실행되면서 객체의 초기화를 한다. 그때 자신의 생성자만 실행되는 것이 아니라 부모 생성자부터 실행 됨
생성자는 객체를 초기화 하는 역할을 하는데, 생성자가 호출될 때 자동으로 부모의 생성자가 호출되면서 부모 객체를 초기화 함
자신을 가리키는 키워드가 this라면, 부모를 가리키는 키워드는 super
super()는 부모의 생성자라는 의미
부모의 생성자를 임의로 호출하지 않으면, 부모 class의 기본 생성자가 자동으로 호출
클래스는 기본 생성자가 없는 경우도 존재하는데, 이런 문제를 해결하기 위해 자식 클래스의 생성자에서 직접 부모 생성자를 호출해줘야 함.
super키워드는 자식에서 부모의 메소드나 필드를 사용할 때도 사용
public class Car1 {
public Car1(String name) { // 기본생성자
System.out.println("Car1의 name 생성자 입니다.");
}
}
public class Truck extends Car1 {
public Truck() { // 기본생성자
// super키워드 : 부모 개체를 나타내는 키워드
// super(); // 부모의 기본생성자를 실행해달라고 하는건데, 부모가 있다면 자동으로 생성
// super 키워드가 필요한 경우, 부모의 생성자가 기본생성자가 아닐때, 부모 생성자를 직접 호출해줘야 함
super("소방차"); // 부모의 생성자가 기본생성자가 아닌 경우 부모 생성자를 수동으로 정의해야함
System.out.println("Truck의 기본생성자 입니다.");
}
}
public class TruckExam {
public static void main(String[] args) {
Truck truck = new Truck(); // Car1 기본생성자 다음 Truck 기본생성자가 실행
//Car1 car1 = new Car1(); // Car1 기본생성자만 실행
}
}
5. 오버라이딩
오버라이딩(OverRiding)
부모가 가지고 있는 메소드와 똑같은 모양의 메소드를 자식이 가지고 있는 것
즉, 메소드를 재정의 하는 것
메소드를 오버라이드 하면, 항상 자식클래스에서 정의된 메소드 호출
그러나, 오버라이딩을 한다고 해서 부모의 메소드가 사라지는 것은 아님
(super 키워드를 이용하여 부모 클래스 호출 가능)
public class Bus2 extends Car2 {
public void run() {
super.run(); // 부모의 run메소드를 호출, 부모의 메소드의 기능도 쓰고 거기에 기능을 추가하고 싶을때 사용
System.out.println("Bus의 run 메소드");
}
}
public class BusExam2 {
public static void main(String[] args) {
Bus2 bus2 = new Bus2(); // 인스턴스 생성
bus2.run(); // 부모의 메소드가 아니라 자식의 메소드가 실행
}
}
public class Car2 {
// 오버라이딩
// 부모가 가지고 있는 메소드와 똑같은 모양의 메소드를 자식이 가지고 있는 것
// 즉, 메소드를 재정의 하는 것
// 부모의 기능을 그대로 사용하지 않을 경우 자식이 기능을 재정의 하는 것
public void run() {
System.out.println("Car2의 run 메소드");
}
}
6. 클래스 형변환
클래스 형변환
부모타입으로 자식 객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용 가능
자식 객체가 가지고 있는 메소드나 속성을 사용하고 싶으면 형변환이 필요
객체들 끼리도 형 변환이 가능하지만 상속관계가 있을때만 가능
부모타입으로 자식타입의 객체를 참조할 때는 묵시적 형변환이 발생
부모타임의 객체를 자식타입으로 참조하게 할때는 명시적 형변환을 해줘야 함.
단, 이렇게 형변환을 할때는 부모가 참조하는 인스턴스가 형변환 하려는 자식타입일때만 가능
public class Bus3 extends Car3{ // Bus3 is a Car3
public void ppangppang() { // 자식만 가지고 있는 메소드
System.out.println("빵빵");
}
}
public class BusExam3 {
public static void main(String[] args) {
// 클래스 형변환
// 부모타입으로 자식객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용 가능
// 자식객체가 가지고 있는 메소드나 속성을 사용하고 싶다면 형변환을 사용 해야 함
Car3 car3 = new Bus3(); // 부모타입으로 자식객체를 참조할 수 있음
car3.run();
// car3.ppangppang(); // 그러나 자식객체를 참조한다 해도, 부모가 가지고 있는 메소드만 사용 가능
// 즉, 부모 타입으로 자식을 가르킬 수 있지만, 부모가 가지고 있는 것만 사용 가능
// 그러나, 사용할 수 있는 방법이 있는데, 그것이 형 변환이다.
Bus3 bus3 = (Bus3)car3; // 형변환
bus3.run();
bus3.ppangppang(); // 따라서 사용 가능
// 그리고 car3를 참조하고 있는 것이 Bus3이기 때문에 형변환을 가능한 것
}
}
public class Car3 {
public void run() {
System.out.println("Car의 run 메소드");
}
}
※ 출처
'Java Note > [프로그래머스] 자바 입문(동영상 강의)' 카테고리의 다른 글
[프로그래머스] 자바 입문 > Part9. 예외처리 (0) | 2020.01.30 |
---|---|
[프로그래머스] 자바 입문 > Part8. 인터페이스와 다른 형식의 클래스 (0) | 2020.01.29 |
[프로그래머스] 자바 입문 > Part5. 클래스와 객체 (0) | 2020.01.23 |
[프로그래머스] 자바 입문 > Part4. 배열 (0) | 2019.12.20 |
[프로그래머스] 자바 입문 > Part3. 제어문 (0) | 2019.12.20 |