상속
1. 확장성, 재사용성
2. 클래스 선언시 extends 키워드를 명시
3. 관계
- 부모 (상위, super) 클래스
- 자식 (하위, sub) 클래스
4. 자식클래스는 부모클래스에 선언되어있는 멤버변수, 메소드를 자신의 것처럼 사용할 수 있다. 단, 접근제한자에 따라 사용 여부가 달라진다.
5. super 키워드
6. 오버라이딩(재정의)
class Parents {
Parents() { }
}
class Child extends Parent {
Child() {
super();
}
}
Child c = new Child(); 객체를 생성하게되면 child 뿐만아니라 Parent 공간도 만들어진다.
Child 디폴트 생성자에 super(); 라는 부모클래스 디폴트 생성자가 생략되있기 때문.
주의> 자바에서는 다중상속을 지원하지 않는다. 상속의 상속 식만 가능.
클래스 다이어그램
첫번째 박스 : 멤버변수와 접근제한자 그리고 자료형
public +
protected #
default ~
private -
Employee
<1>
no : int
name : String
grade : String
salary : int
<2>
Employee()
Employee(no:int, name:String…
getNo() : int
setNo(no:int) : void
이클립스에서 cmd + n -> amaterousUML -> class diagram 에서 클래스다이어그램을 만들 수 있다.
amaterousUML 은 멤버변수를 디폴트로 private
추상클래스
숙제 피트백
각자 도형을 클래스로 추상화시킬수있지않겠냐?
다들 메소드별로 분리시켰는데, 이는 객체지향보단 절차지향이다. 그래서 항상 눈에 보이는 사물들을 객체라 취급하고 그 객체와 커뮤니케이션을 해야하는 것이다.
UML 클래스다이어그램
클래스간의 관계를 명확히 보여준다.
클래스 만들고 변수나 메소드 오른쪽클릭 -> open property view 에서 접근제한자 등등 기본적인것들을 변경할 수 있다.
생성자는 메소드처럼 add operation으로 추가할 수 있지만, 수정은 바로 안되고 open property view에서만 가능하다. 생성자의 매개변수는 arguments에서 add를 통해 가능하다.
우클릭 -> java 에서 클래스다이어그램을 고대로 클래스 소스로 만들 수 있다.
추상클래스
- 그냥 덜만들어진거다.
- 추상클래스를 쓰는 가장 큰 목적은 “강제성 부여”이다.
1. 추상클래스 : 하나 이상의 추상메소드를 가지고있는 클래스
2. 추상메소드 : 내용부가 없는 메소드. 인스턴스 객체를 만들 수 없다. 인스턴스 객체를 만들기위해선 추상클래스를 상속받는 자식클래스가 오버라이딩(재정의)해야한다.
- 선언부에 abstract
- 메소드의 선언부만 있고 바디가 없음.
public
protected static
default abstract void aaa() {}
private
3. 추상메소드를 포함하는 클래스는 반드시 추상클래스로 선언되어야 함
class Test {
abstract void print();
}
-> 불가능
abstract class Test {
abstract void print();
}
-> 올바른 예
4. 추상클래스는 인스턴스 생성이 불가능함 (new 키워드 사용불가능) - heap영역 메모리 할당 불가능
=> 그럼 도대체 추상클래스는 왜있는가?? - 상속관계때문에. 부모가 갖고있던 추상메소드를 자식클래스가 상속받는다. 근데 나는 그 클래스로 인스턴스를 만들고 싶다. 하지만 바디부분이 비어있으니 내가 만들어야 한다. 그래서 구현이 안된 부모의 추상메소드를 자식이 상속받아서 내용부를 내가 만들고싶은것이다. => “메소드 오버라이딩”
메소드 오버라이딩은 상속관계에서만 성립한다. (!= 메소드 오버로드)
ex) 티비 제조사별로 리모콘이 호환이 안된다. 삼성은 turn on이 명령어인데 LG는 다른 명령일것이다. 하지만 적어도 이 tv에서 다른버튼은 안먹혀도 전원과 볼륨버튼은 먹히게 하고싶다. 그러면 전원과 볼륨에 관한 메소드는 동일한 이름을 쓰고싶지 않냐? power on, power off, volumn up, volumn down이라는 명령어를 쓰라고 내가 강제하고 싶단말이다. 이 네 추상메소드를 담은 추상클래스를 담고, 그 자식인 삼성과 LG는 자기들 입맛에 맞게 내용을 바꿀 수 있다. 이렇게, 추상메소드의 필요성을 먼저 생각해야 추상메소드가 필요한거다. 이게 프로그램 유지보수에 결정적 역할을 한다. 변화에 민감하지 않게 만들어준다.
5. 추상클래스는 일반(구현된) 메소드와 추상 메소드 모두 선언이 가능함.
cf) 추상클래스와 인터페이스의 차이
: 추상클래스는 추상메소드만 가질수도 있고, 일반메소드와 추상메소드를 같이 가질수도 있다.
하지만 인터페이스는 오직 추상메소드만 가져야한다.
6. 추상클래스를 상속받는 하위클래스는 상위클래스의 추상메소드를 반드시 오버라이딩(재정의) 해야한다.
7. 추상클래스의 객체변수는 하위클래스를 이용함. (묵시적 형변환)
객체의 형변환
형변환은 기본적으로, A = B 의 대입연산자를 기준으로 왼쪽과 오른쪽의 참조 자료형이 서로 다른 경우에 형변환이 발생된다. 단, 이때 A와 B의 전제조건은 서로 상속관계에 있어야 한다는 것이다.
ex)
public class Printer {}
public class LGPrinter {}
Printer p = new LGPrinter(); //(오류)
public class Printer {}
public class LGPrinter extends Printer {}
Printer p = new LGPrinter(); //=> 형변환 발생
묵시적 형변환
Super = Sub 일때.
상위(부모) 클래스 타입 = 하위(자식) 클래스 타입
Printer p = new LGPrinter();
=> LGPrinter에 인스턴스값을 받아놓고 그 주소값을 Printer에 갖다놓게되고, p는 LGPrinter에 있는 Printer의 멤버변수와 메소드에만 접근할 수 있다. 하지만 이 때, Print의 메소드여도 LGPrinter에서 오버라이딩된 메소드가 있다면 LGPrinter의 메소드를 실행하게 된다. 이를 “다형성”이라 한다. 하지만 멤버변수의 경우엔 Printer, 즉 부모의 멤버변수만 접근가능하다.
=> power()은 부모의 멤버변수니 접근 가능. name은 자식의 멤버변수니 접근 불가능. print()는 자식의 메소드니 접근 불가능. powerOn()은 부모 메소드라 접근가능하나, 추상클래스로서 자식에서 오버라이드된 메소드에 접근한다.
명시적 형변환 (= 강제적 형변환)
Sub = (sub) Super
하위클래스 타입 = (sub) 상위 클래스 타입
=> 반드시 하위클래스를 명시해야 한다.
하지만 이는 컴파일상으로는 에러가 나지 않지만 실행시에는 실제 하위클래스에 대한 메모리공간이 잡혀있지 않기 때문에 에러가 난다. 그래서 전제조건이 있다. 우변항에 부모의 인스턴스 객체가 들어오면 안되고, 부모형의 참조변수가 들어온다. 명시적 형변환이 가능한 경우는 묵시적 형변환이 이미 되어있어야 한다. 그래야 자식클래스의 값까지 가지고있는 부모클래스의 참조변수가 명시적 형변환의 우변항에 오면서 자식클래스의 공간까지 가지고 있기 때문에.
실습 코드 및 과제
https://github.com/LeenaKim/Java_Lessons/tree/master/src/kr/ac/kopo/day07
'Programming > Java' 카테고리의 다른 글
[ JAVA 수업 DAY 10 - 11 ] Final, 인터페이스+, 예외처리, Java API (0) | 2020.05.05 |
---|---|
[ JAVA 수업 DAY 09 ] 객체형변환+, 인터페이스 (0) | 2020.05.05 |
[ JAVA 수업 DAY 06 ] 문자열 (0) | 2020.05.05 |
[ JAVA 수업 DAY 05 ] 클래스와 메소드 (0) | 2020.05.05 |
[ JAVA 수업 Day 04 ] 배열 (0) | 2020.05.04 |