TIL | Java - OOP 특징 : 3.다형성

2022. 10. 12. 11:59·Java

3. 다형성

: 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미

- 상속이 없으면 불가능하다
- 부모타입에 모든 자식 객체가 대입될 수 있다. (서로 변환 가능)
(부모님이 더 크기때문에 자식클래스가 부모에 자동 저장)
- 객체들의 타입을 하나로 통일할 수 있기에 다형성 사용
- 원래 부모클래스에 있는 기능만 사용할 수 있지만 오버라이딩 된 메서드는 먼저 실행된다.

 

package day08.poly.basic;
//하나의 클래스 파일에 여러 클래스 선언이 가능합니다.
//단, 파일명 동일한 클래스가 public 이어야 합니다.
//1파일 1클래스 원칙 (자바에서는)

//최고 부모님 Object!
//                         Object
//                           |
class A extends Object{}//   A
class B extends A{}//       / \
class C extends A{}//      B   C
class D extends B{}//     /     \
class E extends C{}//    D       E

public class Basic { //사용자 클래스
	//다형성(클래스 형변환) - 자식의 주소가 부모에 저장되는 성질
	//멤버변수 //클래스 선언
	
	A a = new B();
	A a1 = new C();
	A a2 = new D();
	A a3 = new E();
	
	//다형성은 상속을 전제로 합니다.
	//bad 예시
	//B b = new C();
	
	//Object형에는 모든 클래스를 저장할 수 있습니다.
	//오브젝트형으로 자동형변환이 되기 때문에 오브젝트를 막 사용하면 안되고 꼭 필요할때만 사용
	Object obj = 1;
	Object obj2 = 3.14;
	Object obj3 = "문자열";
	Object obj4 = new A();
	
}

 

 

부모클래스

package day08.poly.basic;

public class Parents {

	public void method01() {
		System.out.println("부모의 1번 메서드");

	}

	public void method02() {
		System.out.println("부모의 2번 메서드");
	}

}

자식클래스

package day08.poly.basic;

public class Child extends Parents{

	//Child가 method01,2,3 다 사용 가능
	@Override
	public void method02() { 
		System.out.println("오버라이드 된 2번 메서드");
	}
	
	public void method03() {
		System.out.println("자식의 3번 메서드");
	}
	
	//alt+shif+s 오버라이딩 단축키
	//어떤걸 오버라이딩 해야할지 모를때 누름
	
	
}

메인클래스

package day08.poly.basic;

public class MainClass {
	
	public static void main(String[] args) {
		
		
		
		Child c = new Child();
		c.method01();//상속
		c.method02();//오버라이드
		c.method03();//내꺼
		
		System.out.println("----------다형성----------");
		//자식이 부모에 저장되는데, 부모님처럼 사용되지만, 단 자식의 오버라이딩된 메서드가 실행됩니다.
		//다형성이란? 잠깐 형변환을 해주는것
		
		Parents p = c; // == 같은 문장 :Parents p = new Child()
		
		p.method01(); //부모님 실행
		p.method02(); //오버라이딩된 메서드가 실행됨
//		p.method03(); 
		
		System.out.println(p==c); //true 동일한 주소값을 나타냄
		
		System.out.println("----------클래스 캐스팅----------");
		//다형성이 적용되면, 자식이 가지고 있던 본래의 기능을 사용할 수 없기 때문에, 클래스 캐스팅을 사용합니다.
		
//		child cc = p; //p가 더 크니까 안넣어짐
		Child cc = (Child)p; 
		cc.method01();
		cc.method02();
		cc.method03();
		
		System.out.println("-----주의할 점-----");
		//다형성이 적용된 객체만 캐스팅이 가능합니다.
		Parents pp = new Parents();
		Child ccc = (Child)pp;//error
		
	}

}

🏁 예제 ( 1 )

더보기

부모클래스

package day08.poly.basic2;

public class Person { //부모 클래스로 사용
	
	String name;
	int age;
	
	Person(){
		
//		name = "송송송";
//		age = 1;
//		위에것들 못알아들으면 this.붙이기
//		this.name = "송송송";
//		this.age = 1;
	
		this("홍길동", 1);  //두개짜리 생성자 호출
	}
	
	Person(String name) {
		this(name, 1); 	//두개짜리 생성자 호출
	}
	
	Person(String name, int age){
		
		this.name = name.toUpperCase();
		this.age= age;
		
//		System.out.println("백줄짜리 코드...");
		
	}
	
	String info() {
		
		return "이름 : " + name + "\n나이 : " + age;
		
	}
	
}

자식클래스 - Employee

package day08.poly.basic2;

public class Employee extends Person {

	String department;// 부서
	
	//생성자
	Employee(String name, int age, String department){
		
		//super(name,age);
			this.name = name.toUpperCase();
			this.age= age;
			this.department = department;
			
//			System.out.println("백줄짜리 코드...");
			
		
	}
	
	String info() {
		//super.메서드() - 오버라이딩된 메서드에서 부모님의 원형 메서드가 필요할 때 사용 가능
		return super.info() + "\n부서 : " + department;
	}
}

자식클래스 - Student

package day08.poly.basic2;

public class Student extends Person {

	String studentId; //학번
	
	Student(String name, int age, String studentId){
		super(name);
		this.studentId = studentId;
	}
	
	String info() {
		return super.info() + "\n학번 : " + studentId;
	}
}

자식클래스 - Teacher

package day08.poly.basic2;

public class Teacher extends Person{

	String subject; //과목

	//생성자
	Teacher(String name, int age, String subject){

		this.name = name;
		this.age = age;
		this.subject = subject;

	}

	String info() {

		return "이름 : " + name + "\n나이 : " + age + "\n과목 : " + subject;

	}
}

사용자정의 클래스 - House

package day08.poly.basic2;


public class House{
	
	/*
	 * 배열을 전달하라는 말이 아닙니다.
	 * 1. 멤버변수로 크기가 100개인 Person배열을 선언
	 * 2. 배열의 순서를 사용할 count변수 선언
	 * 3. void setPerson(???) 모든 자식클래스를 받을 수 있도록 선언하세요.
	 *    기능 - 멤버변수에 매개변수를 순서대로 저장되는 기능
	 *    
	 * 4. 메인클래스에서는 3명의 Person을 전달하세요.
	 */
	
	private Person arr[] = new Person [100];
	
	private int count; //초기값 0
	
	public void setPerson(Person p) {
		
		arr[count] = p;
		count++;
		
	}
	
	//arr반환 get메서드
	public Person[] getArr() {
		return arr;
	}
	 
	
}

🏁 과제

더보기

부모클래스

package quiz12;


public class Product {
	//상품의 부모클래스 - 수정x
	private int price;
	private String name;
	
	public Product(int price, String name) {
		this.price = price;
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
}

자식클래스 - 컴퓨터

package quiz12;

public class Computer extends Product {
	//가격 600원 이름은 com
	//get, set메서드는 자동으로 상속됩니다
	public Computer() {
		super(600, "com");
	}
}

자식클래스 - 라디오

package quiz12;


public class Radio extends Product {

	//Radio의 생성자는 기본생성자로 만들고, super를 통해서 가격 500원, 이름은 radio로 저장
	//get, set메서드는 자동으로 상속됩니다
	public Radio() {
		super(500, "radio");
	}
	
	
	
}

자식클래스 - 티비

package quiz12;


public class Tv extends Product {
	//가격 400원 이름은 tv
	//get, set메서드는 자동으로 상속됩니다
	
	public Tv() {
		super(400, "tv");
	}

}

사용자정의 클래스

package quiz12;

import java.util.Arrays;

public class MyCart {
	/*
	철수는 TV객체, Radio객체, Computer객체를 전달받아서 계산하는 Cart클래스를 만드려고한다.
	Product클래스는 부모클래스 이다.
	Tv, Radio, Computer는 자식클래스 이다.
	Product클래스에는 필요한 변수가 선언되어 있고 getter, setter가 생성되어 있다.
	 */
	private int money;
	private Product[] cart = new Product[1]; //상품을 저장할 배열
	private int i = 0;

	//2. MyCart의 생성자는 money만 받아서 초기화

	public MyCart(int money){
		this.money = money;
	}

	/*
	 * 3. buy(모든 상품을 받도록 선언)
	 * ************객체의 getter메서드의 활용*************
	 * 가진돈과 전달된 물건객체의 가격을 비교해서 돈이 적으면 "금액부족" 출력후에 종료하세요.
	 * 가진돈이 충분하면 물건의 가격을 money에서 차감하고 add(상품) 메서드를 호출합니다.
	 */ 	

	public void buy(Product p) {
		if(money < p.getPrice()) {
			System.out.println("금액부족");
			return;
		} else {
			money -= p.getPrice();
			System.out.println("잔액 " + money);
			add(p);
		}
	}

	/*
	 * 4. add(모든 상품을 받도록 선언)
	 * *************배열의 복사**************
	 * 만약 i의 값이 장바구니의 크기보다 같거나 크다면
	 * 기존의 장바구니보다 크기가 * 2큰 배열을 생성.
	 * 기존의 장바구니 값을 새로운 배열에 복사.
	 * 새로운 장바구니를 기존의 장바구니와 바꾼다.
	 * 
	 * 상품(매개변수)을 장바구니(배열)에 담는다.
	 * 
	 * info()메서드 호출
	 */


	private void add(Product p) {
		if(i >= cart.length) {
			Product[] cart2 = new Product[cart.length*2];

			for(int j = 0; j < cart.length; j++) {
				cart2[j] = cart[j]; //배열 복사

			}
			cart = cart2;	//배열 변경

		}
		cart[i] = p;	//배열에 추가
		i++;
		info();


	}

	/*
	 * 5.info()
	 * - 장바구니 안에 담긴 물건의 목록(name)을 출력한다.
	 * - 남은금액 출력
	 * 출력예시: TV TV Computer Radio ......
	 * 		  남은금액: 500
	 * 메인에서 buy메서드 실행 
	 * 
	 */

	public void info() {
		for (int j = 0; j < this.i; j++) {
			Product p = cart[j]; //product
			System.out.print(p.getName() + " ");
		}
		System.out.println("\n남은금액:" + money);

	}

}

메인클래스

package quiz12;

public class MainClass {
	
	public static void main(String[] args) {
		
		MyCart cart = new MyCart(20000);
		
		Computer c = new Computer();
		Radio r = new Radio();
		Tv t = new Tv();

		cart.buy(c);
		//cart.buy(new Computer());
		cart.buy(r);
		cart.buy(r);
		cart.buy(t);
	}
	
}

instanceof - 거의 사용하지 않음

: 클래스 타입을 검사해주는 키워드

더보기
package day08.poly.instanceof_;


public class MainClass {

	public static void main(String[] args) {
		
		//instanceof - 객체의 모형을 확인
		
		Person s = new Student("홍길덩",10,"1234");
		Person t = new Teacher("이순신",20,"프로그램");
		
		
//		Student s2 = (Student)s;
//		Teacher s2 = (Teacher)s; 잘못캐스팅
		
		casting(s);
		casting(t);
		
		
	}
	
	public static void casting(Person p) {
		
		if(p instanceof Student) { //p가 스튜던트였으면 true, 아니면 false
			
			Student s = (Student)p;
			System.out.println(s.info());
			
		} else if(p instanceof Teacher) {
			
			Teacher t = (Teacher)p;
			System.out.println(t.info());
			
		}
		
	}
	
}

'Java' 카테고리의 다른 글

TIL | Java - final  (0) 2022.10.13
TIL | Java - static  (0) 2022.10.13
TIL | Java - 키워드 this & super  (0) 2022.10.11
TIL | Java - Overloading : 오버로딩  (0) 2022.10.07
TIL | Java - Overriding : 오버라이딩  (0) 2022.10.07
'Java' 카테고리의 다른 글
  • TIL | Java - final
  • TIL | Java - static
  • TIL | Java - 키워드 this & super
  • TIL | Java - Overloading : 오버로딩
개발 공부
개발 공부
  • 개발 공부
    개발 공부
    개발 공부
  • 전체
    오늘
    어제
    • 전체보기 (163)
      • 프로젝트 (1)
      • JavaScript (46)
      • Node.js (3)
      • Next.js (5)
      • React (17)
      • NoSQL (0)
      • HTML,CSS (3)
      • CS (6)
      • Java (35)
      • Spring (6)
        • Spring의 정석 (1)
      • Spring boot (1)
      • MySQL (1)
      • 리눅스 (16)
      • JSP (9)
      • AWS (0)
      • git (2)
      • 알고리즘 (1)
      • ect (7)
      • Project (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바의 정석
    티스토리챌린지
    오블완
    Java의 정석
    Java
    자바
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
개발 공부
TIL | Java - OOP 특징 : 3.다형성
상단으로

티스토리툴바