자바의 정석 기초편 - 객체지향개념 공부(3)

인영·2022년 11월 3일
0

자바의 정석

목록 보기
3/6

상속(inheritance)

기존의 클래스로 새로운 클래스를 작성하는 것(코드의 재사용)
두 클래스를 부모와 자식으로 관계를 맺어주는 것

class 자식클래스 extends 부모클래스 {}
class Parent {}
class Child extends Parent { } // 상속 관계

자손은 조상의 모든 멤버를 상속받는다.(생성자, 초기화블럭 제외)
자손의 멤버 개수는 조상보다 적을 수 없다.(같거나 많음)

class Parent {
	int age; // 멤버 1개
}
class Child extends Parent { } // 자신의 멤버 0개, 상속받는 멤버 1개 = 총 멤버 1개

자손의 변경은 조상에 영향을 미치지 않는다.
단, 조상의 변경은 자손에 영향을 미친다.

class Parent {
	int age; // 멤버 1개
}
class Child extends Parent { // 자신의 멤버 1개, 상속받은 멤버 1개 = 총 멤버 2개
	void play() { // 새로운 멤버 추가
    	System.out.println("놀자~");
    }
}

포함(composite) 관계

클래스의 멤버로 참조변수를 선언하는 것
작은 단위의 클래스를 만들고, 이 들을 조합해서 클래스를 만든다.

class Point {
	int x;
    int y;
}
class Circle {
	Point c = new Point(); // 원점
    int r; // 반지름(radius)
}

클래스 간의 관계 결정하기

상속관계 ~은 ~이다. (is-a)
포함관계 ~은 ~을 가지고 있다. (has-a)

class Circle extends Point {
	int r;
}

❌ 원(Circle)은 점(Point)이다 - Circle is a Point.
상속은 꼭 필요할 때만.

class Circle {
	Point c = new Point();
    int r;
}

⭕️ 원(Circle)은 점(Point)을 가지고 있다. - Circle has a Point.
90%가 포함관계.


단일 상속(single inheritance)

Java는 단일상속만을 허용한다.(c++은 다중상속 허용)

class TvDVD extends Tv, DVD { } // 에러! 조상은 하나만 허용된다.

비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 한다.


Object클래스 - 모든 클래스의 조상

부모가 없는 클래스는 자동적으로 Object클래스를 상속받게 된다.
모든 클래스는 Object 클래스에 정의된 11개의 메서드를 상속받는다.
toString(), equals(Object obj), hashCode(), ...

class Tv {} // 부모가 없는 클래스
class Tv extends Object {} // 컴파일러가 자동 추가

오버라이딩(overriding)

상속받은 조상의 메서드를 자신에 맞게 변경하는 것

class Point {
	int x;
    int y;
    String getLocation() {
    	return "x:"+x+", y:"+y;
    }
}

선언부 변경 불가.
내용만 변경 가능(구현부 {})
조상의 getLocation()을 오버라이딩

class Point3D extends Point {
	int z;
    String getLocation() { // 오버라이딩
    	return "x:"+x+", y:"+y+", z:"+z;
    }

오버라이딩의 조건

  1. 선언부가 조상 클래스의 메서드와 일치해야 한다.
    String getLocation() - 선언부(반환타입, 메서드이름, 매개변수 목록)
  2. 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
    public, protexted, default, private
  3. 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
    조상이 예외 2개일 때 자손도 작거나 같아야 함

오버로딩 vs 오버라이딩

이름만 비슷하지 전혀 관계가 없는데... 차이를 물을 때가 있기 때문에 알아가자

오버로딩: 기존에 없는 새로운 메서드를 정의하는 것(new, 이름이 같음) -> 상속과 관계 X
오버라이딩: 상속받은 메서드의 내용을 변경하는 것(change, modify) -> 상속과 관계 O

class Parent {
	void parentMethod() {}
}

class Child extends Parent {
	void parentMethod() {} // 오버라이딩
    void parentMethod(int i) {} // 오버로딩
    
    void childMethod() {} // 메서드 정의
    void childMethod(int i) {} // 오버로딩
    void childMethod() {} // 에러! 중복 정의
}

참조변수 Super

객체 자신을 가리키는 참조변수. 인스턴스 메서드(생성자)내에만 존재
조상의 멤버를 자신의 멤버을 구별할 때 사용
(this와 비슷, this는 lv와 iv를 구별할 때 사용)

class Ex {
	public static void main(String args[]) {
    	Child c = new child();
    	c.method();
  	}
}
class Parent { int x = 10; } // super.x
class Child extends Parent {
	int x = 20; // this.x
    void method() {
    	System.out.println("x="+x); // x=20
        System.out.println("this.x="+this.x); // this.x=20
        System.out.println("super.x="+super.x); // super.x=10
    }
}

super() - 조상의 생성자

조상의 생성자를 호출할 때 사용
조상의 멤버는 조상의 생성자를 호출해서 초기화

class Point {
	int x, y;
    
    Point(int x, int y) {
    	this.x = x;
        this.y = y;
    }
}
class Point3D extends Point {
	int z;
    
    Point3D(int x, int y, int z) {
		super(x, y); // 조상클래스의 생성자 Point(int x, int y)를 호출
        this.z = z; // 자신의 멤버를 초기화
   	}
}

🌟생성자의 첫 줄에 반드시 생성자를 호출해야 한다. 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super();를 삽입

0개의 댓글