13일차 09/06 2022

SangYu Lee·2022년 9월 6일
0

codestates backend

목록 보기
14/30

keyword - 상속, 캡슐화

1. 상속

기존에 있던 클래스를 재활용하여 새로운 클래스를 만들어내는 것. 상위클래스에서 하위클래스로 확장한다고 생각하면 된다. 상위클래스의 멤버를 하위클래스에서 모두 가지고 있으며, 그러므로 하위클래스는 항상 상위클래스보다 멤버의 개수가 같거나 많다.
상속은 클래스 이름 옆에 extends 상위클래스 라고 표현한다.

class Syu extends Person {}

상속의 종류에는 여러가지가 있는데, 자바에서는 다중 상속은 지원하지 않는다. 다이아몬드 문제라고 메서드나 필드의 충돌의 여지가 있다고 해서 그렇다고 한다.

자바에서 지원하는 '상속'은 Single, multilevel inheritance이고 나머지는 지원하지 않는다.

상속을 사용하는 이유는

  1. 중복된 코드가 없기 때문에 효율적이다.
  2. 하위클래스들을 상위클래스로 표현할 수 있기 때문에 관리가 용이하다.(다형성)

포함
포함이란 것은 단순하게 클래스의 멤버로 다른 클래스의 참조변수를 선언하는 것이다.

class Person{
	int balance;
    String name;
    Address address;
}
class Address{
	String country;
    String city;
    int postcode;
}

여기서 Person 클래스의 객체를 만들어서 사용할 때 꼭 Address 객체를 생성해야 하는 것은 아니다. heap에 Person 객체가 만들어질 때 이미 Address 멤버의 자료형을 바탕으로 메모리를 할당받았기 때문에 기본형으로 초기화되어 있을 것이다.

메서드 오버라이딩(method overriding)
하위클래스가 상속받은 상위클래스의 메서드를 재정의하는 것이다.

조건이 3가지가 있는데

  1. 메서드 시그니쳐가 똑같아야한다.(메서드 이름, 매개변수, 반환 타입)
  2. 접근제어자가 상위클래스의 접근제어자보다 더 느슨해야한다.
  3. 예외는 상위클래스의 메서드보다 많이 선언할 수 없다.

메서드 오버라이딩의 활용은

class Vehicle{}

class Car extends Vehicle{}
class Motorcycle extends Vehicle{}
class Truck extends Vehicle{}

이렇게 Vehicle이라는 클래스를 상속받은 Car, Motorcylce, Truck이라는 세가지 하위클래스가 있다. 각각 상위클래스 vehicle의 run()이라는 메서드를 오버라이딩해서 다르게 구현했다.

Vehicle car = new Car();
Vehicle motor = new Motorcycle();
Vehicle truck = new Truck();

이 상황에서 각각의 클래스의 객체를 상위클래스 타입으로 선언하는게 가능한데 이것을 upcasting이라고 한다.


super & super()

super
부모 객체의 변수를 가리킬 때 사용되는데, 자식 객체의 변수와 이름이 같을 수도 있으니 헷갈리지 않게 구분하는 것이다.

super.count = count;

super()
부모의 생성자를 호출하는 것. 생성자는 super()는 첫줄에 와야하고 this()와 같이 쓰일 수 없다. 또한 모든 클래스는 Object 클래스를 상속받는데 생성자는 무조건 super()나 this()를 가지고 있어야 한다. 컴파일러가 자동으로 생성해서 직접 안해도 될 뿐이다.

class Person{
	int eyeNum;
	Person(int eyeNum) {
    	this.eyeNum = eyeNum;
    }
}

class Syu extends Person{
	String name;
    int eyeNum;
	Syu(String name) {
    	super(2);
        this.name = name;
    }
}

class Chw extends Person{
	String name;
    int eyeNum;
	Chw(String name) {
    	super(2);
        this.name = name;
    }
}

상위클래스의 생성자가 기본생성자가 아닐 경우에는 꼭 매개변수를 전달해주어야 한다.

2. 캡슐화

정보 은닉을 위해서 사용하는 방법으로, 접근제어자getter,setter가 있다.

접근제어자

public protected default private의 4가지가 있으며 각각의 접근권한을 보여주고 있다. 또한 대상에 따라 사용 가능한 접근 제어자가 다르다.

+패키지
클래스와 인터페이스의 묶음. 물리적인 디렉토리로 구분된다. 같은 패키지에서도 (.)기호로 계층 구조로 나뉠 수 있다.

package comstr.Test.vie

서로 다른 패키지에서는 클래스 이름이 같더라도 충돌이 발생하지 않는다. 다시말하면 클래스 다른 패키지의 클래스를 사용하려면 import를 통해 패키지를 참조해야 한다.
import 패키지.클래스명

import comstr.Test.*

getter & setter

객체지향의 캡슐화의 목적을 달성하면서도 데이터의 변경이 필요한 경우, 대표적으로 private 접근제어자가 포함되어 있는 객체의 변수의 데이터 값을 추가하거나 수정하고 싶을 때 쓰는 방법.

class User{
	private int uid;
    private String username;
    private String password;
    
    public int getUid() {
    	return this.uid;
    }
    public void setUsername(String name) {
    	this.username = name;
    }
}

getUid와 setUsername메서드는 User 클래스 내부에 위치하고 있기 때문에, private으로 설정된 멤버 변수에도 접근할 수 있는 권한이 있다. 클래스 외부의 main 함수에서 User객체.멤버변수 로는 접근할 수 없다. 이처럼 getter, setter는 private한 변수에 접근해서 값을 변경하거나 받아오는 역할을 한다. getter의 경우에는 보통 리턴 타입이 있어야 한다는 점을 유의해야 한다.

profile
아이스커피

0개의 댓글