본문 바로가기
Challenge

6주차 과제: 상속

by Daisy :) 2020. 12. 26.
반응형

자바 상속의 특징 (내꺼 내꺼 부모꺼 내꺼 단, 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

댓글