늦은 프로그래밍 이야기

객체지향 (2) 상속, 접근제어자 본문

내일배움캠프/Java 기초

객체지향 (2) 상속, 접근제어자

한정규 2022. 11. 15. 21:16

상속 (Inheritance)

 - 기존의 클래스를 재사용하는 방식

 - 이미 설계된 클래스를 바탕으로 새로운 클래스를 만들 수 있다.

 - 상속을 통해 클래스 간 계층구조를 만든다.(슈퍼클래스, 서브클래스)

상속을 보여주는 UML Class Diagram

 

특징

 1) 부모클래스(슈퍼클래스)에서 정의된 필드와 메소드를 물려 받는다.

 2) 새로운 필드와 메소드를 추가할 수 있다. (오버로딩)

 3) 부모클래스(슈퍼클래스)에서 물려받은 메소드를 수정할 수 있다. (오버라이딩)

 

클래스 확장

자식클래스(서브클래스) 선언하기

 - 부모클래스(슈퍼클래스)를 확장하여 자식클래스(서브클래스)를 선언할 수 있다.

class 서브클래스명 extends 슈퍼클래스명 {
    서브클래스에 추가하는 멤버
    ...
    서브클래스의 생성자(인수목록) {
    	...
    }
    서브클래스에 추가하는 메소드(인수목록) {
    	...
    }
}

 

자식클래스(서브클래스)의 객체 생성

 - 객체를 생성하는 방법은 클래스의 객체를 생성하는 방법과 동일하다.

클래스명 변수명 = new 클래스명(인수);

예시

class Dog extends Animal {

    Dog(String name) {
        this.name = name;
    }

    public void cry() {
        System.out.println(name + " is barking!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog("코코");
        dog.cry();
    }
}

 - 부모클래스 Animal을 상속받은 자식클래스 Dog를 선언한다.

 

부모클래스의 생성자 지정

 - 자식클래스의 생성자에서 부모클래스의 생성자를 호출하고 싶은 경우 super()를 사용한다.

super(name, color);

오버로딩 (Overloading)

 - 한 클래스 내의 동일한 이름의 메소드를 여러개 정의하는 것.

 - 기존에 없는 새로운 메소드를 정의하는 것.

 

조건

 1) 메소드의 이름이 동일해야 한다.

 2) 매개변수의 개수 혹은 타입이 달라야 한다.

 

예시

  • 오버로딩이 아닌 경우
int add(int x, int y, int z) {
    int result = x + y + z;
    return result;
}

long add(int a, int b, int c) {
    long result = a + b + c;
    return result;
}

 - 반환 타입은 다르지만 매개변수의 자료형과 갯수가 같으므로 오버로딩이 아니다.

 

  • 오버로딩인 경우
int add(int x, int y, int z) {
    int result = x + y + z;
    return result;
}

long add(int a, int b, long c) {
    long result = a + b + c;
    return result;
}

int add(int a, int b) {
    int result = a + b;
    return result;
}

 - 첫번째와 두번째는 매개변수의 다입이 다르고, 세번째는 개수가 다르다.


오버라이딩 (Overriding)

 - 부모클래스로부터 상속받은 메소드의 내용을 변경하는 것.

 

조건

 1) 부모클래스의 메소드와 이름이 같아야 한다.

 2) 부모클래스의 메소드와 매개변수가 같아야 한다.

 3) 부모클래스의 메소드와 반환타입이 같아야 한다.

 

예시

class Animal {
    String name;
    String color;

    public void cry() {
        System.out.println(name + " is crying.");
    }
}

class Dog extends Animal {

    Dog(String name) {
        this.name = name;
    }
    
    @Override
    public void cry() {
        System.out.println(name + " is barking!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog("코코");
        dog.cry();
    }
}
// 자식클래스에서 override한 cry메소드의 문장이 출력된다.

 - 부모클래스인 Animal에 있는 cry 메소드와 메소드의 이름, 매개변수, 반환타입이 같고 메소드 내부의 반환문장이 바뀌었다.


접근제어자 (Access modifier)

 - 접근제어자 : 멤버 변수/함수 혹은 클래스에 사용되며 외부에서의 접근을 제한하는 역할을 한다.

 - 클래스 내부에 선언된 데이터를 부적절한 사용으로부터 보호.

 - 캡슐화(encapsulation)

 

종류

 1) private : 같은 클래스 내에서만 접근이 가능

 2) default(nothing) : 같은 패키지 내에서만 접근이 가능

 3) protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능

 4) public : 접근 제한이 전혀 없음.

 

예시

ModifierTest.java (패키지)

package pkg;

public class ModifierTest {
    private void messageInside() {  // private 같은 클래스 이외는 호출불가
        System.out.println("This is private modifier");
    }

    public void messageOutside() { // public 접근제한 없음.
        System.out.println("This is public modifier");
        messageInside();   // 같은 클래스 내여서 호출 가능.
    }

    protected void messageProtected() { // protected 같은 패키지, 다른패키지의 자손클래스만 호출가능
        System.out.println("This is protected modifier");
    }
    void messagePackagePrivate() {  // default 같은 패키지 내에서만 호출가능
        System.out.println("This is package private modifier"); 
    }
}

Main.java

import pkg.ModifierTest;

class Child extends ModifierTest {
    void callParentProtectedMember() {
        System.out.println("Call my parent's protected method");
        super.messageProtected();  // 다른 패키지의 자손클래스이기 때문에 protected 호출가능.
    }
}

public class Main {
    public static void main(String[] args) {
        ModifierTest modifierTest = new ModifierTest();

        modifierTest.messageOutside();  // public이기 때문헤 호출가능.
//        modifierTest.messageInside(); // compile error
//        modifierTest.messageProtected(); // compile error

        Child child = new Child();
        child.callParentProtectedMember();
    }
}

Comments