상속, 캡슐화

seongmin·2022년 9월 6일
0

Java

목록 보기
5/30
post-thumbnail

상속

  • 상속은 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 자바의 문법 요소이다.

  • 상위 클래스 - 하위 클래스는 서로 상속 관계에 있다고 하며, 하위 클래스는 상위 클래스가 갖고 있는 모든 멤버를 상속한다.

  • 상속을 통해 클래스를 작성하면 코드를 재사용하여 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있어 코드의 중복을 제거할 수 있다.

  • 상속은 다형적(하나의 객체가 여러 모양으로 표현될 수 있다는 것) 표현이 가능하다는 장점이 있다.
    -> ex) '나는 사람이다.' 그와 동시에 '나는 학생이다.'


  • 클래스를 상속할 때에는 extends 키워드를 사용하며, 클래스명 다음에 extends 상위 클래스명을 사용하여 정의한다.
class Person {
    String name;
    int age;

    void learn(){
        System.out.println("공부를 합니다.");
    };
    void walk(){
        System.out.println("걷습니다.");
    };
    void eat(){
        System.out.println("밥을 먹습니다.");
    };
}

class Programmer extends Person { // Person 클래스로부터 상속. extends 키워드 사용 
    String companyName;

    void coding(){
        System.out.println("코딩을 합니다.");
    };
}

포함관계

  • 포함(composite)은 상속처럼 클래스를 재사용할 수 있는 방법으로, 클래스의 멤버로 다른 클래스 타입의 참조변수를 선언하는 것을 의미한다.

  • 상속과 포함관계는 클래스 간의 관계가 ~은 ~이다(IS-A) [상속] 관계인지 ~은 ~을 가지고 있다(HAS-A) [포함]관계인지 문장을 만들어 생각해보는 것이다.

메서드 오버라이딩

  • 메서드 오버라이딩(Method Overriding)은 상위 클래스로부터 상속받은 메서드와 동일한 이름의 메서드를 재정의하는 것이다.

  • 성립조건

  1. 메서드의 선언부(메서드 이름, 매개변수, 반환타입)이 상위클래스의 그것과 완전히 일치해야한다.
  2. 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야 한다.
  3. 예외는 상위 클래스의 메서드보다 많이 선언할 수 없다.

  • 배열로 한번에 관리하는 것 또한 가능하다.
Vehicle[] vehicles = new Vehicle[] { new Bike(), new Car(), new MotorBike()};
for (Vehicle vehicle : vehicles) {
        vehicle.run();

super / super ()

  • super 키워드는 상위 클래스의 객체, super()는 상위 클래스의 생성자를 호출하는 것을 의미하며, 공통적으로 모두 상위 클래스의 존재를 상정하며 상속 관계를 전제한다.

  • 두 개의 같은 이름의 변수를 구분하기 위한 방법이 바로 super 키워드다. super 키워드를 사용하면 부모의 객체의 멤버 값을 참고한다.

  • super() 메서드 또한 this()와 마찬가지로 생성자 안에서만 사용가능하고, 반드시 첫 줄에 와야한다. 모든 생성자의 첫 줄에는 반드시 this() 또는 super() 가 선언되어야 한다.

만약 super() 가 없는 경우에는 컴파일러가 생성자의 첫 줄에 자동으로 super() 를 삽입한다. 상위클래스에 기본생성자가 없으면 에러가 발생하게 된다.

Object 클래스

  • Object 클래스는 자바의 클래스 상속계층도에서 최상위에 위치한 상위클래스다. 따라서 자바의 모든 클래스는 Object 클래스로부터 확장된다.
class ParentEx {  //  컴파일러가 "extends Object" 자동 추가 
}
class ChildEx extends ParentEx {
}

-> ParentEx 클래스를 상속받아 ChildEx 클래스를 만들었을 때 상위클래스 ParentEx는 아무것도 상속하고 있지 않기에 컴파일러는 extends Object를 삽입한다.

  • Object 클래스에서 확장되어 사용되는 대표적인 메서드
메서드명반환타입주요내용
toString()String객체 정보를 문자열로 출력
equals(ObjectObj)boolean등가 비교 연산(==)과 동일하게 스택 메모리값을 비교
hashCode()int객체의 위치정보 관련. Hashtable 또는 HashMap 에서 동일 객체여부 판단
wait()void현재 쓰레드 일시정지
notify()void일시정지 중인 쓰레드 재동작

캡슐화

  • 캡슐화란 특정 객체 안에 관련된 속성과 기능을 하나의 캡슐(capsule)로 만들어 데이터를 외부로부터 보호하는 것이다.

  • 캡슐화를 하는 이유로는, 데이터 보호의 목적내부적으로만 사용되는 데이터에 대한 불필요한 외부 노출을 방지하기 위함이다.

  • 외부로부터 객체의 속성과 기능이 함부로 변경되지 못하게 막고, 데이터가 변경되더라도 다른 객체에 영향을 주지 않기에 독립성을 확보할 수 있고 유지보수와 코드 확장 시에도 오류의 범위를 최소화할 수 있어서 효과적으로 코드를 유지보수하기에 용이하다.

패키지

  • 패키지(package)란 특정한 목적을 공유하는 클래스와 인터페이스의 묶음을 의미한다.

  • 자바에서 패키지는 물리적인 하나의 디렉토리(directory)이고, 하나의 패키지에 속한 클래스나 인터페이스 파일은 모두 해당 패키지에 속해있다.

  • 이 디렉토리는 하나의 계층구조를 가지고 있는데, 계층 구조 간 구분은 점(.) 으로 표현된다.
    패키지가 있는 경우 소스 코드의 첫 번째 줄에 반드시 package 패키지명;이 표시되어야 하고, 만약 패키지 선언이 없으면 이름없는 패키지에 속하게 된다.

  • 패키지로 클래스를 묶는 것의 장점은 클래스의 충돌을 방지해주는 기능으로 같은 이름의 클래스를 가지고 있더라도 각각 다른 패키지에 소속되어 있다면 이름으로 인한 충돌이 발생하지 않는다.

import 문

  • import문 은 다른 패키지 내의 클래스를 사용하기 위해 사용하며, 일반적으로 패키지 구문과 클래스문 사이에 작성한다.
package practicepack.test2; // import문을 사용하는 경우

import practicepack.test.ExampleImp // import문 작성
<import 패키지명.클래스명; 또는 import 패키지명.*;>

public class PackageImp {
		public static void main(String[] args) {
			ExampleImp x = new ExampleImp(); // 이제 패키지명을 생략 가능
		}
}
  • 같은 패키지에서 여러 클래스가 사용될 때는 import문 을 여러번 사용하기보다는 import 패키지명.* 으로 작성하면 해당 패키지의 모든 클래스를 패키지명 없이 사용 가능하다.

접근 제어자

  • 제어자(Modifier)는 자바 프로그래밍에서 클래스, 필드, 메서드, 생성자 등에 부가적인 의미를 부여하는 키워드를 의미한다.
접근 제어자기타 제어자
public, protected, (default), privatestatic, final, abstract, native, transient, synchronized 등
  • 하나의 대상에 대해서 여러 제어자를 사용할 수 있지만, 각 대상에 대해서 접근 제어자는 단 한번만 사용할 수 있다.

  • 접근 제어자를 사용하면 클래스 외부로의 불필요한 데이터 노출을 방지(data hiding)할 수 있고, 외부로부터 데이터가 임의로 변경되지 않도록 막을 수 있다.

접근 제어자접근 제한 범위
private동일 클래스에서만 접근 가능
default동일 패키지 내에서만 접근 가능
protected동일 패키지 + 다른 패키지의 하위 클래스에서 접근 가능
public접근 제한 없음

public(접근 제한 없음) > protected(동일 패키지 + 하위클래스) > default(동일 패키지) > private(동일 클래스)

  • 변수명 앞에 아무런 접근제어자가 없는 경우에는 자동으로 해당 변수의 접근 제어자는 default 가 된다.

getter 와 setter 메서드

  • setter 메서드는 외부에서 메서드에 접근하여 조건에 맞을 경우 데이터 값을 변경 가능하게 해주고 일반적으로 메서드명에 set- 을 붙여서 정의한다.

  • getter 메서드는 이렇게 설정한 변수 값을 읽어오는 데 사용하는 메서드이며, get- 을 메서드명 앞에 붙여서 사용한다.

  • settergetter 메서드를 활용하면 데이터를 효과적으로 보호하면서도 의도하는 값으로 값을 변경하여 캡슐화를 보다 효과적으로 달성할 수 있다.

public class GetterSetterTest {
    public static void main(String[] args) {
        Worker w = new Worker ();
        w.setName("김코딩");
        w.setAge(30);
        w.setId(5);

        String name = w.getName();
        System.out.println("근로자의 이름은 " + name);
        int age= w.getAge();
        System.out.println("근로자의 나이는 " + age);
        int id = w.getId();
        System.out.println("근로자의 ID는 " + id);
    }
}

class Worker {
    private String name;       // 변수의 은닉화. 외부로부터 접근 불가
    private int age;
    private int id;

    public String getName() {    // 멤버변수의 값
        return name;
    }

    public void setName(String name) {       // 멤버변수의 값  변경
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age < 1 ) return;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId (int id) {
        this.id = id;
    }
}

0개의 댓글