DAY - 16
어제 상속과 포함을 배우다가 끝났는데 뒤에 조금 더 남아있었다.
자바에서는 단일상속만을 허용한다.
다중상속을 허용하면 여러 클래스로부터 상속받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있다는 장점이 있지만, 클래스간의 관계가 매우 복잡해진다는 것과 서로 다른 클래스로부터 상속받은 멤버간의 이름이 같은 경우 구별할 수 있는 방법이 없다는 단점이 있다.
이 부분은 프로그래밍 언어마다 차이가 있을 수 있다.
추가적으로 모든 클래스는 상속된 클래스이다.
다만 명시하지 않았을 경우 최상위에 있는 Object라는 클래스로부터의 상속이 생략되어있는 것이다.
오버라이딩
조상클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라 한다.
다만 오버라이딩은 인스턴스메서드만 가능하다. 이 오버라이딩은 후에 배울 다형성에서 자주 쓰이게 될 것이다.
자손클래스에서 오버라이딩하는 메서드는 조상클래스의 메서드와
1. 이름이 같아야 한다.
2. 매개변수가 같아야 한다.
3. 반환타입이 같아야 한다.
즉 메서드의 선언부가 같아야 한다는 것인데 1.5버전부터 공변반환타입이라는 것이 추가되어, 반환타입을 자손클래스의 타입으로 변경하는 것은 가능하도록 조건이 완화되었다.
super
super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다.
앞서 멤버변수와 지역변수의 이름이 같을 때 this를 붙여 구별했듯이 상속받은 멤버와 자신의 멤버가 이름이 같을 때는 super를 붙여 구별할 수 있다.
여기서 만약 Parent 클래스의 int x = 10; 이 문장을 삭제하면 마지막 super.x의 값은 5가 된다.
여기까지 이해를 하고 넘어가는것이 좋다.
하지만 여기서 GrandParent클래스의 int x = 5; 마저 삭제한다면 컴파일에러가 발생한다.
super()
this()와 마찬가지로 이역시 생성자이다.
this()는 같은 클래스의 다른 생성자를 호출하는 데 사용되지만, super()는 조상 클래스의 생성자를 호출하는데 사용된다.
최상위 클래스인 Object클래스를 제외한 모든 클래스의 생성자는 첫 줄에 반드시 자신의 다른 생성자 또는 조상의 생성자를 호출해야 한다.
만약 그렇지 않으면 생성자의 첫줄에 컴파일러가 자동으로 super(); 를 추가한다.
일반적으로 super는 this에 비해 사용 빈도가 압도적으로 낮다.
package와 import
패키지란 클래스의 묶음이다.
패키지에는 클래스 또는 후에 배울 인터페이스를 포함시킬 수 있으며 서로 관련된 클래스들끼리 그룹단위로 묶어 놓음으로써 클래스를 효율적으로 관리할 수 있다.
지금까지는 단순히 클래스 이름으로만 클래스를 구분했지만 사실 클래스의 실제 full name은 패키지명을 포함한 것이다.
패키지를 선언하는 것은 매우 간단하다.
맨위에 package 패키지명 : 이렇게 써주면 끝이다.
패키지명은 대소문자를 모두 허용하지만, 클래스명과 쉽게 구분하기 위해 소문자로 하는 것을 원칙으로 한다.
코드를 작성할 때 다른 패키지의 클래스를 사용하려면 패키지명이 포함된 클래스 이름을 사용해야 한다.
하지만 매번 패키지명을 붙여서 작성하는 것은 매우 불편하기 때문에 사용하고자 하는 클래스의 패키지를 미리 명시하게 되는데 이때 사용하는 것이 import이다.
즉 import란 코드에 사용된 클래스의 패키지에 대한 정보를 제공하는 것이다.
import문은 키워드인 import와 패키지명, 생략하고자 하는 클래스의 이름은 써주면 된다.
하지만 같은 패키지에서 여러개의 클래스가 사용된다면 import문을 여러번 사용하는 대신 클래스명.*; 을 이용해서 지정된 패키지에 속하는 모든 클래스를 사용할 수 있다.
이때 import문 앞에 static을 붙일 수가 있는데 이는 static멤버를 호출할 때 클래스이름을 생략할 수 있다.
제어자
제어자는 클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여한다.
크게 접근제어자와 그외의 제어자로 나뉘는데 접근제어자는 public, protected, default, private가 있고
그 외에는 static, final, abstract, native, transient, synchronized, volatile, strictfp등이 있다.
이 중에서 접근제어자로는 public, private가 많이 사용되고
그 외 중에는 static, final, abstract가 많이 사용된다.
static은 '클래스의' 라는 의미를 가지고 있다. 이는 하나의 변수를 모든 인스턴스가 똑같이 공유하기 때문이다.
인스턴스 멤버를 사용하지 않는 메서드는 static을 붙여서 static메서드로 선언하는것을 고려해야한다. 이렇게 하면 인스턴스를 생성하지 않고도 호출이 가능해서 더 편리하고 속도도 더 빠르다.
final 은 '마지막의' 또는 '변경될 수 없는' 의 의미를 가지고 있으며 거의 모든 대상에 사용될 수 있다.
클래스 앞에 쓰이면 다른 클래스의 조상이 될 수 없음을 뜻하고
메서드 앞에 쓰이면 오버라이딩이 불가능해진다.
변수 앞에 쓰이면 해당 변수는 상수가 된다.
abstract
는 '미완성'의 의미를 가지고 있다.
메서드의 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상 메서드를 선언하는데 사용된다.
이는 뒤에가서 좀더 자세히 배울 것이다.
접근제어자
접근 제어자는 멤버 또는 클래스에 사용되어 해당 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 한다.
접근제어자에는 4가지 종류가 있는데 앞서 말했듯이 private와 public이 제일 많이 사용된다. 또한 아무것도 쓰지 않으면 자동으로 default로 설정이 된다.
private - 같은 클래스 내에서만 접근이 가능하다.
default - 같은 패키지 내에서만 접근이 가능하다.
protected - 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.
public - 접근 제한이 전혀 없다.
접근 제어자는 외부로부터 데이터를 보호하고자 사용된다. 혹은 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해 사용된다.
접근제어자로 인해 보호받는 변수를 사용하려면 그 변수가 있는 클래스에 변수를 읽는 메서드를 포함시키면 된다.
보통 멤버변수의 값을 읽는 메서드를 get멤버변수이름 이라 하고 값을 변경하는 메서드는 set멤버변수이름, 반환 타입이 boolean이면 is멤버변수이름 으로 짓는다.
이는 반드시 그리해야하는 것은 아니지만 암묵적인 규칙이므로 특별한 이유가 없다면 따르도록 하자.
접근제어자는 생성자에 사용됨으로써 인스턴스의 생성을 제한할 수 있다.
생성자의 접근제어자를 private로 지정하면 외부에서 생성자에 접근할수가 없으므로 인스턴스를 생성할 수 없게 된다.
하지만 클래스 내부에서는 인스턴스를 생성할수 있다.
즉 인스턴스를 생성해서 반환해주는 public메서드를 제공함으로써 외부에서 이 클래스의 인스턴스를 사용 가능하게 하는 것이다.
다형성
다형성이란, 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 하는 것이다.
이를 좀더 구체적으로 말하면, 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 한 것이다.
위의 예제를 보면, A클래스를 확장한 것이 B클래스임을 알 수 있다.
즉 A클래스는 조상클래스, B클래스가 자손클래스가 된다.
여기서 B b = new B(); 와 A a = new B(); 는 엄연하게 차이가 있다.
둘 다 같은 타입의 인스턴스이지만 참조변수의 타입이 다르기 때문에 사용할 수 있는 멤버의 개수가 달라진다.
즉 조상타입의 참조변수를 쓰는 a의 경우, B클래스에서만 명시된 멤버들을 사용할 수가 없다.
이 경우 형변환에서도 똑같이 발생하는데, 이전에 기본자료형의 형변환에서 배웠듯이
범위가 작은 것에서 큰 것으로 형변환을 하는데에는 아무런 문제가 없다는 것을 우리는 알고 있다.
형변환은 참조변수의 타입을 반환하는 것이지 인스턴스를 변환하는 것은 아니다. 단지 형변환을 통해서 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 개수를 조절하는 것 뿐이다.
오늘의 과제는 학생예제에서 삭제기능을 구현하는 것이다. 또 스캐너를 자주 사용하니 이를 메서드로 만들어 보라는 것이 과제다.
오늘은 여기까지!!
다형성이 7장의 수문장이라고 한다. 물론 뒤의 인터페이스란 것도 있지만...
너무나 어려운 내용이지만 이걸 설명하시는 선생님에 다시한번 놀라고 더더욱 단 한마디도 놓치지 않아야겠다.