[자바] 인터렉션 연습문제 _ 그래픽카드
이번 게시글에는 수업 시간에 인터렉션을 활용하기 위해 배웠던 문제를 다시 한 번 혼자서 풀어보고자 한다.
문제의 골자는 다음과 같다.
- 인터페이스를 활용하여 그래픽카드와 os의 소통과정을 구현해 볼 것.
- 각 클래스를 . Java 단위로 나눌 것.
- 클래스는 Rgb, PointColor, GraphicsCard, NvidiaGeForce, AmdRadeon, GraphicsCardMain 총 6개로 구성할 것.
그럼 시작해 보겠다.
먼저, Rgb 클래스를 구성해보자.
package inter;
public class Rgb {
private int red;
private int green;
private int blue;
Rgb(){
this(0,0,0);
}
Rgb(int red, int green, int blue){
this.red=red;
this.green=green;
this.blue=blue;
}
public int getRed() {
return this.red;
}
public void setRed(int red) {
this.red=red;
}
public int getGreen() {
return this.green;
}
public void setGreen(int green) {
this.green=green;
}
public int getBlue() {
return this.blue;
}
public void setBlue(int blue) {
this.blue=blue;
}
}
위와 같이, Rgb 클래스에는 색상 int 값이 들어가 있다.
생성자로 초기값을 설정해주고, get-set을 통해 private 변수를 public으로 만들어 준다.
다음은 PointColor 클래스를 작성해준다.
package inter;
public class PointColor extends Rgb {
private int x;
private int y;
private Rgb rgb;
PointColor(){
this(0,0,null);
}
PointColor(int x, int y, Rgb rgb){
this.x=x;
this.y=y;
this.rgb=rgb;
}
public int getX() {
return this.x;
}
public void setX(int x) {
this.x=x;
}
public int getY() {
return this.y;
}
public void setY(int y) {
this.y=y;
}
public Rgb getRgb() {
return this.rgb;
}
public void setRgb(Rgb rgb) {
this.rgb=rgb;
}
}
Rgb를 상속받은 후,
int x, int y, Rgb rgb를 변수로 주고, 생성자로 초기값을 설정한 후 get-set 함수를 활용해 접근 가능하도록 만든다.
다음은 GraphicsCard 클래스를 만들어 보자.
package inter;
public interface GraphicsCard {
public abstract String company();
public abstract String model();
public abstract int memory();
public abstract void write(PointColor pointColor);
}
보다시피 GraphicsCard 는 인터페이스 클래스다.
이 클래스를 상속받는 자녀 클래스(그래픽카드)들이 반드시 활용해야 할 메서드 4개를 작성해 준다.
마지막 write 메서드 역시 메인이 아닌 각 그래픽 카드에서 찍어주기 위해 void 로 리턴타입을 설정해 준다.
다음은 이 클래스를 상속받는 그래픽 카드를 작성해 보자!
// 여기서 추상 메서드를 모두 void로 설정하지 않도록 주의! 나머지 메서드는 그래픽카드에서 os로 그래픽카드의 정보를 반환(return)해 주어야 하므로, 적절한 리턴 타입을 설정하도록 한다.
package inter;
public class NvidiaGeForce implements GraphicsCard
{
private String company;
private String model;
private int memory;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public NvidiaGeForce(String model, int memory) {
company = "NvidaGeForce";
this.model = model;
this.memory = memory;
}
public String company() {
return this.company;
}
public String model() {
return this.model;
}
public int memory() {
return this.memory;
}
public void write(PointColor pointColor)
{
Rgb rgb = pointColor.getRgb();
if(pointColor != null) {
System.out.println("=="+company+"GraphicsCard 출력==");
System.out.println("1. 좌표를 구한다.");
System.out.println("x : "+pointColor.getX());
System.out.println("y : "+pointColor.getY());
System.out.println("2. 색상 구성");
}
if(rgb!=null) {
System.out.println("Rgb : "+rgb.getRed());
System.out.println("Rgb : "+rgb.getGreen());
System.out.println("Rgb : "+rgb.getBlue());
}
System.out.println("3. 화면에 색상 출력");
}
}
위는 다소 복잡해 보이지만, 띁어보면 간단하다. NevidiaGeForce 라는 그래픽카드 메서드를 만든 후, 그래픽카드 인터페이스를 상속받는다.
프라이빗으로 회사, 모델명, 메모리 선언을 했으므로 get-set 을 통해 다른 메서드에서 접근할 수 있도록 만들고, 생성자를 통해 회사명, 모델명, 메모리를 받는다. 회사명의 경우, 확정되었으므로 확정 정의해주고, 나머지의 경우 this 를 통해 인스턴스 변수에 받은 모델명과 메모리를 입력한다.
사실 메서드의 경우, set과 사실상 같은 역할을 하지만, 추상 메서드를 반드시 오버라이딩 해야 하므로, 그대로 작성해준다. 끝으로 wirte 메서드를 작성한다. 여기에는 x, y, rgb 정보가 필요하므로, 이 세 가지 변수를 모두 가지고 있는 pointColor 를 매개변수로 받아 넣는다.
이 때, pointColor의 값이 null이 아닌지 확인해야 할 필요가 있다는 점을 주의하여 if 절을 사용하도록 한다. (왜냐하면 값을 넣지 않고 객체 생성만 하더라도, 일단 오류가 없이 실행될 수 있기 때문이다.)
Amd 역시 Nvidea 클래스와 완전히 동일하므로 생략하도록 하겠다.
마지막으로 작성할 것은 main 이다. 내용은 다음과 같다.
package inter;
public class GraphicsCardMain {
public void operatingSystemWrite(GraphicsCard graphicsCard, PointColor pointColor) {
if(graphicsCard!=null) {
System.out.println("==그래픽카드 출력==");
System.out.println("회사명 : "+graphicsCard.company());
System.out.println("모델명 : "+graphicsCard.model());
System.out.println("메모리 : "+graphicsCard.memory());
graphicsCard.write(pointColor);
}
}
public static void main(String[] args) {
// 엔비디아 객체 생성
NvidiaGeForce nvidiaGeForce = new NvidiaGeForce("Gefpre GT 710", 2048);
//GraphicCards amd = new Amd("모델명",메모리); 이러한 형태도 가능하다. 다형성 예시
PointColor p = new PointColor();
p.setX(100);
p.setY(200);
p.setRgb(new Rgb(222,333,555));
GraphicsCardMain gmain = new GraphicsCardMain();
gmain.operatingSystemWrite(nvidiaGeForce, p);
}
}
우선 클래스에 시스템에 관해서 찍어줄 systemWrite 메서드를 만들고, 그 메서드가 앞서 작성한 write를 호출할 수 있도록 한다. 이러한 과정에서 당연히 그래픽카드 정보와 pointcolor 정보가 필요하므로, 메인 메서드로부터 받는다.
물론, 여기서도 앞과 같이 그래픽카드의 값이 null이 아닌지 확인해준다. 이유는 동일하다.
메인 메서드는 객체 생성과 값 설정, systemWrite 메서드 호출만 해주면 된다.
먼저 엔비디아 객체 생성을 해주고, 매개변수로 모델명과 메모리를 보낸다. 여기서 굳이 참조변수를 엔비디아로 할 필요는 없다. 부모가 자식을 참조할 수 있으므로, 주석 처리한 amd 소스코드와 같은 형태도 가능함을 생각해 볼 수 있다.
그리고 pointcolor를 객체 생성해 준다. 그리고 각 값에 적절한 수를 넣는다.
setRgb 메서드의 경우 매개변수가 rgb 형식이므로, 새로 Rgb를 열어서 값을 넣어 주었다.
이제 마지막으로 같은 클래스 내에 있는 systemWrite 메서드를 호출한다. 단, 해당 메서드가 static이 아니므로 객체 생성을 해 준다.
이제 프로그램을 돌리면 다음과 같은 결과가 나온다.
느낀 점! (겸 오답노트)
이 문제를 혼자서 재구성해보며 몇 가지 문제가 있었다. 가장 첫 번째로 실수했던 부분은 인터페이스 클래스에 추상메서드의 리턴타입을 모두 void로 설정했던 것이다.
두 번째로는, NvidiaGeForce 의 write 메서드에서 객체 생성을 하는 방법이다. 나는 습관적으로 new PointColor로 새로운 객체를 생성하려 했지만, 이 rgb 변수가 하는 목적을 생각해 본다면, 객체 생성을 하는 것이 아니라 당연히 매개변수로받은 pointColor를 사용해야 한다. 근본적으로 저 코드의 쓰임을 이해했다면 틀리지 않았을 것이다.
애초에 전체적인 흐름을 좀 더 자세히 생각해보고 코드를 짜기 시작했어야 하는 것 같다. 설계도의 중요성...
더불어 rgb부터~ 마지막 main까지 코드를 짜는 순서 역시 수업시간과 동일하게 진행했는데 이렇게 차근차근 진행하는 것 역시 익혀 둘 필요가 있는 것 같다.
중간에 if를 쓴 부분에는 (지금은 예외처리에 대하여 배운 시점이고, 위 예제는 이를 배우기 전에 한 것이다) try catch를 사용할 수 있는지도 생각해 보자...