클래스와 인터페이스 1

cutiepazzipozzi·2023년 3월 27일
2

지식스택

목록 보기
12/35
post-thumbnail

클래스와 인터페이스는 추상화의 기본 단위로, 두개를 설계하는데 사용되는 다양한 요소들을 통해 더 유연하게 사용할 수 있는 방법을 알아보자.

여기서 추상화란?

= 각 클래스 간의 공통되는 부분을 뽑아 만든 상위 클래스
(그러나 꼭 상위 클래스일 필요는 없음)
= 코드 중복 방지, 유지 및 보수 편리 등의 장점을 가짐

  • 주로 추상화에는 abstract 제어자가 사용되는데, 이는 메서드나 클래스에 붙어 미완성 딱지를 붙여준다. 이를 통해 상속받아 구체적으로 구현하라는 의미를 내포한다.
  • 클래스의 경우에는 인스턴스를 당연히 생성할 수 없다.
  • 인터페이스도 추상화 클래스와 비슷한 기능을 하지만 일반 메서드나 변수를 구성원으로 가질 수 없는 높은 추상화 정도를 가진다.
    (ex. 상수로 정의할 때에는 public static final로 반드시 표기)
abstract class Student {} //클래스
abstract void check(); //메서드 -> {}대신 ()만 써도 됨

또한 시작에 앞서 정보은닉캡슐화에 대해 소개한다. 아래의 아이템 주제는 정보 은닉을 준수하는 컴포넌트를 설계하기 위한 가장 중요한 요소이기 때문이다.

캡슐화 = 관련이 있는 변수와 함수를 하나의 클래스에 묶어 외부에서 쉽게 접근하지 못하도록 은닉하는 것을 말한다.
이를 통해 외부에서 내부의 정보에 직접적으로 접근할 수 없고 객체가 제공하는 변수나 메서드를 통해서만 접근이 가능하다.
따라서 오류 범위를 줄일 수 있고, 재사용성이 높아지고, 컴포넌트의 단위가 작아져 디버깅이 쉬워지는 등의 장점을 가진다.

//우리가 아는 get, set 메서드가 예시이다.
public class Student {
	private String name;
    
    public void setName(String name) {
    	this.name = name;
    }
    public String getName() {
    	return this.name;
    }
}
public class Main {
	public static void main(String[] args) {
    	Student student = new Student();
        student.setName("뚱띵이");
        
        System.out.println(student.getName());
    }
}

#15 클래스와 멤버의 접근 권한을 최소화하라

= 소프트웨어가 올바로 동작하는 한 항상 가장 낮은 접근 수준을 부여해야 함!

  • 가장 상위(톱레벨?) 클래스와 인터페이스에 부여할 수 있는 접근 제한자는 package-privatepublic이다.
    만약 패키지 외부에서 사용할 일이 없다면 package-private(내부구현)을 무조건 사용하여 다음 release에서 수정, 교체, 제거를 편히 실시하자.
    public 이라면 API이기 때문에 영원히 관리해줘야 하기 때문이다.
    (이게 뭔 말인가 싶었는데 공개 API가 돼서 버전 관리를 해줘야 한다는 말이더라)

    접근 제한자들

    private = 멤버를 선언한 상위 클래스에서만 접근
    package-private = 멤버가 소속된 패키지 안의 모든 클래스에서 접근
    protected = 멤버를 선언한 클래스의 하위 클래스에서도 접근
    public = 모든 곳에서 접근 OK

  • 테스트를 목적으로 코드 접근 제한을 풀어주면 안된다.
    = package-private 접근 제한자의 요소까지 접근할 수 있음!

  • public static final 필드는 기본 타입이나 불변 객체를 참조해야 한다.
    (ex. 값이 정해진 상수 = 로또 당첨 숫자 개수 같은)
    이때 배열은 길이가 0이 아니면 변경이 가능하기 때문에

//1. private 접근 지정자로 변경하고 public으로는 변경 불가도록
private static final Integer[] Lottos = {1, 2, 3, 4, 5, 6};
public static final List<Integer> Values = Collections.unmodifiableList(Arrays.asList(Lottos));

//2. 배열은 private로 선언, 이 배열을 복사해서 반환하는 public 메서드
private static final Integer[] Lottos = {1, 2, 3, 4, 5, 6};
public static final Integer[] Values() {
    return Lottos.clone();
}
  • 또 자바 9에서 모듈 시스템이 도입되면서 두 가지의 암묵적 접근 수준이 추가되었다. 앞서 정리했듯이 모듈은 패키지들의 모음인데 자신 안의 패키지 중 공개할 것들을 module-info.java(모듈의 여러가지 설정을 정의하는 파일)에 명시해놓지 않으면 public, protected 멤버라도 외부에서 접근할 수 없다. 따라서 이 암묵적 접근 수준들은 public 수준과 protected 수준과 같지만, 그 효과가 모듈 내부로 한종되는 변종이 된다.
    - 종속성 : 이 모듈이 의존하는 다른 모듈 목록
    - 공용 패키지 : 모듈 외부에서 접근할 수 있는 모든 패키지 목록
      
    이때 모든 패키지는 모듈 전용(private)이 기본으로 설정되어 있기 때문에 공개적으로 모든 패키지들은 반드시 명시되어야 한다. 
    그러나 주의해야 한다. 모듈의 JAR 파일을 어플리케이션의 classpath에 두면 모듈 안의 모든 패키지는 마치 모듈이 없는 것처럼 행동한다. 그러나 꼭 필요한 경우가 아니라면 아직까진 널리 사용되지 않았기 때문에 사용하지 않는게 좋을 것 같다.

모듈 부분은 이렇게 자바에서 사용한 적이 없어서 더 찾아봐야 할 거 같다.. 그나마 JAR파일이 배포할 때 이용했던 파일이라 이름이 익숙한 정도

#16 public class에서는 public 메서드가 아닌 접근자 메서드를 활용하라

이 주제가 말하는 예시를 정말 간단히 이해하게 설명하자면

public class Student {
	public int age;
    public String name;
    //이렇게 되면 클래스 내부 표현 방식을 맘대로 사용자가 바꿀수도..
    //이렇게 필드를 모아주는 역할만 갖게 만들지 말고
}

pubilc class Student {
	private int age;
    private String name;
    
    public Student(int age, String name) {
    	this.age = age;
        this.name = name;
    }
    
    public int getAge() {
    	return this.age; //이런 접근자를 통해 유연한 사용이 가능토록함
    }
}

그러나 package-private 클래스 혹은 private 중첩 클래스라면 데이터 필드를 노출해도 문제가 없다. 오히려 접근자 방식보다 코드가 깔끔하여 더 나을 수도 있다.
중첩(Nested) 클래스: 클래스 안에 다른 클래스가 내포돼 있는 것

  • 바깥 클래스 멤버를 안의 클래스 멤버에서 사용 가능
  • 일반적으로 내부 클래스에서 static 멤버를 선언할 수 X

물론 public 클래스의 필드가 불변이라면 직접 노출시켜도 외부에서 변경이 불가하기 때문에 단점이 조금 줄지만, API(public)를 변경하지 않고는 표현 방식을 바꿀 수 없기 때문에 추가 작업을 진행할 수 있다.

참고

https://velog.io/@kai6666/Java-%EC%B6%94%EC%83%81%ED%99%94-%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4
https://wikidocs.net/219
https://forwe.tistory.com/27
https://madplay.github.io/post/minimize-the-accessibility-of-classes-and-members
https://cotak.tistory.com/190#%EC%A-%--%EB%B-%B-%--%EC%-D%--%EB%-B%--%EC%-D%--%--%EC%A-%--%EC%--%--%ED%--%--%EB%-A%--%--%EC%BB%B-%ED%-F%AC%EB%--%-C%ED%-A%B-%--%EC%--%A-%EA%B-%--
https://jaynamm.tistory.com/entry/JAVA-%EC%9E%90%EB%B0%94-%EC%BA%A1%EC%8A%90%ED%99%94-Encapsulation
https://mslim8803.tistory.com/39

profile
노션에서 자라는 중 (●'◡'●)

0개의 댓글