3주차 두 번째 조별과제
어제 만든 장바구니 프로그램에서 새로운 문제를 더 던져 주셨다. Person 클래스를 만들고 user와 admin 클래스에게 상속 받게 했다. 기존에 admin은 없고 Customer로 고객을 관리했었는데 상속 개념을 배웠으니 사용하라는 말씀이셨다. 우선 extends를하고 부모에 필드 및 메소드를 만든다음 최대한 자식에서 활용해 보려고 노력했다.
배운점
상속
상속은 다른 클래스 간의 관계를 설정하고 계층적 순서로 정보를 관리하며 코드를 재사용하는 데 도움
새로운 클래스를 만들 때, 원하는 코드 중 일부가 포함된 클래스가 이미 있는 경우 기존 클래스에서 새 클래스를 파생(상속)시킬 수 있음
기존 클래스의 멤버 변수와 메서드를 재사용할 수 있음
필요성
기존 클래스의 기능을 사용하여 새 클래스를 만드는 기술한 클래스가 다른 클래스의 특징(멤버 메서드와 변수)을 가져오도록 하는 자바 객체지향 프로그래밍의 필수적인 부분, 클래스 간의 관계를 더 잘 이해할 수 있고 프로그램 구조를 더욱 조직화할 수 있기 때문에 코드의 가독성과 해석 가능성이 향상됨
응용 프로그램의 유지·관리에 유용함
부모 클래스의 필드와 메소드를 자식 클래스에게 물려줄 수 있음
부모 클래스 = 슈퍼 클래스, 기본 클래스
다른 클래스에 멤버 요소(메서드와 변수)를 상속하는 클래스로 상위 클래스
자식 클래스 = 서브 클래스, 파생 클래스
다른 클래스의 멤버 요소를 상속받은 클래스로 하위 클래스 자식 클래스는 부모 클래스의 모든 멤버 요소를 소유할 뿐만 아니라 그 밖에도 고유한 멤버 메서드와 변수를 추가할 수 있음
자식 클래스를 선언할 때 어떤 부모로부터 상속받을 것인지를 결정하고, 부모 클래스를 다음과
같이 extends 뒤에 기술
Is-A 관계(is a relationship) : Is-A 관계는 상속을 나타냄
‘…는 …이다’라는 의미, 부모-자식 관계
extends, implements 키워드로 구현함
모든 클래스는 java. lang.Object의 하위 클래스이다.
ParentCat class
모든 클래스는 Object 클래스를 상속받는다.
public class ParentCat extends Object{ // Object 상속 생략
private String breed;
public void eat(){
System.out.println("냠냠 먹이를 먹다.");
}
ParentCat(){}
ParentCat(String breed){
this.breed = breed;
}
public String getBreed() {
return breed;
}
}
부모인 ParentCat class는 Object를 상속받는다.
breed를 받는 생성자가 있다.
BabyCat class
public class BabyCat extends ParentCat{
private String color;
public void meow(){
System.out.println("난 냐옹이다옹!");
}
public BabyCat(){}
BabyCat(String color){
super("샴고양이"); // 나의 부모 생성자
this.color = color;
}
public void printInfo(){
super.getBreed();
System.out.println(color);
}
}
자식 클래스인 BabyCat 클래스의 생성자에서 color를 받는다.
동시에 breed(샴고양이)를 super()를 통해 부모 생성자를 사용한다.
public class CatMain {
public static void main(String[] args) {
BabyCat babyCat = new BabyCat("brown");
babyCat.meow();
babyCat.eat();
babyCat.printInfo();
}
}
"brown"을 사용하여 BabyCat 객체를 생성한다.
BabyCat 생성자 안의 super()로 부모의 생성자를 부르고 부모클래스의 breed필드를 할당한다.
Object에 담을 수 있다.
장바구니 문제같은 문제에서 Object에 담고 실제 필요할때 캐스팅해서 사용한다.
역직렬화
Object obj1 = babyCat; // 최상위 객체로 됨
BabyCat baby =(BabyCat) obj1; // 원형으로 역직렬화
baby.printInfo(); // Object 타입일땐 못 불러와,
// 다시 복원시켜야해, object타입은 그릇에 안전하게 보관만
데이터를 전송할 때,
오브젝트 타입을 직렬화해서 전송한다.
destination에 도착했을 때 원형으로 역직렬한다. (serialization)
서버에 파일 업로드, 다운로드도 직렬화 역직렬화 기능.
이 때 instance of 를 쓴다.
Object는 표준 스펙. 표준 사이즈.
print면 print 기능 따로 만드는 게 좋다. 여러기능 믹싱하지마라.
(오버라이딩 해서 만들면 fix 되기 때문에.)
단일 상속
클래스가 하나의 클래스에 의해서만 확장되는 것으로, 단일 수준 상속 이라고도 함
단일 부모 클래스에서 자식 클래스를 만들기 때문에 기본 클래스(부모 클래스)와 파생 클래스(자식클래스)가 각각 하나 뿐 임. 자식 클래스는 단일 기본 클래스로부터만 속성과 행동을 상속받고 부모클래스의 모든 메서드와 변수에 접근할 수 있음
implements는 여러개할 수 있음
다단계 상속
클래스가 하나의 클래스에 상속하고, 상속받은 자식 클래스가 또 다른 클래스에 상속하는 것을 말함
손주는 아버지로부터 상속받고 아버지는 할아버지로부터 상속받음
타입제한
A a = new B();
A클래스타입으로 B객체를 생성한다.
A에 있는 메소드를 B가 오버라이딩 했다면 , a.~~ 메소드로 B에서 오버라이딩 된 메소드가 실행됨
필드는
a. 으로 B에 있는 필드를 접근할 수 없다.
=> A클래스 바운더리 안에 있는애만 접근가능하다.
2번째 장바구니 만들기
Person 클래스를 만들어서 밑에 상속받는 User 클래스와 Admin클래스를 두어 관리자 로그인 기능을 만들라고 하셨다.
Person class
public class Person {
private String name; // 이름
private String phone; // 폰넘버
private String address; // 주소
Person (String name, String phone){
this.name = name;
this.phone = phone;
}
Person(String name, String phone, String address){
this.name = name;
this.phone = phone;
this.address = address;
}
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
// public String getAddress() {
// return address;
// }
}
기존에 있던 Customor 클래스에서 크게 변하지 않았다.
User class
public class User extends Person{
private ArrayList<Book> bookCart = new ArrayList<>();
public ArrayList<Book> getBookCart() {
return bookCart;
}
public void addBookCart(Book book){
this.bookCart.add(book);
}
public void printCartList(){
for (Book book: bookCart) {
book.bookPrint();
}
}
public void printCustomerInform(){
System.out.println("이름: "+getName());
System.out.println("전화번호: "+getPhone());
}
public User(String customerName, String customerTel) {
super(customerName, customerTel);
}**텍스트**
public User(String customerName, String customerTel, String customerAddress){
super(customerName,customerTel,customerAddress);
}
}
Person class를 상속받았다.
User class가 고객 클래스여서 기존 Customor와 비슷하지만 Person 필드에 이름과, 폰넘버가 있기때문에 super을 사용하여 Person 생성자를 사용해 주었다. 메소드는 기존과 비슷하다.
Admin class
public class Admin extends Person {
private String id;
private String password;
public Admin(String name, String phone) {
super(name, phone);
}
public Admin(String name, String phone, String id, String password) {
super(name, phone);
this.id = id;
this.password = password;
}
public String getId() {
return id;
}
public String getPassword() {
return password;
}
public void menuAdminLogin() { // 로그인 메소드
System.out.println("관리자 정보를 입력하세요");
Scanner sc = new Scanner(System.in);
System.out.println("아이디 :");
String adminId = sc.next();
System.out.println("비밀번호 :");
String adminPW = sc.next();
if (this.id.equals(adminId) && this.password.equals(adminPW)) {
System.out.println("이름" + this.getName() + " 연락처 " + this.getPhone());
System.out.println("아이디" + this.getId() + " 비밀번호 " + this.getPassword());
} else {
System.out.println("관리자 정보가 일치하지 않습니다.");
}
}
}
Person class를 상속받았다.
Admin이라는 관리자가 새로 생겼는데, id와 password를 갖는다. 때문에 부모(Person)에 없는 필드 두 개를 추가시켜주었다.
아이디와 비밀번호를 입력받고 그 값이 현재 할당되어있는 id와 password와 같다면 이름, 연락처, 아이디, 비밀번호를 출력시켜 주는 메소드를 추가했다.
느낀점
기존 짰던 코드들이 캡슐화가 잘 되지 않았고, 한 class에 너무 많은 기능이 있었다. 기능에 따라 Service class를 만들어 사용자가 이용하는 메뉴 및 각 메뉴 기능을 하는 클래스를 만들어 분리해 주었다. 너무 결합도가 높아 리펙토링이 반드시 필요하다.
상속기능을 사용하니 User와 Admin이 Person을 상속받아 같은 '사람'이어도 객체 구분이 명확해 졌다. 한 번 만들어 놓은 기능과 필드를 사용하니 메소드를 한 번더 정의하지안하도 되어서 반복이 줄었고 메소드 이름을 남발하지 않아 코드가 간결해짐을 느꼈다.
'신세게 - Java 공부' 카테고리의 다른 글
3주차 배운점 느낀점 - Usecase, 다이어그램, 엑터, 관계, 추상화, 인터페이스 (16) | 2024.10.03 |
---|---|
3주차 배운점, 느낀점 - 도메인, 모델, 요구사항 (10) | 2024.10.03 |
3주차 배운점 느낀점 - 생성자, 오버로딩, this(), 접근제한자, 조별과제 (10) | 2024.09.24 |
2주차 배운점 느낀점 - 클래스, 인터페이스, 상속 (햄버거) (2) | 2024.09.24 |
2주차 배운점 느낀점 - 빌더패턴, 자바빈패턴, 점층적 생성자 패턴 (2) | 2024.09.24 |