-
[자바] 객체지향(2) - 1 ( 패키지 )자바 2022. 7. 9. 11:54728x90
1. 상속
- 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.
- 자바는 단일 상속만 허용- 모든 클래스들에는 Object클래스가 최상위에 위치한다.
클래스간의 관계 - 상속 구현
class Parent { } class Child extends Parent { } class Child2 extends Parent { } // extends 라는 키워드를 써서 상속을 할 수 있다.
Child와 Child2간에는 서로 아무런 관계도 성립되지 않는다.
멤버 변수, 메소드 상속 코드 예시
class Parent { int age; } class Child extends Parent { void play() { System.out.println("놀자"); } } // child class는 age라는 변수도 받는다
상속 계층도 - 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
- 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.클래스간의 관계 - 포함 관계
포함관계는 상속과 마찬가지로 재사용하는 방법 중 하나 이다.
포함 - 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻한다.
재사용 하는 방법
// 재사용 안 할때의 코드 변화 class Circle { int x; int y; int z; } class Point { int x; int y; } // 재사용 할때의 코드 변화 class Circle { Point c = new Point(); // 원점 int z; }
상속 : is-a ( ~은 ~이다. )
포함 : has - a ( ~은 ~을 가지고 있다. )TIP, 인스턴스 생성하는 코드인데, 복잡해 보이는것 이해하기 위한 코드
Circle c = new Circle(new Point(150,150), 50); --same-- Point p = new Point(150,150); Circle c = new Circle(50);
2. 오버라이딩
- 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것 ex) 2차원 -> 3차원
class Point { int x; int y; String getLocation() { return "x" + x + "y" + y } } class Point3D extends Point { int z; String getLocation() { // 오버라이딩 return "x" + x + "y" + y + "z" + z } }
오버라이딩 조건
- 이름이 같아야 한다
- 매개변수가 같아야 한다
- 반환타입이 같아야 한다.
=> 선언부가 서로 일치해야 한다.조상 클래스의 메서드를 자손 클래스에서 오버라이딩할때
1. 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
2. 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
3. 인스턴스 메서드를 static 메서드로 또는 그 반대로 변경할 수 없다.2번에서 주의 할점
class Parent { void parentMethod() throws IOException, SQLException { .... } } // 조상 클래스 보다 작은 수의 예외 class Child extends Parent { void parentMethod() throws IOException { .... } } // 예외 수에 대한 조건이 지켜지지 않는 경우 class Parent { void parentMethod() throws Exception { .... } }
- 예외 수에 대한 조건이 지켜지지 않은 이유는 Exception는 모든 예외의 최고 조상이므로 가장 많은 개수의 예외를 던질 수 있도록 선언됨
Q. 조상 클래스에 정의된 static 메서드를 자손 클래스에서 똑같은 이름의 static메서드로 정의할 수 있나?
있다. 하지만, 호출시엔 ' 클래스이름.메서드이름() '으로 해야하고, static 멤버들은 자신들이 정의된 클래스에 묶여있다 생각하기
오버로딩 - 기존에 없는 새로운 메소드를 정의하는 것 ( new )
오버라이딩 - 상속받은 메소드의 내용을 변경하는 것 ( change, modify )super
- super()은 this()와 마찬가지로 생성자다.
-> 자주 나오는 에러 파트에 나올 수 있는 에러 파트 적었으니 확인! ( 12번 )
- 조상 클래스로부터 상속받은 멤버를 참조하는데, 멤버변수와 지역변수의 이름이 같을 때 this를 써 구별하듯, 상속받은 멤버와 자신의 멤버와 이름이 같을때, super로 구분
조상 클래스의 멤버와 자손클래스의 멤버가 중복 정의되어 서로 구별할때는 super 사용하기
- super는 static메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.
예시 - 조상의 메서드 호출
class Point { int x; int y; String getLocation() { return "x :" + x + "y : " + y; } } class Point3D extends Point { int z; String getLocation() { // 오버라이딩 // return "x :" + x + "y : " + y + "z : " + z; return super.getLocation() + "z : " + z; } }
첫 줄에 반드시 자신의 다른 생성자 또는 조상의 생성자를 호출하는 예시
class PointTest { public static void main(String[] args) { Point3D p3 = new Point3D(1,2,3); } } class Point { int x,y; Point(int x, int y) { this.x = x; this.y = y; } Stirng getLocation() { return "x :" + x + "y :" + y; } } class Point3D extends Point { int z; /* Point3D(int x, int y, int z) { super(); this.x = x; this.y = y; this.z = z; } */ // or Point3D(int x, int y, int z) { super(x,y); // 조상 클래스의 생성자를 호출한다 this.z = z; } Stirng getLocation() { return "x :" + x + "y :" + y; } }
3. 패키지( package )
패키지란, 클래스의 묶음 ( 클래스 or 인터페이스 포함 )
예시, java.lang 패키지 -> java.lang.String은 java.lang에 속한 String클래스 라는 의미
- 클래스가 물리적으로 하나의 클래스파일( . class )인 것과 같이 패키즈는 물리적으로 하나의 디렉토리다.
- 하나의 소스파일에는 첫 번째 문장으로 단 한번의 패키지 선언만을 허용한다
- 모든 클래스는 반드시 하나의 패키지에 속해야 한다
- 패키지는 점(.)을 구분자로 하여 계층구조 구성할 수 있다.
- 패키지는 물리적으로 클래스 파일을 포함하는 하나의 디렉토리이다.패키지의 선언
package 패키지명;
패키지는 소문자로 하며, 첫번째 문장에 하나의 소스파일에는 단 한번만 선언할 수 있다.
import문
import문은 클래스의 패키지를 미리 명시해주면서 클래스이름에서 패키지 명을 생략할 수 있다.
import 선언
일반적인 소스파일( *.java )의 구성의 순서
1. package문
2. import 문
3. 클래스 선언선언하는 방법
import 패키지명.클래스명; or import 패키지.*;
import 패키지.* 이런식으로 호출하는것이 일일이 지정하는것보다 편리하다.
전후 비교 코드 예시
import java.text.SimpleDateFormat; import java.util.Date; class ImportTest { public static void main(String[] args) { Date today = new Date(); SimpleDateFormat data = new SimpleDateFormat("yyyy/MM/dd"); // java.text.SimpleDateFormat data = new java.text.SimpleDateFormat("yyyy/MM/dd"); SimpleDateFormat data = new SimpleDateFormat("hh:mm:ss a"); System.out.println(date.format(today)); System.out.println(time.format(today)); } }
- java.lang 패키지는 빈번히 사용되서 import문으로 지정하지 않아도 된다.
static import 선언
import static java.lang.Integer.* // Integer클래스의 모든 static메서드 import static java.lang.Math.random; // Math.random()만. 괄호 안붙임 import static java.lang.System.out; // out만으로 참조가능 -> System.out.println(Math.random()) -> out.println(random());
4. 제어자
제어자는 클래스, 변수 또는 메서드의 선언부에 사용되어 부가적인 의미를 더한다
static
static은 클래스의 또는 공통적인 의미를 갖는다. ( 멤버변수, 메서드, 초기화 블록에 사용가능 )
하나의 변수를 모든 인스턴스가 공유하기에 클래스변수(static 멤버변수)는 인스턴스에 관계없이 같은 값을 갖는다.
class Static { static int w = 200; // 클래스 변수 static { } // 클래스 초기화 블럭 static int max(int a, intb) { } // 클래스 메서드 }
final
final 마지막의 또는 변경될 수 없는 을 의미한다. ( 클래스, 메서드, 멤버변수, 지역변수 )
변수에 사용하면, 변경할 수 없는 상수가 되고,
메서드에 사용되면 오버라이딩을 할 수 없게 되고,
클래스에 사용되면 자신을 확장하는 자손클래스를 정의하지 못하게 된다final class Final { // 조상이 될 수 없는 클래스 final int MAX_SIZE = 200; // 상수 ( 멤버변수 ) final void getMaxSize() { // 오버라이딩을 할 수없는 메서드 final int LV = MAX_SIZE; // 상수( 지역변수 ) return MAX_SIZE; } }
final이 붙은 벼수는 일반적으로 선언과 동시에 초기화 하지만, 인스턴스벼수는 생성자에게 초기화 되도록 할 수 있다.
class Card { final int NUMBRE; final String KIND; static int w = 100; static int h = 100; Card(String kind, int num) { // 이 부분이 생성자에 의해서 final이 붙은 변수를 초기화 하는 것이다. KIND = kind; NUMBER = num; } Card() { this KIND + " " + NUMBER; } public String toString() { return KIND + " " + NUMBER; } } class FinalCard { public static void main(String[] args) { Card c = new Card("HEART", 10); c.NUMBER = 5; // 에러, cannot assign a value to final variable NUMBER System.out.println(c.KIND); // 이렇게 해야함 } }
abstract
abstract은 미완성의 의미를 갖는다 . 메서드의 선언부만 작성하고 수행내용은 구현하지 않은 추상 메서드를 선언하는데 사용 ( 클래스, 메서드 )
abstract class AbstractTest { abstract void move(); }
접근 제어자
접근제어자를 사용하는 이유
- 외부로부터 데이터 보호
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해만일 메서드 하나를 변경해야 할때, 접근제어자를 적절히 선택해서 접근 범위를 최소화하도록 노력하자 ( public이면 전부를 봐야함 )
제어자 같은 클래스 같은 패키지 자손클래스 전체 public O O O O protected O O O X default O O X X private O X X X 생성자의 접근 제어자
보통 생정자의 접근 제어자는 클래스의 접근제어자와 같지만, 다르게 지정할 수 있다.
private이니 외부에서 접근할 수 없어서, 인스턴스를 만들 수 없다.
하지만, 클래스 내부에서는 인스턴스 생성 가능
-> 클래스 내부 메서드가 public 이면서 static 이여야 외부에서 이 클래스 인스턴스를 사용할 수 있다.
private인 클래스는 다른 클래스의 조상이 될 수 없다.
이유는, 생성자의 접근 클래스가 private이므로 자손클래스에서 호출하는 것이 불가능하기 때문이다
따라서 private 클래스 앞에 final을 더 추가하여 상속할 수 없는 클래스라는것을 알리기
제어자의 조합
1. 메서드에 static과 abstract를 함께 사용할 수 없다.
2. 클래스에 abstract와 final을 동시에 사용할 수 없다.
3. abstract메서드의 접근 제어자가 priate일 수 없다.
4. 매서드에 private과 final을 같이 사용할 필요가 없다.'자바' 카테고리의 다른 글
[자바] 예외처리 (0) 2022.07.13 [자바] 객체지향(2) - 2 (0) 2022.07.13 [자바] 객체지향(1) (0) 2022.07.07 [자바] 배열의 활용 (0) 2022.07.01 [자바] 배열 (0) 2022.06.28