JAVA OOP
Object Oriented Programming
절차지향 -> 객체 지향 (설계지향)
class MyClass{ 변수(멤버변수) -> 접근지정(외부, 내부) 함수(메서드) -> 처리 }
절차 지향에서는 순서를 중요시하였다. 하지만 객체 지향 에서는 처리 방식이 무엇이 있는지만 신경쓰면 나머지는 순서에 맞게 호출만 해주면 된다.
클래스명 변수(instance) = new 클래스명();<br>
-> MyClass cls = new MyClass<br>
cls 는 스택 영역에 올라가게된다. new MyClass 는 힙에 올라간다.<br>
MyClass cls = null; -> (0) 로 셋팅한다.
## Sorting (객체화)
package sortingClass;
import java.util.Scanner;
public class Sorting {
// 멤버 변수(2가지 이상 처리(메서드)에서 접근 해야하는경우), 아래 멤버 함수에 모두 접근이 가능하다.
int number[];
boolean updown;
// 처리
public void input() {
Scanner sc = new Scanner(System.in);
System.out.println("정렬할 갯수: ");
int count = sc.nextInt();
number = new int[count];
for (int i = 0; i < number.length; i++) {
System.out.println((i + 1) + "번째 수 : ");
number[i] = sc.nextInt();
}
System.out.println("오름(1)/내림(2) = ");
int ud = sc.nextInt();
if (ud == 1)
updown = true;
else
updown = false;
}
public void sorting() {
for (int i = 0; i < number.length - 1; i++) {
for (int j = i + 1; j < number.length; j++) {
if (updown) {
if (number[i] > number[j]) {
swap(i, j);
}
} else {
if (number[i] < number[j]) {
swap(i, j);
}
}
}
}
}
public void swap(int i, int j) {
int temp = number[i];
number[i] = number[j];
number[j] = temp;
}
public void result() {
for (int i = 0; i < number.length; i++) {
System.out.println(i + ":" + number[i]);
}
}
}
Sorting 클래스를 만들고 안에 멤버 변수와 그를 이용한 메서드를 생성하였다.
package sortingClass;
public class MainClass {
public static void main(String[] args) {
Sorting sort = new Sorting();
sort.input();
sort.sorting();
sort.result();
}
}
Main클래스에서 인스턴트를 생성하고 Sorting 클래스의 매서드를 이용하여 user가 입력한 수를 정렬하는 프로그램을 만들었다.
이전 방식보다 소스코드가 더 명확해지고 가독성이 좋아졌다.
객체 지향의 특징
상속 & 다형성
- 상속 : 부모클래스에서 기능을 상속한다. 추가로 기능을 확장하는 경우
- 다형성 : 상속 후에 여러형태로 자식클래스가 구현되는것을 의미
Over Ride
- 받은 재산을 수정해서 확장 하는 목적 ( 관리를 효율적으로 하기 위해 이용)
- 각 자식 클래스 마다 오버라이딩 한 메서드의 내용은 달라진다.
- 형식이 완전히 똑같아야 Over Ride가 된다.
Parent p = new Child(); p.method(); // Child 메서드가 호출된다.(오버라이딩만된것만) p.func; (Error) // Child 의 func 메서드는 못 찾는다. (p(인스턴스)는 Parant의 인스턴스로 생성되어서)
- 만약 Parent 부모 클래스가 있고 Child의 자식 클래스가 있을때 같은 메서드(즉 Over Ride) 된 메서드를 출력한다. 만약 Child 클래스에 func 메서드가 있으나 부모클래스에는 해당 메서드가 없다면, 인스턴스 p 는 func 메서드를 호출 하지 못한다.
Parant human[] = new Parant[4];
human[0] = new ChildOne();
human[1] = new ChildTwo();
human[2] = new ChildTwo();
human[3] = new ChildOne();
// 한번에 다 넣고 man 일때 lady 일때 구분해서 만들어 줄 수 있다.
for (int i = 0; i < human.length; i++) {
human[i].method();
}
//결과
// ChildOne method()
// ChildTwo method()
// ChildTwo method()
// ChildOne method()
*/
Parant p1 = new ChildOne();
Parant p2 = new ChildTwo();
p1.method();
p2.method();
// 아래와 같이 캐스트 변환을 해줘야 한다.
ChildOne co = (ChildOne)p1; // 캐스트 변환 (강제 형변환) p1을 ChildOne의 인스턴스로 바꿔준다.
// ChildOne의 함수를 사용할 수 있게 된다.
co.func();
((ChildOne)p1).func(); // 위처럼 새로운 인스턴스에 p1을 넣어도 되고 바로 캐스트 변환해서 사용해도된다.
만약 Parant 클래스 인스턴스로 생성했으나 ChildOne 이나 ChildTwo 에 있는 method를 불러오기 위해서는 캐스트 변환을 해주어야 한다.
super
- 해당 예약어를 통해 부모 클래스의 생성자를 선택 할 수 있다.
- 생략이 가능하다.
- 입력하지 않으면 자동적으로 기본 생성자 생성
자식 클래스를 생성할때 상속클래스를 우선적으로 내려 받고 자식클래스의 내용을 호출한다.
instanceOf
- 상속 받은 Object를 부모 클래스의 instance로 생성
ChildOne -> Parant
ChildTwo -> Parant
- 생성된 instance에 어떤 자식클래스가 생성되었는지 판별할 수 있는 제어자
Parant arrpar[] = new Parant[3];
arrpar[0] = new ChildOne();
arrpar[1] = new ChildTwo();
arrpar[2] = new ChildOne();
for (int i = 0; i < arrpar.length; i++) {
arrpar[i].method(); // over ride 된 method for문을 통해 전부 호출 가능
if(arrpar[i] instanceof ChildOne) { // istanceOf 를 통해 True false를 알려준다.
((ChildOne)arrpar[i]).oneMethod(); // over ride가 아닌 method
}
}
자식 클래스에 오버라이드가 되지 않은 메서드를 호출하고 싶을때 캐스트변환을 해주어야한다.
다만 어느 클래스에 있는지 매번 찾지 않고 instanceOf 예약어를 이용하여 호출해 줄 수 있다.