전체 방문자
오늘
어제
21종
종이의 코딩 공부방
21종
  • 분류 전체보기 (174)
    • JAVA (64)
    • Springboot (46)
      • 블로그만들기 (45)
    • Database (60)
      • Oracle (60)
    • 프로젝트 3 (CELOVER) (0)
    • 개발서버 구축 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

최근 댓글

hELLO · Designed By 정상우.
21종

종이의 코딩 공부방

JAVA

[자바/JAVA] 프로그래밍 - 상속성 (Inheritance)

2023. 6. 12. 18:52

상속쓰기 전

Desktop Class

package com.kh.chap01_beforeVSafter.before.model.vo;

public class Desktop {
	
	private String brand;
	private String pCode;
	private String pName;
	private int price;
	private boolean allInOne;
	
	public Desktop() {
		
	}
	
	public Desktop(String brand, String pCode, String pName, int price, boolean allInOne) {
		this.brand = brand;
		this.pCode = pCode;
		this.pName = pName;
		this.price = price;
		this.allInOne = allInOne;
	}
	
	public void setBrand(String brand) {
		this.brand = brand;
	}
	
	public String getBrand() {
		return brand;
	}
	
	public void setpCode(String pCode) {
		this.pCode = pCode;
	}
	
	public String getpCode() {
		return pCode;
	}
	
	public void setpName(String pName) {
		this.pName = pName;
	}
	
	public String getpName() {
		return pName;
	}
	
	public void setPrice(int price) {
		this.price = price;
	}
	
	public int getPrice() {
		return price;
	}
	
	public void setAllInOne(boolean allInone) {
		this.allInOne = allInone;
	}
	
	public boolean isAllInOne() {	// 관례적 표현 get대신 is로 표현
		return allInOne;
	}
	
	public String information() {
		return "brand : " + brand + ", pCode : " + pCode + ", pName : " + pName + ", price : " + price + ", allInOne : " + allInOne;
	}
	

}

Smartphone Class

package com.kh.chap01_beforeVSafter.before.model.vo;

public class SmartPhone {

	private String brand;
	private String pCode;
	private String pName;
	private int price;
	private String mobileAgency;
	
	public SmartPhone() {
		
	}
	
	public SmartPhone(String brand, String pCode, String pName, int price, String mobileAgency) {
		this.brand = brand;
		this.pCode = pCode;
		this.pName = pName;
		this.price = price;
		this.mobileAgency = mobileAgency;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getpCode() {
		return pCode;
	}

	public void setpCode(String pCode) {
		this.pCode = pCode;
	}

	public String getpName() {
		return pName;
	}

	public void setpName(String pName) {
		this.pName = pName;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public String getMobileAgency() {
		return mobileAgency;
	}

	public void setMobileAgency(String mobileAgency) {
		this.mobileAgency = mobileAgency;
	}

	public String information() {
		return "brand : " + brand + ", pCode : " + pCode + ", pName : " + pName + ", price : " + price + ", mobileAgency : " + mobileAgency;
	}
}

Tv Class

package com.kh.chap01_beforeVSafter.before.model.vo;

public class Tv {

	private String brand;
	private String pCode;
	private String pName;
	private int price;
	private int inch;
	
	public Tv() {
		
	}
	
	public Tv(String brand, String pCode, String pName, int price, int inch) {
		this.brand = brand;
		this.pCode = pCode;
		this.pName = pName;
		this.price = price;
		this.inch = inch;
	}
	
	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getpCode() {
		return pCode;
	}

	public void setpCode(String pCode) {
		this.pCode = pCode;
	}

	public String getpName() {
		return pName;
	}

	public void setpName(String pName) {
		this.pName = pName;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getInch() {
		return inch;
	}

	public void setInch(int inch) {
		this.inch = inch;
	}

	public String information() {
		return "brand : " + brand + ", pCode : " + pCode + ", pName : " + pName + ", price : " + price + ", inch : " + inch;
	}
}

실행 클래스

package com.kh.chap01_beforeVSafter.before.run;

import com.kh.chap01_beforeVSafter.before.model.vo.Desktop;
import com.kh.chap01_beforeVSafter.before.model.vo.SmartPhone;
import com.kh.chap01_beforeVSafter.before.model.vo.Tv;

public class BeforeRun {

	public static void main(String[] args) {
		
		// Desktop 객체 생성
		// brand, pCode, pName, price, allInOne
		
		Desktop d = new Desktop("삼성", "d-01", "짱짱데스크탑", 200000, true);
		
		// Tv 객체 생성
		// brand, pCode, pName, price, inch
		Tv t = new  Tv("엘지", "T-01", "겁나 얇은 티비", 350000, 65);
		
		// SmartPhone 객체 생성
		// brand, pCode, pName, price, mobileAgency
		SmartPhone s = new SmartPhone("애플", "s-01", "아이폰", 1300000, "KT");
		
		System.out.println(d.information());
		System.out.println(t.information());
		System.out.println(s.information());
	}
}

컴파일 결과

유지보수 요청 : pName => productName 으로 바꿔라... 제조일자(createDate) 필드 추가해라 ...3개다

세 클래스에 공통적인 필드와 메소드들이 존재함
이런 중복된 코드들을 따로 "부모클래스"로 한번만 정의해두면 중복된 코드들을 주일 수 있음!!
=> 수정과 같은 유지보수 요청이 들어왔을 때 일일히 찾아서 수정할 필요 없이
한번만 정의해둔 부모클래스만 수정하면 전체적으로 반영됨

세 클래스가 공통적으로 가지고 있는 것
=> brand, pCode, pName, price 핋드들, setter/getter, information 메소드
==> product 클래스 미리 정의해볼것!


상속을 쓴다면 ?

Desktop Class

package com.kh.chap01_beforeVSafter.after.model.vo;
		//자식    ----------> 부모
		//후손    ----------> 조상
		//하위    ----------> 상위
		//this   ----------> super
public class Desktop extends Product {
	
	private boolean allInOne;

	public Desktop() {
		
	}
	
	public Desktop(String brand, String pCode, String pName, int price, boolean allInOne) {
//		this.brand = brand;	// this : 이 클래스의 주소값
		
		// brand ~ price 네 개의 값들은 부모클래스(Product)의 필드에 대입
		
		// 해결방법1. 부모클래스에 있는 필드르 protected 접근 제한자로 수정
		/*
		super.brand = brand;
		super.pCode = pCode;
		super.pName = pName;
		super.price = price;
		*/
		
		// 해결방법2. 부모클래스에 있는 setter 메소드 활용하기 (public 이기 때문에 setter 메소드 사용가능)
		/*
		super.setBrand(brand);
		super.setpCode(pCode);
		super.setpName(pName);
		super.setPrice(price);
		*/
		
		// 해결방법3. 부모 생성자 호출하기 => 우리는 이걸로 간다.
		// this 생성자 this(), super 생성자 super() 위치가 항상 위여야한다
		super(brand,pCode,pName,price);
		this.allInOne = allInOne;

	}
	
	public boolean isAllInOne() {
		return allInOne;
	}
	
	public void setAllInOne(boolean allInOne) {
		this.allInOne = allInOne;
	}
	
	// 오버라이딩 : 부모클래스에 있는 매소드를 자식 클래스에서 재정의 하는 것
	public String information() {
		return super.information() + ", allInOne : " + allInOne;
	}
}

Smartphone Class

package com.kh.chap01_beforeVSafter.after.model.vo;

public class SmartPhone extends Product{
	
	public String mobileAgency;
	
	public SmartPhone() {
		
	}
	
	public SmartPhone(String brand, String pCode, String pName, int price, String mobileAgency) {
		super(brand, pCode, pName, price);
		this.mobileAgency = mobileAgency;
		
	}
	
	public String getMobileAgency() {
		return mobileAgency;
	}
	
	public void setMobileAgency(String mobileAgency) {
		this.mobileAgency = mobileAgency;
	}
	
	public String information() {
		return super.information() + ", mobileAgency : " + mobileAgency;
	}

}

Tv Class

package com.kh.chap01_beforeVSafter.after.model.vo;

public class Tv extends Product{

	private int inch;
	
	public Tv() {
		
	}
	
	public Tv(String brand, String pCode, String pName, int price, int inch) {
		super(brand, pCode, pName, price);
		this.inch = inch;
	}
	
	public int getInch() {
		return inch;
	}
	
	public void setInch(int inch) {
		this.inch = inch;
	}
	
	public String information() {
		return super.information() + ", inch : " + inch;
	}
}

상속을 쓰기 전에는 없는 Product Class

package com.kh.chap01_beforeVSafter.after.model.vo;

public class Product {
	
	// 세 클래스 모두 공통적으로 가지고 있는 요소들 (필드, 메소드) 만을 기술
	private String brand;
	private String pCode;
	private String pName;
	private int price;
	
	public Product() {
		
	}
	
	public Product(String brand, String pCode, String pName, int price) {
		this.brand = brand;
		this.pCode = pCode;
		this.pName = pName;
		this.price = price;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getpCode() {
		return pCode;
	}

	public void setpCode(String pCode) {
		this.pCode = pCode;
	}

	public String getpName() {
		return pName;
	}

	public void setpName(String pName) {
		this.pName = pName;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}
	
	public String information() {
		return "brand : " + brand + ", pCode : " + pCode + ", pName : " + pName + ", price : " + price;
	}

}

실행 Class

package com.kh.chap01_beforeVSafter.after.run;

import com.kh.chap01_beforeVSafter.after.model.vo.Desktop;
import com.kh.chap01_beforeVSafter.after.model.vo.SmartPhone;
import com.kh.chap01_beforeVSafter.after.model.vo.Tv;

public class AfterRun {

	public static void main(String[] args) {
		
		// Desktop 객체 생성
		// brand, pCode, pName, price, allInOne
		
		Desktop d = new Desktop("삼성", "d-01", "짱짱데스크탑", 20000, true);
		
		// Tv 객체 생성
		// brand, pCode, pName, price, inch
		Tv t = new Tv("엘지", "t-01", "겁나 얇은 티비", 350000, 65);
		
		// SmartPhone 객체 생성
		// brand, pCode, pName, price, mobileAgency
		SmartPhone s = new SmartPhone("애플", "s-01", "아이폰", 1300000, "KT");
		
		System.out.println(d.information());
		System.out.println(t.information());
		System.out.println(s.information());
		
		s.setPrice(120000000); // 부모클래스에 있는 메소드 호출
		s.setMobileAgency("SKT");	// 자식 클래스에 있는 메소드 호출
//		System.out.println(s.information());	// 오버라이딩
		
	}

}

컴파일 결과


상속의 장점

- 보다 적은 양의 코드로 새로운 클래스 작성 가능
- 중복된 코드를 별도로 관리하기 때문에 코드의 추가 변경에 용이(프로그램의 생산성과 유지보수에 크게 기여)

상속의 특징

- 자식객체룰 가지고 부모클래스에 있는 메소드를 마치 내 것처럼 호출 가능
- 부모클래스에 있는 메소드를 오버라이딩을 통해 자식 클래스에서 재정의 가능
=> 오버라이딩을 하는 순간 자식클래스에 있는 메소드 우선권을 가짐
클래스간의 상속은 다중상속이 불가능하다 (단일 상속만 가능)


실습예제


Vehicle Class

package com.kh.chap02_inherit.model.vo;

public class Vehicle {

	private String name;
	private double mileage;
	private String kind;
	
	public Vehicle() {
		
	}
	
	public Vehicle(String name, double mileage, String kind) {
		this.name = name;
		this.mileage = mileage;
		this.kind = kind;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public double getMileage() {
		return mileage;
	}
	
	public void setMileage(double mileage) {
		this.mileage = mileage;
	}
	
	public String getKind() {
		return kind;
	}
	
	public void setKind(String kind) {
		this.kind = kind;
	}
	
	public String information() {
		return "name : " + name + ", milage : " + mileage + ", kind : " + kind ; 
	}
	
	public void howToMove() {
		System.out.println("움직이다.");
	}
	
}

Car Class

package com.kh.chap02_inherit.model.vo;

public class Car extends Vehicle {
	
	private int tire;
	
	public Car() {
		
	}
	
	public Car(String name, double mileage, String kind, int tire) {
		super(name, mileage, kind);
		this.tire = tire;
	}
	
	public int getTire() {
		return tire;
	}
	
	public void setTire(int tire) {
		this.tire = tire;
	}
	
	public String information() {
		return super.information() + ", tire : " + tire;
	}
	
	@Override	// 어노테이션(생략가능) 대신 부모에 무조건 이 메소드 이름이 있어야 함
	public void howToMove() {	// 이름 이상하게 하면 오류남
		System.out.println("바퀴를 굴려 움직인다.");
	}
	
	@Override
	public String toString() {
		return "아무말";
	}

}

Ship Class

package com.kh.chap02_inherit.model.vo;

public class Ship extends Vehicle{
	
	private int propeller;
	
	public Ship() {
		
	}
	
	public Ship(String name, double mileage, String kind, int propeller) {
		super(name, mileage, kind);
		this.propeller = propeller;
	}
	
	public int getPropeller() {
		return propeller;
	}
	
	public void setPropeller(int propeller) {
		this.propeller = propeller;
	}
	
	public String information() {
		return super.information() + ", propeller : " + propeller;
	}
	
	@Override
	public void howToMove() {
		System.out.println("프로펠러를 돌려서 움직인다.");
	}

}

Airplane Class

package com.kh.chap02_inherit.model.vo;

public class Airplane extends Vehicle{
	
	public int tire;
	public int wing;
	
	public Airplane() {
		
	}
	
	public Airplane(String name, double mileage, String kind, int tire, int wing) {
		super(name, mileage, kind);
		this.tire = tire;
		this.wing = wing;
	}
	
	public int getTire() {
		return tire;
	}
	
	public void setTire(int tire) {
		this.tire = tire;
	}
	
	public int getWing() {
		return wing;
	}
	
	public void setWing(int wing) {
		this.wing = wing;
	}
	
	public String information() {
		return super.information() + ", tire : " + tire + ", wing : " + wing;
	}
	
	@Override
	public void howToMove() {
		System.out.println("바퀴를 굴리다가 날개를 휘저으며 움직인다.");
	}

}

실행 Class

package com.kh.chap02_inherit.run;

import com.kh.chap02_inherit.model.vo.Airplane;
import com.kh.chap02_inherit.model.vo.Car;
import com.kh.chap02_inherit.model.vo.Ship;

public class InheritRun /*extends Object*/ {	// 자바의 모든 클래스는 object의 후손, object에서 있는 메소드를 쓸 수 있음

	public static void main(String[] args) {
		Car c = new Car("벤틀리", 12.5, "세단", 4);
		Ship s = new Ship("낚시배", 3, "어선", 1);
		Airplane a = new Airplane("종이비행기", 0.01, "제트기", 10, 4);
		
		System.out.println(c.information());
		System.out.println(s.information());
		System.out.println(a.information());
		
		c.howToMove();	// 부모클래스에 있는 howToMove 메소드를 사용가능 
		s.howToMove();
		a.howToMove();
		
		System.out.println(c.hashCode());
		System.out.println(c.equals(s));	// 그럼 부모가 2명인가요? 다중상속인가요? ㄴㄴ 얘의 부모가 object의 자식 => 즉 할머니 같은 느낌
		System.out.println(c.toString());	// Car에서 toString을 오버라이딩 해서 반환값을 바꿔 줄 수 있음
		System.out.println(c/*.toString()*/);
		

	}
}

컴파일


정리

상속의 장점

- 보다 적은 양의 코드로 새로운 클래스 작성 가능
- 코드를 공통적을 관리하기 때문에 추가나 변경에 용이 (유지보수, 생산성 up)


상속의 특징

- 클래스간의 상속에 있어서는 다중상속이 안된다!!(단일 상속만 가능 즉, 부모는 하나다)

- 자식객체는 부모클래스에 있는 메소드를 마치 내 것처럼 호출 가능
 + 부모클래스에 있는 메소드가 맘에 안들면 자식 클래스에서 오버라이딩 가능 (내 입맛대로 재정의)
- 부모클래스에 정의돼있는 protected 필드는 자식클래스에서 직접 접근 가능
- 명시되어있지는 않지만 모든 클래스(제공하는 클래스, 직접만든 클래스)는 Object 클래스의 후손이다.
 => 즉, object클래스에 있는 메소드를 마음대로 호출 가능!!
 => 뿐만 아니라 오버라이딩을 통해 재정의도 가능함!!

    'JAVA' 카테고리의 다른 글
    • [자바/JAVA] 프로그래밍 - 상속 (inheritance) 실습 문제_1
    • [자바/JAVA] 프로그래밍 - 오버라이드 (Override)
    • [자바/JAVA] 프로그래밍 - 객체 배열(Object Array) 오류
    • [자바/JAVA] 프로그래밍 - 객체 배열(Object Array), for each문(향상된 for문)
    21종
    21종
    코딩 공부한 것 정리하려고 만든 블로그

    티스토리툴바