Chavo Kim 2020. 10. 1. 23:02

1. inheritance(상속)이란?

하나의 클래스가 다른 클래스의 특징을 상속받은 채로 설치되는 것

종의 분류와 비슷하다고 볼 수 있다.

 

상속의 예

2. Inheritance(상속)의 장점

2-1. 모듈화

하나의 클래스를 잘 설치해두면 그 클래스를 기반으로 다른 클래스를 생성할 수 있다.

만약 수정 사항이 생기면 최상위 부모 클래스만 수정하면 그에 따른 수정 결과가 자식 클래스에게 상속됨

 

2-2. 재사용성

겹치는 attribute나 method가 있을 때 번거롭게 코드를 두 번 쓰지 않아도 된다.

 

3. Inheritance(상속) 사용 문법

extends를 이용해서 상속을 수행할 수 있다.

class Point{
	int x, y;
    public void move(int dx, int dy){x += dx; y += dy;}
}

class Point3d extends Point{
	int z;
    public void move(int dx, int dy, int dz)
    {x += dx; y += dy; z += dz;}
}

4. "Is-a" rule of inheritance

B 가 is a A의 관계일 때만 상속을 시켜줄 수 있다.

 

ex) Programmer is a person.

Mama also is a person.

 

Programmer와 Mama 클래스 모두 Person 클래스에서 상속 받을 수 있다.

 

그러나 "has-a" 관계일 때는 상속 불가능

 

ex) CarOwner has a Car

 

CarOwner는 Car 클래스에게 상속을 받을 수 없다.

 

5. 상속 관계

상속을 해주는 클래스를 부모 클래스(Superclass)

상속을 받는 클래스를 자식 클래스(Subclass)

라고 한다.

 

모든 클래스는 Object class의 자식 클래스!

 

5-1. Object class

모든 클래스는 default(extends를 사용하지 않아도)로 Object에 상속된다.

 

Object class의 대표적인 method들

 

(1) toString()

: object를 String으로 선언할 때의 값을 반환(ex) System.out.println(Object))

 

(2) getClass()

: class object를 반환할 때 class 대표형을 나타낸다.

 

(3) equals()

: class 간의 equality를 반환하는 method

 

finalize(), clone(), hashCode(),,....

 

해당 method들을 overriding을 통해서 자식 class에서 사용할 수 있다!

 

5-2. 상속의 종류

(1) Single Inheritance

 

(2) Multi-level Inheritance

 

(3) Hierarchical Inheritance

 

 

(4) Multiple Inheritance

: 여러 super class에게 상속을 받는 형태이지만,

java에서는 해당 상속을 허용하지 않는다.

단 여러 interface에 대해서는 상속이 가능하다.

 

multiple inheritance

 

6. Overriding & Hiding

6-1. Overriding

subclass는 override를 통해 superclass의 method를 재정의해서 사용할 수 있다.

(단, constructor는 overriding 불가능)

 

overriding을 하기 위한 조건

 

1. C가 A의 subclass여야 하고,

2. override하고자 한 method는 같은 func name, argument types, order(signature)를 가지고 있어야 한다.

3. 해당 method는 protected or public이다.

 

@Override notation을 쓰면 compiler가 미리 해당 method가 super class에 선언되어 있는지 확인하기 때문에 typo error를 방지할 수 있다.

 

class Parent{
	void printName() {System.out.println("Parent");}
}

class Child extends Parent {
	@Override /* it raise an error if there is no "printName" method in "Parent" class
    */
    void printName() {System.out.println("Child");}
}

 

6-2. Hiding

static method는 overriding이 아닌 hiding을 사용하는데, upcasting을 할 때 선언된 type으로 static method를 불러오게 된다.

 

static method의 경우 hiding이 사용된다.

 

inor.tistory.com/7 에서 들고 온 hiding의 예시

 

class Car{
    public void accelate(){
        System.out.println("일반 엔진 사용");
    }
     
    public static void stop(){
        System.out.println("일반 브레이크 사용");
    }
}
 
class RacingCar extends Car{
    @Override
    public void accelate(){
        System.out.println("레이싱카 전용 엔진 사용");
    }
     
    public static void stop(){
        System.out.println("레이싱카 전용 브레이크 사용");
    }
}
 
public class Overriding {
    public static void main(String[] args) {
        Car myCar = new RacingCar();
        //일반 메서드
        myCar.accelate();
        // "레이싱카 전용 엔진 사용" 출력
        
        //클래스 메서드
        myCar.stop();
        // "일반 브레이크 사용" 출력
    }
}


출처: https://inor.tistory.com/7 [Inor]

6-3. Type Casting

하나의 데이터 타입을 다른 데이터 타입으로 바꾸는 것.

 

casting은 instance 그 자체의 타입(actual type)을 바꾸지 않고, explicit data type만 바꾸게 된다.

 

Upcast : superclass의 타입으로 casting 하는 것

 

Downcast : subclass의 타입으로 casting하는 것

 

Upcasting은 별다른 요구사항 없이 intrinsic으로 자동으로 이루어진다.

 

Parent parent1 = new Child(); // Intrinsic Casting
Parent parent2 = (Parent) (new Child()); // Explicit Casting
class Parent{
	void printName() {System.out.println("Parent");}
}

class Child extends Parent {
	@Override
    void printName() {System.out.println("Child");}
}

Child child = new Child();
child.printName(); //Child
Parent parent = (Parent) child;
parent.printName(); //Child

/* parent still points to the instance of the Child class Casting does NOT change
the type of the instance itself. */

 

Downcasting

: explicit하게 cast를 해줘야 함.

runtime 때 type checking이 이루어짐

 

class Parent{
	void printName() {System.out.println("Parent");}
}

class Sister extends Parent {
	@Override
    void printName() {System.out.println("Sister");}
}

class Brother extends Parent {
	@Override
    void printName() {System.out.println("Brother");}
}

Parent parent = (Parent) (new Sister());
parent.printName(); //Sister
Brother sister = (Brother) parent;
/* Exception in thread "main"
java.lang.ClassCastException: class Sister cannot be cast to class Brother
*/

6-4. super

keyword

super

를 사용해서 subclass 내부에서 superclass로 접근할 수 있다.

 

class T1 {String s() {return "1";}}
class T2 extends T1 {String s() {return "2";}}
class T3 extends T2 {String s() {return "3";}
	void test(){
    	System.out.println("s() = " + s());
        System.out.println("super.s() = " + super.s());
        System.out.println("((T2)this).s() = " + ((T2)this).s());
    	System.out.println("((T1)this).s() = " + ((T1)this).s());
	}
}

T3 t3 = new T3();
t3.test();

/*
s() = 3
super.s() = 2
((T2)this).s() = 3
((T1)this).s() = 3
*/

 

super();

를 사용해서 superclass의 constructor를 선언할 수도 있다.

 

하지만 direct하게 grandparent에 접근하는 것은 금지되어 있음

ex) super.super();

 

또한 subclass constructor에 superclass constructor를 선언하지 않아도 default로 superclass를 선언하게 된다.

 

 

class Point {
	int x, y;
    Point() {x = 1; y = 1;}
}

class ColoredPoint extends Point {
	int color = 0xFF00FF;
}

//main method
ColoredPoint cp = new ColoredPoint();
System.out.println(cp.color);

//Order of execution
ColoredPoint() {super();}
Point() {super();}
Object() {}
x = 1; y = 1;
int color = 0xFF00FF;;

 

7. 접근 제한자

7-1. Public & protected

subclass에게 상속되며 overriding이 가능하다.

 

7-2. Default vs Protected

default는 package 밖에 있는 subclass에 상속이 안되지만

protected는 가능

 

package 사이의 interaction을 관리할 때 둘을 구분한다.

 

7-3. Private

private한 member들은 상속은 되지만 subclass에서 접근할 수 없음.

 

getter나 setter를 이용한 indirect way로 접근 가능

 

7-4. Final

final class는 상속되지 않는다.

 

method를 final로 선언하면 해당 method가 overriding되는 것을 방지할 수 있다.

variable을 final로 선언하면 해당 variable은 갱신되지 않는다.