다시 하자 기초! 상속과 접근제한자
상속의 정의와 장점
상속이란 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다. 상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 용이
조상클래스 - 부모클래스, 상위클래스, 기반클래스
자손클래스 - 자식클래스, 하위클래스, 파생된클래스
상속 시 주의할점
1.자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
2.생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
위 그림처럼 Point3D는 x,y,z를 각각 만들어서 사용이 가능하지만 Point라는 x,y가 있는 클래스를 상속받아서 z만 추가한 형태로 사용이 가능하다. 그리고 자손 클래스의 인스턴스를 만들면 조상 클래스의 인스턴스를 생성하지 않아도 조상 클래스의 멤버 변수들을 사용할 수 있다.
상속관계
부모클래스는 상속받은 Child와 Child2는 아무런 관계가 없다. 서로 영향은 안주지만 만약 두 클래스간에 공통적으로 사용되는 변수가 생긴다면 각각 따로 넣기보단 부모에 그걸 추가해 서로 나눠받도록 구성하는게 바람직하다.
또한 자식클래스의 변수 추가는 부모 클래스에 영향을 안주기 때문에 이 점도 유의해야 할 것.
포함관계
-한 클래스의 멤버변수로 다른 클래스를 선언하는 것
-작은 단위의 클래스를 먼저 만들고, 이 들을 조합해서 하나의 커다란 클래스를 만든다.
상속이 아닌 방식으로 다른 클래스를 선언하여 처리하는 것.
클래스간의 관계 결정하기 - 상속 vs 포함
가능한 한 많은 관계를 맺어주어 재사용성을 높이고 관리하기 쉽게 한다.
is-a와 has-a를 가지고 문장을 만들어서 상속으로 구성할지 포함관계를 할지 결정할 수 있다.
상속관계 - '~은 ~이다.(is-a)'
포함관계 - '~은 ~을 가지고 있다.(has-a)'
ex)원은 점이다.
원은 점을 가지고 있다.
단일상속
다른 객체지향 언어에서는 다중상속을 허용한다. 하지만 자바에서는 단일상속만을 허용한다. 다중상속을 하게 될 경우 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있다는 장점이 있지만 클래스간의 관계가 매우 복잡해진다는 이유와 부모클래스간의 중복되는 변수이름이나 메서드를 구별할 방법이 없다는 단점을 갖고 있다. 그렇기 때문에 다소 불편한 점이 있긴 하겠지만 클래스 간의 관계가 보다 명확해지고 코드를 더욱 신뢰할 수 있다는 장점으로 단일 상속을 사용한다.
Object 클래스
모든 객체들은 자동적으로 오브젝트 클래스를 상속받게 되어있다. 그렇기 때문에 아무런 상속도 받지 않은 클래스에 컴파일을 해보면 extends Object가 보이게 된다. 그렇기에 결국 최상위 조상으로는 Object클래스가 나온다. 우리가 클래스에서 자주 사용하는 toString()이나 equals()를 바로 사용가능 한 것도 사실은 Object클래스에서 사용하는 것이다.
super
자손 클래스에서 부모 클래스의 멤버를 참조할 때 사용되는 변수다. 상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때는 this와 super로 구별 할 수 있다. 부모클래스로부터 상속받은 멤버도 자손 클래스 자신의 멤버이므로 super대신 this를 사용할 수 있지만 이름이 같아서 구별해야되는 경우에 사용한다. 메서드를 호출 할 경우에도 같은 방식으로 사용하면 된다.
super()의 이유!
자식 클래스를 호출할 때 부모의 생성자도 호출해서 초기화 작업을 해야지만 사용이 가능한 것이다. 그렇기에 자식 클래스에서 super()라는 작업으로 부모의 초기화 작업을 자동으로 해주게끔 해야함. 없으면 컴파일러가 자동적으로 넣어주긴함
제어자
제어자는 클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여한다. 제어자의 종류는 크게 접근 제어자와 그 외의 제어자로 나눌 수 있다.
접근 제어자 - public protected default private
그 외 - static final abstract native transient synchronized volatile strictfp
제어자는 클래스나 멤버변수와 메서드에 주로 사용되며, 하나의 대상에 대해서 여러 제어자를 조합하여 사용하는 것이 가능하다. 단 접근 제어자는 한 번에 네 가지 중 하나만 선택해서 사용할 수 있다. 즉, 하나의 대상에 대해서 public과 private을 함께 사용할 수 없다는 것이다.
final - 마지막의 변경될 수 없는
상수값을 지정하는 것으로 오버라이딩도 되지 않으며 변경 되지 않는 ReadOnly가 되는 변수 선언
abstract - 미완성의 의미를 가지고 있다. 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상 메서드를 선언하는데 사용된다.
사용 될 수 있는 대상
1. 클래스 - 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.
2. 메서드 - 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다.
접근 제어자
멤버 또는 클래스에 사용되어, 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 한다. 접근 제어자가 default임을 알리기 위해 실제로 default를 붙이지는 않는다. 클래스나 멤버변수, 메서드, 생성자에 접근 제어자가 지정되어 있지 않다면 접근 제어자가 default임을 뜻한다.
private 같은 클래스 내에서만 접근 가능
default 같은 패키지 내에서만 접근 가능
protected 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근 가능
public 접근 제한이 전혀 없다
접근 제어자를 이용한 캡슐화
이렇게 외부에서의 접근을 제한 하는 이유는 보통 클래스 내부에 선언된 데이터를 보호하기 위해서다. 데이터가 유효한 값을 유지하도록 또는 비밀번호와 같은 데이터를 외부에서 함부로 변경하지 못하도록 하기 위해서는 외부로부터의 접근을 제한하는 것이 필요하다. 이것을 데이터 감추기, 객체지향개념의 캡슐화에 해당하는 내용이다.
그리고 외부에 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서 사용하기도 한다.
생성자의 접근 제한자가 private 일 경우 (싱글톤 패턴)
생성자의 접근 제한자가 private라면 외부에서 인스턴스를 만들 수 없을 것이다. 하지만 그 클래스 내부의 메서드는 public으로 생성을 해서 인스턴스는 사용하도록 할 수 있다. 하지만 이 메서드는 public인 동시에 static이여야한다.
싱글톤 패턴의 장점
고정된 메모리 영역을 얻으면서 한번의 new로 인스턴스를 사용하기 때문에 메모리 낭비를 방지할 수 있음
또한 싱글톤으로 만들어진 클래스의 인스턴스는 전역 인스턴스이기 때문에 다른 클래스의 인스턴스들이 데이터를 공유하기 쉽다.
DBCP(DataBase Connection Pool)처럼 공통된 객체를 여러개 생성해서 사용해야하는 상황에서 많이 사용.
(쓰레드풀, 캐시, 대화상자, 사용자 설정, 레지스트리 설정, 로그 기록 객체등)
안드로이드 앱 같은 경우 각 액티비티나 클래스별로 주요 클래스들을 일일이 전달하기가 번거롭기 때문에
싱글톤 클래스를 만들어 어디서나 접근하도록 설계하는 것이 편하기 때문...
+ 인스턴스가 절대적으로 한개만 존재하는 것을 보증하고 싶을 경우 사용.
+ 두 번째 이용시부터는 객체 로딩 시간이 현저하게 줄어 성능이 좋아지는 장점!
싱글톤 패턴의 단점
싱글톤 인스턴스가 너무 많은 일을 하거나 많은 데이터를 공유시킬 경우 다른 클래스의 인스턴스들 간에
결합도가 높아져 "개방-폐쇄 원칙" 을 위배하게 된다. (=객체 지향 설계 원칙에 어긋남)
따라서 수정이 어려워지고 테스트하기 어려워진다.
또한 멀티쓰레드환경에서 동기화처리를 안하면 인스턴스가 두개가 생성된다든지 하는 경우가 발생할 수 있음
개발을 할때 항상 들어온 goto는 쓰면 안돼! 전역 객체는 안 좋은거야! 라는 말 처럼 꼭 필요한 경우아니면
지양해야함. // 적절히 잘 쓰면 아주 좋음, (그게 어렵지)
마지막으로 제어자를 조합해서 사용할 때의 주의할 점
1. 메서드에 static과 abstract를 함께 사용할 순 없다.
2. 클래스에 abstract와 final을 동시에 사용할 수 없다.
3. abstract메서드의 접근제어자가 private일 수 없다.
4. 메서드에 private과 final을 같이 사용할 필요는 없다.