<상속(inheritance)>
ㅇ class Child extends Parent {
// ................
}
ㅇ 자손은 조상(부모의 부모)의 모든 멤버를 상속받는다(무조건!!! 다받음)
- 생성자, 초기화 블럭 은 제외
- 자손의 맴버 개수는 조상보다 적을수 없다(같거나 많다.)
<포함(composite)>
ㅇ 클래스의 맴버로 참조변수를 선언하는것
class Circle {
Point c = new Point( );
int r;
}
ㅇ 클래스 간의 관계 결정하기--> 어느문장이 자연스러운지에 따라 구현하면 된다/절대적아님
- 상속관계 : [ ~은 ~이다.(is-a) ] 10% => 상속은 여러가지 제약이 있기때문에 꼭필요할때만
- 포함관계 : [ ~은 ~을 가지고 있다.(has-a) ] 90% => 잘모르겠다면 포함으로 !!!!
ㅇ 프로그래밍 = 설계(90%) + 코딩(10%) -> 설계 능력은 그림을 계속 그려 봐야 한다
<단일상속(Single Inheritance)>
ㅇ java는 단일 상속만을 허용한다(c++은 다중상속 허용)
- 다중상속시 이름이 같은 메서드(내용은 완전다름) => 충돌문제 생김 => java이후 언어는 단일상속만 허용
- C++에서 java은 다중상속이 안된다 깜 => java는 인터페이스를 통해 다중상속
- 비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 한다
ㅇ Object클래스 -> 모든 클래스의 조상
- 부모가 없는 클래스는 자동적으로 Object클래스를 상속받게 된다
- toString( ), equals(Object obj), hashCode() 등 11개의 메서드를 가진다
<오버라이딩(overrinding)> -> 어퍼친것
ㅇ 상속받은 조상의 메서드를 자신에 맞게 변경하는것
- 선언부는 못 바꾸고 내용만(구현부)만 바꿈
ㅇ 오버라이딩의 3조건 (무조건 외우자 !!!)
1. 선언부가 (반환타입,메서드이름,매개변수목록) 조상 클래스의 메서드와 일치해야 한다.
2. 접근제어자를(public protecctected private) 조상 클래스의 메서드 보다 좁은범위로 변경불가
3. 예외는(8장내용) 조상클래의 메서드보다 많이 선언할수 없다 (작거나 같아야 한다)
ㅇ 오버로딩 vs 오버라이딩
- 오버로딩(overloading) : 상속관계없음, 기존에 없는 새로운 메서드를 정의 하는것(new)
- 오버라이딩(overriding) : 상속받은 메서드의 내용을 변경하는것(change, modify)
<참조변수 super>
ㅇ 객체 자신을 가리키는 참조변수, 인스턴스 메서드(생성자)내에만 존재
ㅇ 조상의 멤버를 자신의 멤버와 구별할때 사용
- this -> lv 와 iv 구별에 사용
- super -> 조상멤버와 자신멤버 구별
<생성자 super()>
(참조변수 super와 전혀 관계 없음)
ㅇ 조상의 생성자
- 조상의 생성자를 호출할때 사용 (생성자, 초기화블럭은 상속이 안됨)
- 조상의 멤버는 조상의 생성자를 호출해서 초기화
ㅇ 생성자의 첫 줄에 반드시 생성자를 호출해야한다 그렇지 않으면 컴파일러가 생성자릐 첫 출에 super();를 삽입
<패키지(package)>
ㅇ서로 관련된 클래스 묶음
ㅇ 클래스는 클래스파일(*.class)이고, 패키지는 폴더 . 하위패키지는 하위폴더
ㅇ 클래스의 실제이름(full name)은 패키지를 포함 (ex) java.lang.String)
ㅇ rt.jar(런타임/실행중/실행할때 의미)는 클래스들을 합축한 파일(JDK설치경로\rje\lib에 위치)
- jar -> 클래스파일 묶어 압축해놓은것(jar.exe 로 압축해제)
- java9부터 rt.jar없어지고 rt.jar파일이 넘커서 module개념으로 찢어놓음 (rt.jar 없어짐)
<패키지의 선언>
ㅇ 패키지는 소스파일의 첫 번째 문장으로 단 한번 선언
ㅇ 같은소스 파일의 클래스들은 모두 같은 패키지에 속하게 된다
ㅇ 패키지 선언이 없으면 이름없은(unnamed)패키지에 속하게 된다
--> 책내용 (비슷한것 가툐) <--
- 하나의 소스파일에는 첫 번째 문장으로 단 한 번의 패키지 선언만을 허용한다.
- 모든 클래스는 반드시 하나의 패키지에 속해야 한다
- 패키지는 점(.)을 구분자로 하여 계층구조로 구성할수 있다
- 패키지는 물리적으로 클래스 파일(.class)을 포함하는 하나의 디렉토리이다
<import문>
ㅇ 클래스를 사용할때 패키지이름을 생략할수 있다
ㅇ 컴파일러에게 클래스가 속한 패키지를 알려준다
ㅇ java.lang패키지의 클래스는 import하지 않고도 사용할수 있다
- String, Object, System, Thread 등등
ㅇ import문은 패키지문과 클래스선언의 사이에 선언한다
<static import문>
ㅇ static멤버를 사용할때 클래스 이름을 생략할수 있게 해준다
- 클래스 이름을 넣으면 코드가 길어져서 사용한다
import static java.Math.random;
Math.random( ) => random( ) 가능
<제어자(modifier)>
ㅇ 형용사역할로 명사의 부가적인 의미를 부여하듯이
클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미 부여
- 하나의 대상에 여러 제어자를 같이 사용가능(접근제어자는 하나만)
ex) public static final int WIDTH = 200
<static>
ㅇ 클래스의, 공통적인 의미를 가지고 있다
제어자 | 대상 | 의미 |
static | 멤버변수 | - 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 된다. - 클래스 변수는 인스턴스를 생성하기 않고도 사용가능하다 - 클래스가 메모리에 로드될때 생성된다 |
메서드 | - 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다 - static메서드 내에서는 인스턴스멤버들을 직접 사용할수 없다 |
<final>
ㅇ 마지막의, 변경될수 없는 의미를 가지고있다
- 모든것에 붙일수 있다
제어자 | 대상 | 의미 |
final | 클래스 | 변경될수 없는 클래스, 확장될수 없는 클래스가 된다(자손이 없다) 그래서 final로 지정된 클래스는 다른 클래스의 조상이 될수 없다 ex) String, Math -> 글자의 계정은 고치면 안되닌간 |
메서드 | 변경될수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될수 없다 (오버 라이딩 안됨) | |
멤버변수 | 변수 앞에 final이 붙으면, 값을 변경할수 없는 상수가 된다 | |
지역변수 |
<abstract>
ㅇ 추상의, 미완성의 의미를 가진다
- 추상클래스의 인스턴스 생성불가 (미완성 설계도)
- 추상클래스를 상속받아서 완전한 클래스(완전한 설계도/구상클래스)를 만든후에 객체생성가능
제어자 | 대상 | 의미 |
abstract | 클래스 | 클래스 내에 추상 메서드가 선언되어 있음을 의미한 |
메서드 | 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다 |
<접근제어자(access modifier)>
ㅇ public > protected > (default) > private
- private : 같은 클래스 내에서만 접근이 가능하 다
- (default) : 같은 패키지 내에서만 접근이 가능하다
- protected : 같은 패키지내에서, 그리고 다른 패키지의 자손 클래스에서 접근이 가능하다
ㅇ 클래스 앞에는 public 이나 default 만 가능하다
ㅇ 멤버들에는 4개가 다 가능하다
- public : 접근제한이 전혀 없다
※[참고] 하나의 소스파일(*.java)에는 public클래스가 단 하나만 존재할수 있으며,소스파일의 이름은 반드시
public 클래스의 이름과 같아야 한다
<캡슐화와 접근 제어자>
- 외부로부터 데이터를 보호하기 위해서
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해 사용
ㅇ 켑슐화 :
접근제어자를 pivate로 하여 멤버변수에 외부에서 직접접근하지 못하도록 하고 메서드를 public로 하여 간접접근 허용
- 접근 제어자의 범위를 최대한 좁혀야 디버깅시 점검 범위를 적게 할수있다
- 클래스 안에서만 쓰는 메서드는 private로 설정하여 디버그시 다른 클래스에서 사용하는지 살펴볼 필요가 없다
<다형성(polymorphism)>
- java를 공하는 학생은 다형성을 이해하는 학생과 못하는 학생 둘로 구분된다
- 다형성을 이해못하면 추상클래스와 인터페이스를 이해 할수 없다
- 많을다! 형태형 ! => 하나가 여러가지 형태를 취함
- 다형성이 머냐고? 물어보면 => 조상타입 참조변수로 자손타입 객체를 다루는것 입니다
- 장점이 2가지다
- 프로그램이 유연해진다
- 보통은 참조변수 타입과 인스턴스의 타입이 일치한다
- 참조변수가 조상타입 일때와 자손타입 일때의 차이는 참조변수로 사용할수 있는 멤버의 갯수가 달라집니다
- Tv타입의 참조변수로는 CaptionTv인스턴스 중에서 Tv클래스의 맴버들(상속받은 맴버포함)만 사용할수 있다
class Car {
}
class Tank entends Car {
}
Car tt = new Tank( )
tt.drive => 탱크를 몰고 출퇴근 용도로만 쓸수 밖에 없다
<참조변수의 형변환> ch7-24,25 (많이 헷갈림 ㅠㅠ 외워버릴 고얌)
- 3.6 ---->(int)--> 3 : 기본형의 형변환은 값이 바뀐다
- 참조변수 형변환은 사용할수 있는 멤버의 갯수를 조절하는것 뿐이다 (주소값, 객체 이런것들은 변함이 없다)
- 조상 자손 관계의 참조변수는 서로 형병환 가능
FireEngine f = new FireEngine()
Car c = (Car)f; => 조상인 Car타입으로 형변환 (생략가능) , = 대입연산자는 두개 타입이 같아야 한다
-> 메버갯수가 줄어둠(안전/형변환 생략가능/자동생성)
FireEngine f2 = (FireEngine) c; => 자손인 FireEngine타입으로 형변환(생략불가)
-> 맴버겟수가 늘어남(안전하지않음/형변환생략불가)
<instanceof 연산자>
ㅇ 참조변수의 형변환 가능여부 확인에 사용 가능하면 true변환
- 형변환 해도 되는지 확인 후 형변환
1. 참조변수의 형변환은 왜 하나요?
=> 참조변수(리모콘)을 변경함으로써 사용할수 있는 멤버의 갯수를 조절하가 위해서(객체 그대로 !!!)
2. instanceof연산자는 언제 사용하나요?
=> 참조변수를 형변환하기 전에 형변환 가능여부를 확인할때
ㅇ c 리모콘(참조변수)로는 c.water( ) 가 안되고 f2 리모콘(참조변수)로는 f2.water() 가 된다
- 형변환은 멤버의 갯수를 조절하는것 뿐이다
- 참조변수 f의 실제 객체가 중요하다
Car c = new Car( );
FireEngine f = (FireEngine) c ; //형변환에러 java.lang.ClassCastException
f.water() // 컴파일 에러
ㅇ 형변환 되냐? 안되냐가 중요한게아니라 실제 참조변수 c 가 가리키는 실제인스턴스가 무엇인지가 중요하다
[책내용] 364 page
ㅇ 맴버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우, 조상타입의 참조변수를 사용했을 때는 조상
클래스에 선언된 멤버변수가 사용되고, 자손타입의 참조변수를 사용했을 때는 자손클래스에 선언된 멤버변수가
사용된다 하지만 중복 정의 되지않은 경우, 조상타입의 참조변수를 사용했을 때와 자손타입의 참조변수를
사용했을때의 차이는 없다
(중복된 경우는 참조변수의 타입에 따라 달라지지만, 중복되지 않은 경우 하나뿐이므로 선택의 여지가 없기 때문이다)
- 메서드의 경우 조상 클래스의 메서드를 자손의 클래스에서 오버라이딩한 경우에도 참조변수의 타입에 관계없이
항상 실제 인스턴스의 메서드(오버라이딩된 메서드)가 호출되지만 멤버변수의 경우 참조변수의 타입에 따라 달라진다
<매개변수의 다형성> ch7 -27
ㅇ 참조형 매개변수 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄수 있다
다형성의 장점 1. 다형적 매개변수
2. 하나의 배열로 여러종류 객체 다루기
다형성의 배운것 3가지
1. Tv t = new SamrtTv( ); 조상타입 참조변수로 자손타입 객체를 다루는것
2. 참조변수의 형변환 - 리모콘 바꾸기, 사용가능한 멤버겟수 조절
3. instanceof 연산자 - 형변환 가능여부 확인
<여러종류의 객체를 배열로 다루기>
ㅇ 조상타입의 배열에 자손들의 객체를 담을수 있다
<추상클래스(abtract class)>
ㅇ 미완성 설계도, 미완성 메서드(구현부가(몸통 { }없는 메서드)를 갖고 있는 클래스
ㅇ 상속을 통해 추상메서드를 환성해야 인스턴스 생성 가능
- 꼭 필요하지만 자손마다 다르게 구현될것으로 예상되는 경우
ㅇ [책내용 376page]
- 메서드는 선언부와 구현부(몸통)로 구성되어있다
실제 작업내용인 구현부가 없는 메서드가 무슨 의미가 있을까 싶기도 하겠지만, 메서드를 작성할때
실제 작업내용인 구현부보다 더 중요한 부분이 선언부이다.
메서드의 이름과 메서드의 작업에 필요한 매개변수, 그리고 작업의 결과로 어떤 타입의 값을 반환할것인가를
결정하는것은 쉽지 않은일이다. 선언부만 작성해서 메서드의 절반 이상이 완성된것이라 해도 과언이 아니다
- 메서드를 사용하는 쪽에서는 메서드가 실제로 어떻게 구현되어있는지 몰라도 메서드의 이름과 매개변수, 리턴타입,
즉 선언부만 알고 있으면 되므로 내용이 없을 지라도 주상메서드를 사용하는 코드를 작성하는것이 가능하며,
실제로는 자손 클래스에 구현된 완성된 메서드가 호출되도록 할수 있다
ㅇ 추상 사전적 정의
- 낱낱의 구체적 표상이나 개념에서 공통된 성질을 뽑아 이를 일반적인 개념으로 파악하는 정신 작용
- 상속이 자손클래스를 만드는데 조상 클래스를 사용하는것이라면,
이와 반대로 추상화는 기존의 클래스의 공통부분을 뽑아내서 조상 클래스를 만드는것이라 할수 있다
- 추상화 : 클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업
- 구체화 : 상속을 통해 클래스를 구현, 확장하는 작업
Unit[ ] group = new Unit[3]
group[0] = new Marine( );
group[1] = new Tank( );
group[2] = new Dropship( );
for (int i =0; i < group.length ; i++)
group[i].move(100,200);
1. 다형성의 장점 => 조상타입의 배열에 자손들의 객체를 담을숫 있다
2. 추상클래스의 장점 => Unit의 move함수를 추상메서드로 해서 리모콘을(참조변수)먼저 만들어놓고
Unit을 상속받은 각각 유니트는 선언부는 같고 몸통은 다른 메서드를 구현한다
※ 추장메서드라도 만들어서 원하는 리모콘을 만든다 !!!!
- 추상화 <--> 구체화(명확)
ㅇ 추상화된 코드는 구체화된 코드보다 유연하다. 변경에 유리
GregorianCalendar cal = new GregorianCalendar( ); // 구체적 명확 분명
Calendar(추상클래스) cal = Calendar.getInstance( )(켈린더 자손객체를 반환(다형성)) ; // 추상적 (애매하게 써놓은다...) 멀 반환할지 불분명
지금은 절대 이해할수없으나 진도를 뺀다 실제 코드서 추상회된것을 보고, 반복학습을 하다보면 이해할수 있다
<인터페이스(interface)>
- 추상메서드의 집합 (프로그래밍의 관점 일반적인 관점은 다음 강의에서 설명한다)
- static메서드는 디폴트메서드, 상수 이런개념은 본질을 흐트려 뜨린다 넘겨 !!!!!
- 구현된것이 전혀 없는 설계도 껍데기(모든멤버가 public)
- 추상클래스와 인터페이스의 차임점 =>
일반클래스인데 추상메서드를 가지고 있는것이고 인터페이스는 구현된것이 아무것도 없다( all 추상메서드)
interface 인터페이스 이름 {
public static final 타입 상수이름 = 값; // 상수 (변수 iv, cv 절대 못씀)
public abstract 메서드이름(매개변수목록); // 추상메서드
}
- 인터페이스의 조상은 인터페이스만 가능(Object가 최고 조상 아님)
- 다중상속이 가능(추상메서드 충돌해도 문제없음, 선언부만 있어서 메서드충돌이 무의미 )
<인터페이스의 구현>
- 인터페이스의 정의된 추상메서드(미완성 설계도)를 완성하는것
class 클래스 이름 implements 인터페이스이름 {
// 인터페이스에 정의된 추상메서들ㄹ 모두 구현해야 한다 (추상메서드 작성)
}
implements = 구현하다
class Fighter implements Fightable {
public void move(int x, int y) { }
public void attack(Unit u) { }
}
ㅇ Fighter클래스는 Fightable인터페이스를 구현했다// 몸통완성
ㅇ 일불만 구현하는 경우, 클래스 앞에 abstract를 붙여야 함.
1. 인터페이스란?
=> 추상 메서드의 집합 (외우자 !!!) 상수, static메서드, 디폴트메서드는 jdk1.8부터 추가(핵심 아님 !!!!)
2. 인터페이스 구현이란?
=> 인터페이스의 추상메서드 몸통 { }만들기 (미완성 설계도 완성하기)
ㅇ 추상 클래스 구현
class AudioPlayer extends Player{
void play(int pos) { ........... }
void stop( ) { ............. }
}
ㅇ 인터페이스 구현
class Fighter implements Fightable {
public void move(int x, int y) { ............ }
public void attack(Unit u) { .............. }
}
3. 추상클래스와 인터페이스의 공통점은?
=> 추상메서들르 가지고 있다(미완성 설계도)
4. 추상클래스와 인터페이스의 차이점은?
=> 인터페이스는 iv를 가질수 없다
<인터페이스를 이용한 다형성>
ㅇ 인터페이스는 C++에는 없는 개념으로 다중상속 효과를 낸단
- 인터페이스도 다형성이 된다
- 인터페이스 로 자손객체 가리킬때 인터페이스에있는 리모콘만 기능만 가능 ch7-38
- 인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능 ( 외울정도로 반복하자 !!!!! )
- 인터페이스를 메서드의 리턴다입으로 지정할수 있다 (기본형과 똑 같다 !!!)
[책내용 388page]
리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환하는것을 의미한다
(이문장을 외울때까지 반복해야 한다)
[동영상 내용]
==> 괜히 중요하지 않은것을 어렵게 설명한것 같다 ( 탑입만 맞춰주자 !! , 반환타입이 인터페이스가 무슨의미인가? 왜우자!)
<인터페이스의 장점> ch7-39
ㅇ 인터페이스란 두 대상(객체)간의 '연결, 대화, 소통'을 돕는 '중간 역할'을 한다
ex) 컴퓨터 win10의 역할 -> 마더보드 바꿔도 인터페이스OS가 안바뀌면 똑같은 사용법
- interface = inter(~사이) + face(얼굴, 대상)
ㅇ 선언(설계)와 구현을 분리시킬수 있게 한다 (선언부만 떼어내기)
class B {
public void method( ) {
System.out.println("methodInB");
}
}
====> 선언부만 떼어내서 분리시킨다 !!!
interface I {
public void method( );
}
class B Implements I {
public void method( ) {
System.out.println("methodInB");
}
}
ㅇ 개발 시간을 줄일수 있다
class A가 class B의 인터페이스를 이용함으로써 class B가 완성될때까지 기다릴 필요없다
ㅇ 표준화가 가능하다 ex) JDBC(인터페이스 집함)
- java가 JDBC 인터페이스를 주면서 각DB회사에 줘서 표준화 시킨다
ㅇ 서로 관계없는 클래스들을 관계를 맺어줄수 있다 ch7-39
- 인터페이스를 구현함으로써 클래스들을 묶을수 있다
java는 객체지향개념이 제일 중요하다 진도는 계속해서 빼고 객체지향 개념을 반복 학습을 하자
<디폴트 메서드 와 static메서드>
ㅇ 인터페이스에 디폴트 메서드, static메서드 추가 시킴(JDK1.8부터)
- 인터페이스는 추상메서드만 있었으나 그동안 문제점이 있어서 , 요구사항이 있어서, 변화를 위해서 만듬
ㅇ 디폴트 메서드가 기존의 메서드와 충돌할때의 해결책
1. 여러 인터페이스와 디폴트 메서드간 충돌
- 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩 해야 한단
2. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
- 조상클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다
충돌시 무조건 그냥 직접 오버라이딩 하면 해결된다
※ 하루에 6장 30분 7장30 무조건 복습을 하고 진도를 빼자 !!!!!!
<내부 클래스(inner class)>
ㅇ 내부 클래스의 장점
- 내부클래스에서 외부 클래스의 멤버들을 쉽게 접근 할수 있다 (객체 생성없이 접근한다)
- 코드의 복잡성을 줄일수 있다 (켑슐화) // class A만 쓰는 class B 를 노출시키지 않고 내부클래스로
ㅇ 내부클래스 공부로 스트레스 받지 말자 !!! 나중에 필요할때 보면 된다 !!!
<익명클래스(anonymous class)>
ㅇ 이름이 없는 일회용 클래스. 정의와 생성을 동시에
new 조상클래스이름( ) {
// 맴버 선언
}
new 구현인터페이스( ) {
// 맴버 선언
}