만들어진 클래스 이용
1.내가 원하는 기능을 가진 클래스를 찾기
2.내개 원하는 기능을 수행해주는 메소드를 찾기
static 인지 아닌지 확인: static 이라면 인스턴스를 생성할 필요가 없음
- static이 아니라면 인스턴스를 생성해야 하므로 생성자를 다시 확인
메소드의 매개변수를 확인
- 매개변수는 메소드에게 일을 시킬 때 메소드가 사용할 데이터입니다.
- 필요한 데이터를 제공하지 않으면 메소드는 일을 하지 않거나 에러를 발생
return type을 확인
- 작업을 수행하고 어떤 결과를 돌려주는지 확인
package & import
1.package
- 관련있는 클래스의 모임
- 파일 시스템에서는 하나의 디렉토리
- package가 배포 단위
- 클래스는 실행은 가능하지만 배포를 할 수 없습니다.
- 자바에서는 클래스들을 다른 프로젝트에서 사용하도록 배포하고자 할 때는 클래스들을 패키지로 묶어서 jar로 압축해서 전달하면 됩니다.
2.자바의 클래스 로드
- 자바는 실행되는 프로그램에 존재하는 모든 클래스들을 jvm에 로드하고 실행
- 자바에서는 존재하는 모든 클래스를 별도의 작업이 바로 사용이 가능
- 사용을 할 때는 클래스의 전체 경로를 입력해야 합니다.
패키지이름.클래스
의 형태로 사용해야 합니다.
3.import
- import는 가져오는 개념이 아니고 줄여쓰기 위한 개념입니다.
- 클래스를 만들기 전 상단 부분에 import를 해주면 패키지이름을 생략하고 클래스를 사용할 수 있습니다.
1) 패키지이름.*
- 패키지에 존재하는 모든 클래스들을 패키지 이름을 생략하고 사용 가능
2) 패키지이름.클래스이름
- 클래스이름에 해당하는 클래스만 패키지 이름을 생략하고 사용 가능
3) 예제
Scanner의 원래 이름은 java.util.Scanner
java.util.Scanner sc = new java.util.Scanner(System.in);
- 위처럼 작성하면 너무 길어서 import 하고 사용
import java.util.Scanner;
Scanner sc = new Scanner(System.in);
- Eclipse에서는 클래스 이름만 사용한 경우 클래스 이름에 커서를 갖다대면 import 해주겠다는 메시지가 보여고 이를 클릭하면 자동으로 import 구문이 입력됩니다.
4) import 할 때 주의할 점
- 클래스를 찾을 때 자바는 현재 프로젝트에서 찾고 없으면 다른 패키지에서 찾습니다.
- 제공되는 클래스와 동일한 이름의 클래스를 만들면 제공되는 클래스를 사용할 때는 패키지이름을 전부 입력해서 사용해야 합니다.
- 제공되는 클래스와 동일한 이름의 클래스를 만들지 않는 것이 좋습니다.
- 서로 다른 패키지에 동일한 이름의 클래스가 존재하는 경우가 있는데 프로젝트 내에서 2개의 클래스를 모두 사용할 때는 하나는 패키지이름을 전부 입력하는 것이 좋습니다.
java.util.Date 와 java.sql.Date의 경우 모두 사용하는 경우에 하나는 전체 경로를 입력하는 것이 좋습니다.
5) java application을 개발할 때 import 하지 않아도 java.lang 패키지는 이미 import가 되어 있어서 클래스 이름만 이용하면 됩니다.
상속(Inheritance)
1.개념
하위 클래스가 상위 클래스의 모든 것을 물려받는 것
물려받는 클래스를 하위(Sub) 클래스라고 하는데 다른 용어로는 Derived(파생 클래스) 클래스라고도 하고 물려주는 클래스를 상위(Super) 클래스라고 하는데 다른 용어로는 Based(기반 클래스) 클래스라고도 합니다.
자주 사용하는 상위 클래스들을 파악해서 프로그램을 만들기 쉽게 제공해주는 것을 프레임워크 또는 엔진 이라고 부릅니다.
윈도우 용 프로그램 개발 프레임워크로 가장 유명한 것이 VC#, VC++(MFC)
Java 개발 프레임워크로 유명한 것은 Spring
2.상속을 이용했을 때의 장점
코드를 간결하게 만들수 있기 때문에 유지보수가 편리해집니다.
재사용성이 증가
3.단점
- 상위 클래스의 내용을 변경하면 하위 클래스도 영향을 받게됩니다.
- 하위 클래스는 상위 클래스에 종속됩니다.
4.상속을 관계로 표현할 때는 is a 관계라고 합니다.
5.java는 단일 상속만 지원합니다.
- java의 모든 클래스는 하나의 클래스로부터만 상속을 받을 수 있습니다.
6.java의 모든 클래스는 java.lang.Object 라는 클래스로부터 상속을 받습니다.
7.java에서 상속 방법
class 클래스이름 extends 상위클래스이름{
}
8.접근지정자와 상속
private: 상속은 되지만 하위 클래스에서 접근 할 수 없음(사용 불가)
default(package): 동일한 패키지내에서는 하위 클래스에서 상위 클래스의 멤버를 사용할 수 있고 서로 다른 패키지에서는 사용이 불가능
protected: 하위 클래스에서 사용 가능
public: 하위 클래스에서 사용 가능하고 인스턴스도 사용 가능
9.상속과 접근 지정자
1) 상위 클래스로 사용할 Based 클래스
public class Based {
private int num;
String title; //접근 지정자를 설정하지 않는 것을 default 또는 package
protected String content;
public int readcnt;
}
2) Based 클래스로 부터 상속받은 Derived 클래스
//Based 클래스를 상속받은 Derived 클래스
public class Derived extends Based {
//메소드
public void disp() {
//num = 10; //num은 private 멤버라서 보이지 않는다고 에러 메시지
//protected로 변경할 것인지 물어봅니다.
title = "제목";
content = "내용";
readcnt = 0;
}
}
- 상속을 받을 때는 클래스를 만들 때 Super Class에 입력해도 되고 클래스를 만든 후 직접 extends 상위 클래스 이름을 입력해도 됩니다.
10.super
1) 인스턴스 메소드에서의 super
인스턴스 메소드 안에서 어떤 이름을 사용하면 메소드 안에서 먼저 찾고 없으면 메소드 외부에서 찾으며 그래도 없으면 상위 클래스에서 이름을 찾습니다.
- 상위 클래스에도 없으면 undefined 되었다고 에러 메시지 출력
메소드 안에서 찾지 않고 메소드 외부에서 부터 찾고자 할 때는 this. 을 앞에 붙이면 됩니다.
- this가 붙으면 메소드 안에서는 찾지 않고 메소드 외부의 클래스에서 먼저 찾고 없으면 상위 클래스에서 찾습니다.
this. 대신에 super.을 붙이면 자신의 클래스에서도 찾지 않고 상위 클래스에서만 찾습니다.
this를 사용해야만 하는 경우는 메소드 내에 만든 변수와 클래스에 만들어진 변수 이름이 같을 때 클래스에 만들어진 변수를 사용할 때 이용
- super는 현재 클래스와 상위 클래스에 동일한 이름의 메소드가 있을 때 상위 클래스의 메소드를 호출하기 위해서 사용합니다.
실습
- Based 클래스에 print() 메소드를 생성
public void print() {
System.out.println("상위 클래스의 print");
}
- Derived 클래스에 print() 메소드를 생성
public void print() {
System.out.println("하위 클래스의 print");
}
public void method() {
print(); //앞에 아무것도 붙지 않았기 때문에 자신의 클래스에서부터 찾아 갑니다.
//자신의 클래스에 만든 print()
System.out.println("======================");
super.print(); //상위 클래스에서 print()를 찾습니다.
//Based에 만든 print()
}
- main 메소드를 소유한 실행 클래스를 만들어서 Derived 클래스의 method()를 호출
public class Main {
public static void main(String[] args) {
//Derived 클래스의 method()를 호출
//Derived 인스턴스를 생성
Derived d = new Derived();
//메소드 호출
d.method();
}
}
2) 생성자에서의 super()
생성자에 첫번째 줄은 작성을 하지 않더라도 super()입니다.
- 상위 클래스의 매개변수가 없는 생성자를 호출하는 구문입니다.
Based 클래스를 상속받은 Derived 클래스에 생성자를 만들지 않더라도 아래와 같은 생성자가 존재
public Derived(){
super(); //이 구문은 new Based(); 와 동일한 구문
}
Based에 생성자를 만들고 super()를 호출하지 않으면 자동으로 super()가 삽입됩니다.
상속을 받으면 상위 클래스의 모든 멤버를 상속받아서 생성해야 합니다.
- 상위 클래스의 멤버를 생성할려면 상위 클래스의 생성자를 호출해야 합니다.
- 코드 상 호출하지 않더라도 무조건 해야 하기 때문에 자바에서는 자동으로 삽입해줍니다.
상위 클래스에 매개변수가 없는 생성자(default constructor)가 없으면 하위 클래스에 생성자를 만들어서 상위 클래스의 생성자를 직접 호출해야 합니다.
11.polymorphism(다형성)
1) method overriding(메소드 재정의)
- 상위 클래스에 존재하는 메소드를 하위 클래스에서 다시 만드는 것
- 메소드 이름이 같고 매개변수의 개수와 자료형이 같은 메소드를 다시 만드는 것
- 매개변수의 개수나 자료형이 다르면 method overloading(메소드 중복정의)
- 하는 이유는 자신이 만든 클래스의 경우는 다형성 구현을 위해서 이고 프레임워크가 제공하는 클래스가 상위 클래스인 경우는 기능확장을 위해서 입니다.
2) 프레임워크가 제공하는 클래스를 상속받아서 사용하는 경우
- 프레임워크가 제공하는 클래스는 기본 기능만 제공해주기 때문에 기본 기능을 확장하기 위해서 상속을 받아서 사용
- 기본 기능을 확장할 때 메소드 오버라이딩을 사용하는데 이 때 상위 클래스의 메소드를 호출을 해주어야 합니다.
public void method(){
super.method();
//추가하고자 하는 기능
}
- 상위 클래스의 메소드 호출 시점은 정리를 하는 메소드를 제외하고는 상위 클래스의 메소드를 먼저 호출합니다.
- 정리하는 메소드는 상위 클래스의 메소드를 나중에 호출합니다.
- android studio 같은 경우에는 자신이 제공하는 클래스를 상속받아서 메소드를 오버라이딩 할 때 상위 클래스의 메소드를 호출하지 않으면 에러 발생하고 VC++ 같은 곳에서는 메소드 오버라이딩 할 때 상위 클래스 메소드 호출하는 구문이 자동 삽입됩니다.
3) @Override
@이 붙는 것은 자바에서는 annotation 이라고 하고 python에서는 decorator 라고 합니다.
- 어노테이션은 자주 사용하는 자바 코드를 매번 작성하는 것이 번거롭기 때문에 이 어노테이션을 추가하면 자바가 컴파일을 할 때 자동으로 코드를 삽입해주는 것입니다.
@Override 는 이 메소드가 오버라이딩 된 메소드를 라는 것을 알려주기 위한 어노테이션
- 이 어노테이션을 붙였는데 이 메소드가 상위 클래스에 없으면 에러가 발생합니다.
프로그램의 가독성을 높이기 위해서 오버라이딩 한 경우에는 붙여주는 것이 좋습니다.
4) 객체 지향 언어에서의 참조형 사이의 대입
- C나 Java 와 같은 정적 자료형 언어들은 변수를 선언할 때 사용한 자료형의 데이터만 변수에 대입할 수 있습니다.
int a = 10;
//a에는 정수만 대입이 가능합니다.
- 참조형 에서는 한가지 예외가 있습니다.
- 상위 클래스 타입으로 만들어진 변수에 하위 클래스 타입의 인스턴스 참조를 대입할 수 있습니다.
하위 클래스 타입으로 만들어진 변수에 상위 클래스 타입의 인스턴스 참조는 대입할 수 없는데 강제 형 변환을 하면 대입이 되고 문법적인 에러는 없습니다.
원래의 자료형이 하위 클래스 타입이 아니면 실행할 때 예외가 발생합니다.
Based , Based를 상속받은 Dervied가 존재
Based obj = new Based(); //Based 로 만든 변수에 Based 인스턴스를 대입 - 에러 없음
Derived ins = new Derived(); //에러 없음
Based o = new Derived(); //Derived가 Based로 부터 상속을 받았기 때문에 가능
Derived d = new Based(); //이 문장은 에러 Based가 Derived의 하위 클래스가 아니어서 에러
Derived d1 = (Derived)(new Based()); //강제 형 변환을 해서 에러는 아님 - 실행 시 에러
Derived d2 = (Derived)(o); //강제 형 변환을 에러는 아님 - 실행 시 에러 아님
5) 참조형 변수의 멤버 호출
- 참조형 변수는 변수를 선언할 때 사용한 자료형의 멤버만 호출이 가능합니다.
Based o = new Derived();
o 는 Based 에 존재하는 것만 호출할 수 있습니다.
Based는 없고 Derived에만 존재하는 것은 호출할 수 없습니다.
예외적으로 overriding 된 메소드는 인스턴스를 만들 때 사용한 생성자의 것을 호출합니다.
- o가 오버라이딩 된 메소드를 호출할 때는 Based 의 것이 호출되는 것이 아니고 Derived의 것이 호출됩니다.
6) polymorphism(다형성)
- 동일한 메시지에 대하여 다르게 반응하는 성질
- 동일한 코드가 대입된 인스턴스에 따라 다른 메소드를 호출하는 것
12.다형성 구현 실습
1) 다형성과 상관없이 Terran, Zerg, Protoss의 공격 메소드를 생성하고 Main에서 실행하는 코드를 작성하고 실행
- Terran 클래스를 생성하고 attack 메소드를 구현
public class Terran {
//테란의 공격 메소드
public void attack() {
System.out.println("탱크로 대포를 쏘고 마린으로 총을 쏩니다.");
}
}
- Protoss 클래스를 만들고 attack 메소드를 구현
public class Protoss {
//프로토스 공격 메소드
public void attack() {
System.out.println("질럿은 찌르고 드래군은 공을 던집니다.");
}
}
- Zerg 클래스를 만들고 attack 메소드를 구현
public class Zerg {
//저그의 공격
public void attack() {
System.out.println("저글링은 때리고 히드라는 침을 뱉습니다.");
}
}
- main 메소드를 소유한 실행 클래스를 만들고 3개 클래스의 attack을 호출하는 코드를 작성
public class Main {
public static void main(String[] args) {
Terran t = new Terran();
t.attack();
Zerg z = new Zerg();
z.attack();
Protoss p = new Protoss();
p.attack();
}
}
2) 위까지 실행하면 3개의 메소드를 호출할 수 있습니다.
지금은 3개 클래스의 인스턴스를 가지고 메소드를 호출하기 위해서 3개의 변수에 각각의 인스턴스를 대입해서 메소드를 호출했습니다.
메소드를 호출하는 코드가 다릅니다.
인터페이스에 메소드를 연결할려고 하면 3개의 명령어가 필요합니다.
하나의 명령어로 3개 메소드를 모두 호출할 수 있도록 하기 위해서 동일한 코드가 3개의 메소드를 호출할 수 있도록 변경
Terran, Zerg, Protoss 클래스의 인스턴스를 모두 저장할 수 있는 변수를 만들기 위해서 3개 클래스에 상속할 상위 클래스를 생성하고 메소드를 오버라이딩 할 수 있도록 attack을 구현
public class Starcraft {
//하위 클래스의 인스턴스가 attack을 호출할 수 있도록 오버라이딩을 위한 메소드
public void attack() {
}
}
- Terran, Zerg, Protoss 클래스에 Starcraft 클래스를 상속하도록 클래스 선언문 수정
public class Terran extends Starcraft
public class Zerg extends Starcraft
public class Protoss extends Starcraft
- main 메소드 수정
Starcraft star = new Terran();
star.attack();
star = new Zerg();
star.attack();
star = new Protoss();
star.attack();
'Language_Study > JAVA' 카테고리의 다른 글
[JAVA, App] 10.예외처리 (0) | 2020.12.25 |
---|---|
[JAVA, App] 9.추상메소드 (0) | 2020.12.23 |
[JAVA, App] 7.클래스 (0) | 2020.12.23 |
[JAVA, App] 6.검색 (0) | 2020.12.23 |
[JAVA, App] 5.데이터정렬 (0) | 2020.12.23 |