※ 개인적인 개발 수업 정리글입니다. 꾸준히 정리할 예정이고 틀린 부분이 있다면 언제든지 댓글 환영입니다.
책156쪽
상속
■ super 키워드
-"부모클래스"의 인스턴스 의미
-this : 메모리에 올라간 "자신클래스"의 인스턴스 의미
① 변수 이름이 동일할 때,
② 자식클래스에서 부모클래스의 생성자 호출할 때,
==>반드시 상위클래스의 멤버 및 생성자를 명시적으로 호출 ex)기본생성자
■ 오버라이딩
어제 이렇게까지 한거 책 보고 둘러봄
책169쪽
■ 다형성
-부모타입으로 자식객체 만들 수 있다!
①상속관계가 있어야하고
②부모타입의 변수로, 자식의 객체 생성참조 할 수 있음
기존) Manager m = new Manager (); Engineer e= new Enginner();
다형성) Employee m = new Manager(); // 다형성 객체
Employee e = new Engineer(); // 다형성 객체
//m,e의 타입은 Employee타입이므로, m,e으로 사용가능한 변수, 함수-name,age
왜? [Employee 변수: name,age | Manager변수: name,age,depart ]라면 Employee타입이므로, 부모변수에만 접근가능
//자식객체의 유일한 변수와 함수까지 사용하려면(depart까지), 자식 타입으로 형 변환 하고 사용해함.
책171쪽 예제해보기
변수 emp 가 Employee타입으로 선언됐지만,
그 아래 변수emp가, 새로 만든("홍길동",2000)[Employee생성자로 가져올건데 암튼]
그 객체의 타입은 Manager타입임
그래서 그 아래에
1) Manager 타입의 새로운 m을 선언하고,
2) 기존의Employee타입의emp을 가져오고
3) 앞에 (Manager) 명시적으로 적어서 형변환 시켜줌
■ instanceof
-메서드의 파라미터를 사용해서, 부모클래스가 자식클래스와 함께 사용되려면,
1) 부모자식클래스마다 각각 고유메서드를 추가
==>단점: 코드 중복 및 유지보수가 어려워짐.
2) 부모 클래스에만 메서드를 추가하고, 자식클래스에서 메서드를 오버라이딩해서 사용.
==>단점: 오버라이딩은 강제성이 없기 때문에 자식클래스에서 부모클래스의 메서드를 재정의하지 않아도 전혀 무관
3) 부모 클래스에서 모든 자식 클래스의 세밀한 구현까지 작성하고, 자식클래스들은 그냥 상속 받아서 사용.
이것이 다형성이며 대부분의 API는 다형성을 이용해서 구현되어 있다.
다형성을 이용한 메서드 사용 시, instanceof 연산자를 활용하여 실제로 메서드의 파라미터로 넘어온 클래스타입을 구분가능
if ( 변수 instanceof 클래스타입1 ) { ~~
} else if ( 변수 instanceof 클래스타입1 ) { ~~
} else if ( 변수 instanceof 클래스타입2 ) { ~~
< instanceof 비교할 때 주의할거 >
맨 위에 작은 타입의 자식클래스명 타입을 먼저 쓰고,
↓↓↓↓↓↓↓↓↓↓
맨 아래에 큰 타입의 부모클래스명 타입을 쓰기
*부모클래스명 타입으로 먼저 쓰면 전부 맨 위부터 부모클래스로 걸려버림
책173쪽 예제해보기
프로젝트 08Day2의 패키지 com.test5의 클래스Ex06_8
┌조금다름. Employee도 자식클래스로 해버리고 제일 부모클래스가 Test클래스임.
책175쪽 예제
08Day2 프로젝트의 Cat, Dog, Fish, Pet
Object 클래스
■ equals 메서드
값 비교 : 연산자==
객체 비교 : 함수 equals
책178쪽 예제6-9
08Day3 프로젝트 -
■ toString 메서드
■ UML 가이드
-클래스 다이어그램 보는 방법
* [워크샵05]는 [07장_인터페이스와 추상클래스] 까지 끝내고 하기로함
7장. 인터페이스,추상클래스,중첩클래스
< 왜 등장했는가? >
-부모 입장에서
"나를 상속받는 자식1, 자식2은,
이 함수를 무조건 강제적으로 오버라이딩(재정의)해야한다." 라고 강제성을 주는거고,
Test 출력할 경우, 자식1에도 자식2에도 각각의 함수가 강제적으로 출력되어서 나옴.
안하면 ? 귀찮게 부모클래스에서 하나하나 수정해주고... 자식클래스에서 하나하나수정해주고...
-상속은 강제성이 없음. 그러다보니까 나중에 재사용성과 유지보수 할때 통일성일관성이 없어서
어려워지는거임.
-그래서 강제성을 주고, 나중에 재사용유지보수할때 통일성일관성있고 편리하게빠르게 관리가능.
∴ 인터페이스와 추상클래스는, 방식은 다르지만 상속보단 강제성을 지니고 있다. 정도!
■ 추상클래스
[ UML표기법 : 이탤릭체]
- 추상클래스 : 블록({})이 없는 메서드를 포함할 수 있는 클래스.
- 추상 메서드 : 블록({})이 없는 메서드. abstract 키워드를 사용
★ 추상클래스 특징 ★
-미완성 클래스
-구성요소 :
public abstract class 클래스명 {
//인스턴스 변수 (멤버변수)
//일반 메서드
//생성자
//추상 메서드 == public abstract 리턴타입 메서드명1 ([파라미터]);
}
-반드시 추상 메서드를 포함할 필요는 없다.
-하지만 추상메소드가 있다면, 객체생성이 불가능함. why...?
==>불완전한 추상 클래스를 사용하기 위해서는 일반 클래스를 이용
-객체 생성은 불가능하지만 선언된 변수의 데이터형으로 사용할 수 있다.
-자식클래스에서 반드시 추상 클래스의 추상 메서드를 재정의 해야 된다.
┌부모클래스 생성할때, abstract 추상클래스로 할거라고 체크하고 생성┐
★★★★★★★★★★★★★★★★★★★★
1. 브레스 { } 가 없는 함수의 형식만 선언
[ 부모클래스 ]
public abstract class 부모클래스명 {
public abstract void 함수a (인자) { } ;
접근제한자 함수 함수이름 (매개변수) { } ;
}
============================>자식클래스에서 이 함수a를 반드시 강제 오버라이딩 해라.
[ 자식 클래스 ]
public class 클래스명 extends 부모클래스명 {
@Override
public void 함수a(인자) {
}
============================>자식클래스가 이 함수a를 오버라이딩 함.
★★★★★★★★★★★★★★★★★★★★
┌부모클라스┐
┌자식클라스┐
2. 브레스 { } 가 있는 함수를 만드려면 하위클래스에 넣어야함
[ 부모클래스 ]
public abstract class 부모클래스명 {
public abstract void 함수a ( ) { } ; //abstract void 함수명( )은 정말로 ( )가 비어서 void만 쓴거임..?
접근제한자 함수 함수이름 ( ) { } ;
}
============================>자식클래스에서 이 함수a를 반드시 강제 오버라이딩 해라.
[ 자식 클래스 ]
public class 클래스명 extends 부모클래스명 {
@Override
public void 함수a( ) {
}
============================>자식클래스가 이 함수a를 오버라이딩 함.
(예제) 09Day 프로젝트 생성 - AbstractClass
(예제) 09Day2 프로젝트 생성 - AbstractClass
(예제) 09Day3 프로젝트 생성 - Pet, Cat, Dog
ㄴ 이거 그냥 따라만 썼다... 다시 복습하면서 이해하기
■ 인터페이스 ≠ 클래스. 같은거 아님!
[ UML표기법 : <<인터페이스이름>> ]
-확장자 = *.java
-구성요소 :
public interface 인터페이스명 {
//public static final로 지정한 상수. //[인터페이스명.변수a]로 사용됨
//public abstract가 지정한 추상메소드 //public, abstract 없어도 묵시적으로 public abstract임
//public default void c ( ) { 내용 } //default 붙이면 내용이 고정된건데 거의 안쓰는듯
}
-객체생성불가(new사용불가) =>구성요소 사용불가여서, 독자적으로 사용 못하고 클래스를 이용해서 사용(상속관계)
-클래스와 상속관계에선 implements 키워드 사용. 다중구현가능 ( 클래스명 implements 인터페이스a, 인터페이스b )
-클래스는 반드시 인터페이스의 추상메소드를 concrete메소드로 구현(오버라이딩)
ㄴ 상속 받는 클래스는 구현을 안할거래도, 무조건 인터페이스의 함수를 오버라이딩해야함
★★★★★★★★★★★★★★★★★★★★
[ 인터페이스 ]
public interface 인터페이스명 { //인터페이스명A로 예시
int NUM = 10 ; //public static final이 자동지정된 상수(상수명은 전부대문자) [인터페이스명.변수a]로 사용
public abstract void 함수b ( ) {내용} ; //public abstract 명시적 기재
public static void 함수a ( ) {내용} ; //abstract 없어도 묵시적으로 abtract임
void 함수c ( ) {내용} ; //public, abstract 없어도 묵시적으로 public abstract임
다만 public void 함수d( ) {내용} ; //이런 일반메소드는 불가라는데?
}
========================>자식클래스에서 이 함수들을 전부 반드시 강제 오버라이딩 해라.
[ 자식 클래스 ]
public class 클래스명 implements 인터페이스명 { //클래스명ConcreteClass으로 예시
@Override
public abstract void 함수b ( ) {내용} ; //abstract void 함수명( )은 정말로 ( )가 비어서 void만 쓴거임..?
@Override
public static void 함수a ( ) {내용} ; //abstract void 함수명( )은 정말로 ( )가 비어서 void만 쓴거임..?
@Override
void 함수c ( ) {내용} ;
}
=======================>자식클래스가 이 함수a를 오버라이딩 함.
[ Test 클래스 ]
public class Test {
public static void main(String[ ] args) {
일단 A a = new A( ) ; //인터페이스를 인터페이스 타입으론 객체생성 불가
A.NUM = 100 ; //static final 묵시적으로 있어서 수정 불가
sysout ( A.NUM ) ; //출력값: 10
ConcreteClass c = new ConcreteClass () ; //클래스로는 객체생성 가능
c.a( ) ; //클래스의 오버라이딩 함수를 가져올 수 있음
A tt = new ConcreteClass( ) ; //다형성으로 인해, 작은타입의 ConcreteClass로 큰타입의 A으로 객체생성 가능.
}
===========================
★★★★★★★★★★★★★★★★★★★★
< interface 주의할거 > *instanceof
맨 위에 큰 타입의 <<인터페이스명 타입>>을 쓰기
↑↑↑↑↑↑↑↑↑↑↑↑
맨 아래에 작은 타입의 자식클래스명 타입을 쓰기
*instanceof가 부모클래스명 타입으로 먼저 쓰면 전부 맨 위부터 부모클래스로 걸려버린걸,
반대로 이용하는거임. 가장 큰 타입의 인터페이스를 써버려서 빨리 true로 잡혀버리기!!
(예제) 09Day5 프로젝트 생성 - 인터페이스 A, B, C 생성 / 클래스 ConcreteClass 생성
ㄴ(인터페이스끼리) 인터페이스 C가 인터페이스 A,B를 상속받는다.
ㄴ(클래스<-인터페이스 여러개) 클래스 ConcreteClass가 인터페이스 A,B를 상속받는다.
ㄴ 클래스 ConcreteClass가 클래스 ConcreteClass를 상속받고 인터페이스 C를 상속받는다.
ㄴ 클래스 ConcreteClass가 인터페이스 C를 상속받는다.
■ 중첩클래스
-거의 안 쓰이기 때문에 졸ㄹ라 대충하고 지나갈거임.
-4가지 패턴 있는데 그중 1,2가지만 볼거임.
<다른 블로그에서 끌어온 글>
1. abstract class(추상 클래스)와 interface 공통점
선언만 있고 구현 내용이 없다.
그래서 자기 자신이 new를 해서 객체를 생성할 수 없으며,
[추상클래스를 extends 받거나, interface를 implements 한] 자식만이 객체를 생성할 수 있다.
상속받은 자식이 구현을 반드시 하도록 해야할 때 사용한다.
JAVA에서는 type이 지정되있기 때문에 선언된 type과 자식의 type이 같아야만 한다.
2. abstract class(추상 클래스)와 interface 차이점
추상클래스는 말그대로 클래스이고, interface는 구현하기 전에 메소드에 대해 명세된 것이랄까?
그래서 상속을 받음에도 불구하고 클래스에선 상속이라고 쓰지만 interface는 implemets(구현) 이라고 쓴다.
추상클래스의 정의는 abstract 메소드가 하나라도 존재하는 클래스를 일컫는다.
때문에 일부는 구현된 메소드도 있고, abstract라고 붙어있는 메소드는 구현이 안되어있다.
추상클래스를 상속받는 클래스는 반드시 추상메소드를 구현해야한다.
그래서 필수적으로 구현해야할 추상메소드가 있을 때 추상클래스를 쓰게된다.
인터페이스는 구현체 없이, 메소드에 대한 명세만 되어있다.
인터페이스를 상속받는 클래스는 반드시 인터페이스에 있는 메소드를 다 구현해야한다.
자바는 단일상속을 지원하기 때문에 추상클래스는 단일상속이지만,
interface를 사용하게 되면, implements를 구현하는 부분에서 extends 또한 사용할 수 있다.
즉, 다중상속이 가능해진다.
[ '이러이러한 메소드를 쓸 것이다.' 인터페이스에 선언을 해놓고, 가져다가 반드시 선언된 그대로 모두 구현해야 되는게]
=인터페이스이고,
[ 이러이러한 메소드가 있지만 가져다 쓰거나 오버라이드 하거나, abstract가 붙은 메소드만은 반드시 구현해야 되는게]
=abstract class이다.
3. abstract class(추상 클래스)와 interface 용도
인터페이스를 설명하려면 다형성(Polymorphism)에 대한 개념이 등장한다.
다형성이라고 하면 어려울 것 같지만 아래같이 생각하면 쉬울 것이다.
동물interface들은 모두 먹고method, 걷는다method.
하지만 동물들마다 먹고 걷는 방식은 다르다.
구현체(implement) : 고양이, 원숭이, 병아리
구현체에서는 동물 각각이 먹고 걷는 방식을 구현한다.
같은 '먹는다'라는 동사에서, 동물마다 여러가지 형태로 구현할 수 있기때문에 이름이 다형성.
그렇다면 인터페이스를 쓰면 얻는 이득이 무엇인가?
동물interface이 먹고method, 걷고method, 자는method 것은 공통적인데, 그 것을 행하는 방법이 각자 다르다.
고양이implement는 걸을 때 네발로 걷고, 원숭이implement는 두발 또는 네발로, 병아리도 두발로..
그래서 동물interface이 먹고method, 걷고method, 잔다method는 틀만 만들어놓고
고양이implement, 원숭이implement, 병아리implement는 그 틀안에 자신만의 방법으로 메소드를 구현하는 것이다.
반드시 구현체 동물들은 먹고method 걷고method 자는method 방법이 구현되어야 한다. 동물이라면..
그리고 고양이implement의 자는법이 달라져도 원숭이implement, 병아리implement에게는 아무 영향도 없다.
그럼 추상화 클래스는 언제 쓰는게 좋은가?
야생고양이가 새끼를 낳았다.
새끼는 인간에 의해 집고양이가 되었다고하자.
어미고양이(부모클래스) - 야생고양이
- 자는법 (method)
- 집에서 사는법 (추상화 메소드)
새끼고양이(자식클래스) - 집고양이
- 자는법 (method)
- 집에서 사는법 (method)
어미고양이는 야생고양이므로,
집에서 사는법은 모르지만, 새끼고양이는 집에서 사는법을 알려주기 위해 추상화 메소드로 만들었다.(구현X)
어미고양이는 자는법method이 있었고, 자식에게 전수하였다.
그러나 자식은 집고양이라 어미고양이와 자는법method이 달랐다.
그래서 자식고양이 나름대로 자는법method을 새로 터득하였다.
그게 이미 구현되어있는 부모클래스의 내용을 Override를 하는 것이다.
새끼고양이는 집 생활을 하며, 어미고양이가 모르는, 집에 사는법을 더 많이 터득하였다.
(부모 클래스보다 더 많이 구현되는 경우가 대부분이다)
그니깐 총정리를 하면,
인터페이스는 다형성이라 생각하면되고, 상속받은 클래스들은 반드시 인터페이스의 모든 함수를 사용해야하고 거기에 고유함수도 사용
상속은 부모 - 자식 관계로 생각하면 된다.
부모가 갖고있는 특정 기능만을 유전 받으면서, 기능을 더 추가한다거나, 특정기능a+기능b
부모의 유전된 기능을 약간 수정할 때 쓴다. 특정기능a =>특정기능a'
'Govern > Eclipse SE -상속,클래스,타입' 카테고리의 다른 글
07-26(월) 2.제네릭/컬렉션/ Iterator (0) | 2021.07.27 |
---|---|
07-26(월) 1.사용자예외클래스 throws/throw (0) | 2021.07.27 |
07-23(금) 2.클래스들,Array API, 예외처리조금 (0) | 2021.07.27 |
07-23(금) 1.커플링 중첩클래스 (0) | 2021.07.23 |
07-21(수) 상속 오버라이딩 (0) | 2021.07.21 |