자바 상속의 특징 (내꺼 내꺼 부모꺼 내꺼 단, private시에는 부모꺼 부모꺼)
상속이란 ? 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것 입니다.
- 코드의 재 사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여합니다.
- 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 이름을 키워드'extends'와 함께 써주기만 하면 됩니다.
- 자손 클래스는 조상 클래스의 모든 멤버를 상속받습니다.(단, 생성자와 초기화 블럭은 상속되지 않습니다)
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많습니다.
- 자손의 변경은 조상에 영향을 주지 않습니다.
- 자손클래스를 인스턴스화 할 떄 부모클래스가 먼저 인스턴스화 됩니다.
super 키워드
super키워드는 자식클래스에서만 사용이 가능합니다.
super는 내가 상속받은 부모의 인스턴스를 가리키고, 메서드내에서도 부모의 속성을 가지고 올 수 있습니다.
public class Parents {
private long money;
String familyName;
public Parents() { //생성자를 통해 기본 money초기화
this.money = 1_000_000_000;
}
public long getMoney() {
return money;
}
public static void main(String[] args) {
Child child = new Child("Kevin");
System.out.println(child.money);
System.out.println(child.getMoney());
System.out.println(child.getFullName());
}
}
class Child extends Parents{
String name;
long money;
private Child() {
this.money = 50_000_000;
}
public Child(String name) {
//super(); -> 내부적으로 super();를 먼저 실행하고 아래 코드들이 실행됩니다.
this();
this.name = name;
super.familyName = "Yang"; // super는 내가 상속받은 부모의 인스턴스를 가리킵니다.
}
public String getFullName() { // super는 메서드내에서도 부모의 속성을 가지고 올 수 있습니다.
return this.name + " " + super.familyName;
}
}
위의 코드를 실행하게 되면 아래 내용이 출력됩니다.
50000000
1000000000
Kevin Yang
메소드 오버라이딩
오버라이딩이란 부모에 있는 메소드를 자식이 가져와서 재정의하는 것 입니다.
1. 메서드 구조(반환타입, 메서드이름, 파라미터)가 동일하면 기능부의 내용이 달라도 상관이 없습니다.
2. 부모를 기준으로 자식이 접근제어자를 더 큰 범위로 변경하는 것은 가능하지만, 작은 범위로 변경하는것은 불가능 합니다.
3. 오버라이딩된 메서드는 어느 클래스를 기준으로 하더라도 가장 마지막에 오버라이딩된 메서드가 실행됩니다.
public class Parents {
private long money;
String familyName;
public Parents() {
this.money = 1_000_000_000;
}
protected long getMoney() {
return this.money;
}
public static void main(String[] args) {
Child child = new Child("Kevin");
Parents parents1 = (Parents)new Child("Daisy");
Parents parents2 = new Child2();//부모클래스는 자녀 클래스를 담을 수 있습니다.
System.out.println(child.money);
System.out.println(child.getMoney());
System.out.println(child.getFullName());
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
System.out.println(parents1.getMoney()); //어느 클래스를 기준으로 하더라도 가장 마지막에 오버라이딩된 메서드가 실행됩니다.
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
System.out.println(parents2.getMoney()); //어느 클래스를 기준으로 하더라도 가장 마지막에 오버라이딩된 메서드가 실행됩니다.
}
}
class Child extends Parents{
String name;
long money;
public Child() {
this.money = 50_000_000;
}
public Child(String name) {
this();
this.name = name;
super.familyName = "Yang";
}
public String getFullName() {
return this.name + " " + super.familyName;
}
public long getMoney() {
return money + super.getMoney();
} //메서드 구조가 동일하면 기능부의 내용이 달라도 상관이 없습니다.
// 부모를 기준으로 자식이 접근제어자를 더 큰 범위로 변경하는 것은 가능하지만, 작은 범위로 변경하는것은 불가능 합니다.
}
class Child2 extends Child{
public long getMoney() {
return 0;
}
위의 코드를 실행하게 되면 아래 내용이 출력됩니다.
50000000
1050000000
Kevin Yang
+++++++++++++++++++++++++++++++++++++++++
1050000000
+++++++++++++++++++++++++++++++++++++++++
0
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
위의 설명중 "3. 오버라이딩된 메서드는 어느 클래스를 기준으로 하더라도 가장 마지막에 오버라이딩된 메서드가 실행됩니다."에 해당하는 내용이며,
Parents parents1 = (Parents)new Child("Daisy");
이렇게 부모는 자식객체를 담을 수 있지만 반대로
Child child = new Parents();
로 자식이 부모의 객체를 담을 수 없습니다.
추상 클래스
목적
코드의 강제화
여러 클래스에서 공통적으로 사용되는 기능이 있을때
추상클래스로 공통적으로 사용되는 부분을 구현하고 고유한 기능을 수행하는 메서드만 추상메서드로 선언하여
각각의 클래스의 코드 중복을 막고 규격화된 코드의 형태를 유지할 수 있게 합니다.
특징
Parents p = new Parents(); -> 이 코드는 에러발생. abstract는 절대 객체를 만들 수 없습니다.
추상메서드:이름만 있고, 기능부가 없는 메서드 생성이 가능합니다.
추상클래스는 무조건 상속을 받아서 사용이 되고, 상속받은 클래스는 추상메서드를 오버라이딩하여 구현하여야 합니다.
public class Abstract {
public static void main(String[] args) {
// Parents p = new Parents(); -> 이 코드는 에러발생. abstract는 절대 객체를 만들 수 없습니다.
Parents p1 = new Child1();
Parents p2 = new Child2();
p1.printMoney();
p1.printName();
p2.printMoney();
p2.printName();
}
}
abstract class Parents{
public abstract void printName();//추상메서드:이름만 있고, 기능부가 없는 메서드 생성이 가능합니다.
public void printMoney() {
System.out.println(10_000_000);
}
}
class Child1 extends Parents{ //추상클래스는 무조건 상속을 받아서 사용이 되고, 상속받은 클래스는 추상메서드를 오버라이딩하여 구현하여야 합니다.
@Override
public void printName() {
System.out.println("Kevin");
}
}
class Child2 extends Parents{
@Override
public void printName() {
System.out.println("Daisy");
}
}
위의 코드를 실행하게 되면 아래 내용이 출력됩니다.
10000000
Kevin
10000000
Daisy
final 키워드
final이 변수에 붙으면 상수가 되고, 클래스에 붙으면 그 클래스를 상속 시킬 수 없다는 뜻이 됩니다.
그 클래스는 더이상 상속받을 수 없고 그 클래스가 마지막이 됩니다.
final이 붙은 Parents2클래스를 상속하려 하지만 아래와 같은 에러가 발생되며 상속되지않습니다.
Object 클래스
object 는 최상위객체로 모든 객체의 가장 조상은 object가 되고 , extends가 명시되지않은 모든 클래스는
Extends Object가 내부적으로 생성되어있습니다.
보통 hashCode(), toString(), equals()등이 가장 많이 사용됩니다.
<reference>
자바의 정석 저자 남궁 성
'Challenge' 카테고리의 다른 글
8주자 과제: 인터페이스 (0) | 2021.01.08 |
---|---|
7주차 과제: 패키지 (0) | 2021.01.02 |
5주차 과제: 클래스 (0) | 2020.12.19 |
4주차 과제: 제어문 (0) | 2020.12.03 |
3주차 과제: 연산자 (0) | 2020.11.25 |
댓글