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 |