객체를 늘 먼저 생각하고, 내 코드가 진짜 객체 지향스러운지 고민해주세요
본 과제는 다형성에 초점을 둔 과제입니다.
고려해보시면 좋을 기준
처음에는 먼저 생각한 것은 phone이라는 인터페이스를 생성 후, 각 객체들을 개별적으로 생각해서 Samsung, Apple 클래스를 만들어서 이를 implements해와서 재정의하는 것으로 생각했다. 이렇게 하면 클래스 간 상/하위 관계가 명확하고 오버라이드를 통해 재정의하기 때문에 좋은 객체 코드라고 생각했다.
package phone;
public interface Phone {
public void buyPhone();
public void turnOnPhone();
}
package phone;
public class SamsungPhone implements Phone{
String name;
String phoneName;
public SamsungPhone(String name, String phoneName) {
this.name = name;
this.phoneName = phoneName;
}
@Override
public void buyPhone() {
System.out.println(name + "님이 " + phoneName+"을 샀습니다.");
}
@Override
public void turnOnPhone() {
System.out.println(name + "님이 " + phoneName+"을 켰습니다.");
System.out.println("*** 폰 켜지는 중 ***");
}
}
package phone;
public class ApplePhone implements Phone {
String name;
String phoneName;
public ApplePhone(String name, String phoneName) {
this.name = name;
this.phoneName = phoneName;
}
@Override
public void buyPhone() {
System.out.println(name + "님이 " + phoneName+"을 샀습니다.");
}
@Override
public void turnOnPhone() {
System.out.println(name + "님이 " + phoneName+"을 켰습니다.");
System.out.println("@@@ 폰 켜지는 중 @@@");
}
}
이렇게 각 객체를 구성하고 메인 메서드를 실행했다.
import phone.ApplePhone;
import phone.SamsungPhone;
public class Main {
public static void main(String[] args) {
SamsungPhone samsungPhone = new SamsungPhone("재용", "삼송폰");
samsungPhone.buyPhone();
samsungPhone.turnOnPhone();
System.out.println();
ApplePhone applePhone = new ApplePhone("잡스", "사과폰");
applePhone.buyPhone();
applePhone.turnOnPhone();
}
}
각 구매자와 제품 명은 그때 그때 달라질 수 있고 이들의 정보를 담으면 좋겠다고 생각해서 생성자를 통해 만들 수 있게 했고 이를 통해 메서드에서 출력할 수 있게 생각했다. 그런데 이들을 생각해보니 사실상 SamsungPhone과 ApplePhone의 코드는 겹치는 부분이 많다. 그렇기 때문에 인터페이스나 추상 클래스를 통해 좀 더 간결하게 만들 수도 있을 것 같다는 생각을 했다.
공통 규약인 추상 클래스를 통해 이를 간결하게 해보자!! 가 2차 코드의 목표가 되었다.
ApplePhone과 SamsungPhone 클래스의 메서드가 거의 동일하다는 점을 고려한다면, 중복 코드를 줄일 수 있는 방법이 필요하다. 이를 위해서는 공통된 기능을 가진 상위 클래스나 인터페이스를 도입하면 된다.
간단한 방법 중 하나는 추상 클래스를 활용하는 것이다. Phone 인터페이스를 구현하는 추상 클래스를 만들고, 그 안에 공통된 기능을 가진 메서드를 구현할 수 있다. 그리고 SamsungPhone과 ApplePhone은 이 추상 클래스를 상속받도록 구성하면 된다.
package phone;
public interface Phone {
void buyPhone();
void turnOnPhone();
}
** 추가된 추상클래스 **
package phone;
public abstract class AbstractPhone implements Phone {
String name;
String phoneName;
public AbstractPhone(String name, String phoneName) {
this.name = name;
this.phoneName = phoneName;
}
@Override
public void buyPhone() {
System.out.println(name + "님이 " + phoneName + "을 샀습니다.");
}
@Override
public void turnOnPhone() {
System.out.println(name + "님이 " + phoneName + "을 켰습니다.");
}
}
package phone;
public class SamsungPhone extends AbstractPhone {
public SamsungPhone(String name, String phoneName) {
super(name, phoneName);
}
@Override
public void turnOnPhone() {
super.turnOnPhone();
System.out.println("*** 폰 켜지는 중 ***");
}
}
package phone;
public class ApplePhone extends AbstractPhone {
public ApplePhone(String name, String phoneName) {
super(name, phoneName);
}
@Override
public void turnOnPhone() {
super.turnOnPhone();
System.out.println("@@@ 폰 켜지는 중 @@@");
}
}
이렇게 하면 AbstractPhone 클래스에 공통 기능을 구현함으로써 중복을 제거할 수 있고, SamsungPhone과 ApplePhone은 이를 상속받아 필요한 기능만 추가하면 된다! 이렇게 각 출력문만 바꿔주고 슈퍼 클래스에서 받아올 수 있게 했다.

이렇게 잘 출력이 된다!
고려해보시면 좋을 기준
내 생각대로 채점을 해보자!