https://www.youtube.com/playlist?list=PLpPXw4zFa0uKKhaSz87IowJnOTzh9tiBk
Rob Edwards 교수님의 CS310 Data Structures in Java를 공부하고 정리한 내용입니다.
부스트 코스 자바로 구현하고 배우는 자료구조에서도 학습할 수 있습니다.
객체지향 프로그래밍
Student s = new Student();
JVM은 Student에 대한 정보를 heap에 저장하고, heap의 주소를 참조변수에 저장하기 위해 4byte의 공간을 마련한다. heap에는 Student가 무엇을 상속했느냐에 따라 다른 크기를 할당한다.
예를 들어 Person()에 id, name, email 등 Student, Teacher 등 모든 사람이 가지는 정보를 가지고 있다고 하자.
그리고 Student는 gpa를, Student를 상속한 UnderGraduate는 졸업한 해인 year를 가지고 있다고 하자.
그러면 아래와 같이 클래스를 구성할 수 있다.
public class Person {}
public class Student extends Person {}
public class UnderGraduate extends Students {}
자바 특징의 특징
Java에서는 다중상속을 허용하지 않는다. 그래서 Student 클래스를 만들면 Person만을 상속하는 것을 알고 Person의 멤버와 메서드를 모두 가져온다. 마찬가지로 UnderGraduate 클래스를 만들면 Student와 Person의 멤버와 메서드를 모두 가져올 수 있다. 또한 위 이미지처럼 상속 계층 구조를 트리로 그릴 수 있는데, 트리를 올라갈 수만 있다. 그래서 Student, Undergraduate는 Faculty나 Admin의 정보를 갖고 있지 않다.
참조변수에 인스턴스를 할당할 때
Student s = new UnderGraduate();
위에서 클래스를 만들면 힙에 그에 맞는 공간이 할당된다고 했다. UnderGraduate, Person, Student의 정보를 힙에 저장하는데 Student의 참조변수로 UnderGraduate 객체를 가르키면 UnderGraduate에 포함돼있는 Student에 대한 멤버와 메서드를 사용할 수 있어서 컴파일 에러 없이 사용할 수 있다.
UnderGraduate u = new Student();
반대로 자손의 참조변수가 조상의 인스턴스를 가리키면 컴파일 에러가 난다. 힙에 할당되는 공간은 Student에 해당하는만큼인데 u로 UnderGraduate 클래스의 내용을 접근하려하면 불가능하기 때문에 컴파일 할 수 없다.
생각해보기
1) Person u = new Student();라 정의했을 때, 컴파일이 될까요?
UnderGraduate u = new Student();가 컴파일되지 않는 이유와 같이 컴파일 할 수 없다.
Comparable 인터페이스
equals 메서드 오버라이딩
Object o = "Hello World";
Object t = "Hello World";
if (o.equals(t)) { System.out.println("Object true"); }
String one = "Hello World";
String two = "Hello World";
if (one.equals(t)) {System.out.println("String true"); }
Object의 equals는 메모리의 주소를 비교한다. 그래서 내용이 같아도 object true를 출력하지 않는다. 하지만 String의 경우 Object의 equals를 오버라이딩해서 주소는 상관없이 내용을 비교하게 구현했다.
Monkey m = new Monkey();
Monkey n = new Monkey();
if (m.equals(n))
위의 경우에는 Monkey가 equals를 재정의 했는지 Object의 equals를 사용하는지 알 수 없다. 용도에 맞게 재구현하도록 하자.
Comparisons with generics
Comparisons을 통해 확장해서 대소를 비교할 필요가 있다. 이때 Comparable<T> 인터페이스를 사용한다. Comparable 인터페이스는 compareTo라는 추상메서드를 가지고 있다.
public int compareTo(T obj)
같은 타입의 오브젝트를 입력받아 정수를 반환하는데, 다음과 같은 규칙으로 작성한다.
if ( a < b ) return < 0
if ( a == b) return 0
if ( a > b ) return > 0
위의 형식에 맞게 비교 기준을 목적에 맞게 작성하면 된다.
if (((Comparable<T>)data).compareTo(obj)==0) // they are the same
위와 같이 Comparable 인터페이스를 만들면 자료형에 알맞은 데이터가 들어와 compareTo 함수를 통해 같은 자료형의 데이터를 비교할 수 있다.
생각해보기
1) Comparable 인터페이스의 T는 무엇을 의미할까요?
특정 타입이 아닌 원하는 타입의 일반적인 타입이다.
Generic Programming
제네릭 프로그래밍이 왜 필요한지에 대해 알아본다.
public class ss {
public int[] superSort(int[] array) {
//...sort...
return array;
}
}
다음과 같은 sorting 메서드를 작성했다고 하자. 지네릭 프로그래밍이 없다면, int[] 가아닌 String[]을 정렬하고 싶을 때
public class ss {
public String[] superSort(String[] array) {
//...sort...
return array;
}
}
다음과 같이 코드의 int를 직접 String으로 수정해야하고 Person으로 바꾸자 하면 Person으로 수정해야 한다.
Object[] arr = new Object[10];
Student s = new Student();
Object obj = s; //캐스팅가능
arr[0] = obj;
arr[1] = new Monkey();
arr[2] = new String();
위 코드를 컴파일 하는데는 문제가 없다. 왜냐하면 Monkey든 Student든 String이든 모든 것은 Object이기 때문이다. 하지만 모든 다른 타입이 섞여있어서 코드가 좋아보이지 않는다.
다양한 type의 메서드를 한번에 정의하기 위해, 그리고 위처럼 복잡한 배열 생성을 지양하기 위해 등 여러가지 이유로 Parameterized Types가 필요하고 Generic Programming이 필요하다.
생각해보기
1) 제너릭 프로그래밍의 장점은 무엇인가요?
ans1. 위의 sorting 예시처럼 비슷한 기능을 지원할 때 코드의 재사용성이 높아진다.
ans2. 제네릭을 사용하면 위의 배열 예시처럼 잘못된 타입이 들어왔을 때 컴파일 단계에서 방지할 수 있다.
ans3. 클래스 외부에서 타입을 지정해주기 때문에 따로 타입체크나 형변환이 필요없다. 관리가 용이해진다.
Parameterized Types
자료구조를 다룰 때, container를 분리할 필요가 있다.
MyContainer<Monkey> = new MyContainer<Monkey>();
MyContainer<Monkey> = new MyContainer<Monkey>();
다음과 같이 MyContainer를 한 번만 작성해도 원하는 타입에 따라 구분해서 담을 수 있다.
클래스를 작성할 때 첫번재 rule은 대문자로 Type을 파라미터화 시키는 것이다.
//클래스
public class LinkedList
public class LinkedList<E>
//메서드
public void addFirst(String s)
public void addFirst (E obj)
public String removeFirst()
public E removeFirst()
String, Integer 등 어느 것이라도 E에 대입해서 사용할 수 있다.
Constructor
class Node<E> {
E data;
Node<E> next;
public Node(E obj) {
data = obj;
next = null;
}
}
T뿐만 아니라 다른 Letter를 사용해도 된다.
E[] storage = (E[]) Object[size];
생각해보기
1) 매개변수화 타입과 객체를 사용하는 방식의 차이점은 무엇인가요?
매개변수화 타입은 해당 클래스나 자료구조의 내용을 건들지 않고 다른 타입을 사용할 수 있지만 오브젝트는 형 변환을 하거나 필요할 때 마다 해당 클래스를 수정해야 한다. 매개변수화 타입을 사용하면 재사용성이 높아진다.
'CS > 자료구조' 카테고리의 다른 글
[자료구조] 자바 힙 소개 및 구현 (0) | 2022.12.21 |
---|---|
[자료구조] 자바 해시 소개 및 구현 (0) | 2022.12.12 |
[자료구조] 자바 반복자, 연결 리스트, 스택과 큐 (0) | 2022.12.05 |
[자료구조] 자바 연결 리스트 소개 및 구현 (0) | 2022.12.05 |
[자료구조] 복잡성 : 자료구조 입문 (0) | 2022.11.24 |