11/23 수업 (18회차) _ 다형성 예제 / Vector 클래스 / 추상 클래스
** 예제 1123 (다형성) **
class Parent4{
int x = 100;
void method() {
System.out.println("Parent4 method()...");
}
}
class Child4 extends Parent4{
int x = 200;
void method() {
System.out.println("x = " + x);
System.out.println("super.x = " + super.x);
System.out.println("this.x = " + this.x);
}
}
public class MySample1123 {
public static void main(String[] args) {
// 다형선 - 참조형변수와 인스턴스 연결
// 다형성 _ 부모타입의 참조변수로 자식의 객체를 만든다.
Parent4 p = new Child4();
Child4 c = new Child4();
System.out.println("p.x = "+ p.x); //인스턴스 변수는 참조(잠조형변수=부모의 인스턴스변수)하는 값이 찍힌다. p.x = 200
p.method();
System.out.println("c.x = " + c.x);
c.method();
//Parent p = new Child();
//인스턴스 변수
//부모에게 있고 자식에도 있으면 -> 부모꺼 실행
//부모에게 있고 자식에게 없으면 -> 부모꺼 실행
//부모에는 없고 자식에게 있으면 -> 오류2
//메소드
//부모에게 있고 자식에도 있으면 -> 자식꺼 실행 (메소드 오버라이딩)
//부모에게 있고 자식에게 없으면 -> 부모꺼 실행
//부모에는 없고 자식에게 있으면 -> 오류2
}
}
** 예제 1123_2 (다형성) **
class Product2{
int price; //제품가격
int bonusPoint; //제품구매시 제공 보너스 점수
Product2(int price){
this.price = price;
bonusPoint = (int)(price / 10.0); //제품가격의 10퍼센트 적용
}
}
class Tv3 extends Product2{
Tv3(){
super(900);
}
public String toString() {
return "Tv";
}
}
class Computer2 extends Product2{
Computer2(){
super(500);
}
public String toString() {
return "Computer";
}
}
class Buyer{
int money = 10000; //보유금액
int bonusPoint = 0; //보유보너스
void buy(Product2 p) { //매개변수의 다형성
if (money < p.price) { //보유금액보다 사려는 가격비 비싼경우 못사게 처리
System.out.println("잔액 부족으로 물건을 살 수 없습니다.");
return; //프로그램 끝
}
money -= p.price; //this.money = this.money - p.price;
bonusPoint += p.bonusPoint; //this.bonusPoint = this.bonusPoint + p.bonusPoint
System.out.println(p + "을(를) 구매하셨습니다.");
}
}
public class MySample1123_2 {
public static void main(String[] args) {
// 다형성 - 매개변수의 다형성
Buyer b = new Buyer();
System.out.println("현재 보유중인 현금은 " + b.money + "만원 입니다.");
Product2 p = new Tv3(); //Tv3 p = new Tv3(); 으로 해도 결과는 같음 (Buyer 클래스 buy메서드에 매개변수가 매개변수가 다형성)
b.buy(p); //b.buy(new Tv3()); -> main()메서드에서 구매제품에 대한 정보를 알 수 없음.
System.out.println("현재 구매한 가격은 " + p.price + "입니다.");
System.out.println("현재 남은 돈은 " + b.money + "만원 입니다.");
System.out.println("현재 보유중인 보너스 점수는 " + b.bonusPoint + "점 입니다.");
System.out.println("\n");
Product2 p2 = new Computer2();
b.buy(p2);
System.out.println("현재 구매한 가격은 " + p2.price + "입니다.");
System.out.println("현재 남은 돈은 " + b.money + "만원 입니다.");
System.out.println("현재 보유중인 보너스 점수는 " + b.bonusPoint + "점 입니다.");
}
}
** 예제 1123_3 (다형성 - 객체를 배열로) **
class Product3{
int price;
int bonusPoint;
Product3(int price){
this.price = price;
this.bonusPoint = (int)(price*0.1);
}
}
class Tv4 extends Product3{
Tv4(){
super(100);
}
public String toString() {
return "Tv";
}
}
class Computer3 extends Product3{
Computer3(){
super(300);
}
public String toString() {
return "컴퓨터";
}
}
class Audio extends Product3{
Audio(){
super(50);
}
public String toString() {
return "오디오";
}
}
class Buyer2{
int money = 1000;
int bonusPoint = 0;
Product3[] item = new Product3[10];
int cnt = 0; //배열에 사용될 카운트
void buy(Product3 p) {
if(money < p.price) {
System.out.println("잔액 부족으로 물건을 살 수 없습니다.");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
item[cnt++] = p; //p - 객체의 시작 주소값
System.out.println(p + "을(를) 구매하셨습니다."); //각 클래스에 toString 오버라이딩 메서드 호출
int i;
for(i = 0 ; i < item.length ; i++) {
System.out.println("item[" + i + "] : " + item[i]);
}
}
void summary() {
int sum = 0; //구입물품 가격 합계
String itemList = ""; //구입물품 목록
int i;
//구입한 물품 총 가격과 목록
for(i = 0 ; i < item.length ; i++) {
if(item[i] == null)
break;
sum += item[i].price;
itemList += item[i].toString() + ", ";
}
System.out.println("구입하신 물품의 총 금액은 " + sum + "만원 입니다.");
System.out.println("구입하신 제품은 "+ itemList + "입니다.");
System.out.println("구입하신 제품의 총 보너스 점수는 " + bonusPoint + "점 입니다.");
}
}
public class MySample1123_3 {
public static void main(String[] args) {
// 다형성 - 객체를 배열로
Buyer2 b = new Buyer2();
b.buy(new Tv4());
b.buy(new Computer3());
b.buy(new Audio());
b.summary();
}
}
** Vector 클래스 **
- 자바의 배열은 고정 길이를 사용함. 즉, 배열이 한번 생성되면 배열의 길이를 증가하거나 감소 할 수 없다는 단점이 있음. (배열복사 말고)
- Vector클래스는 가변길이의 배열이라고 할 수 있음. (내부적으로 배열복사)
- 즉 Vector클래스는 객체에 대한 참조값을 저장하는 배열이므로 다양한 객체들이 하나의 Vectoer에 저장될 수 있고 길이도 필요에 따라 증감할 수 있다는 점이 배열과 다른 점이다.
.Vector 클래스의 생성자
Vector 클래스의 생성자 | 설 명 |
Vector() | 10개의 데이터를 저장할 수 있는 길이의 객체를 생성한다. 저장공간이 부족한 경우 10개씩 증가한다. |
Vector(int size) | size 개의 데이터를 저장할 수 있는 길이의 객체를 생성한다. 저장공간이 부족할 경우 size개씩 증가한다. |
Vector(int size, int incr) | size 개의 데이터를 저장할 수 있는 길이의 객체를 생성한다. 저장공간이 부족한 경우 incr개씩 증가한다. |
. Vetor 클래스의 주요 메서드
메서드 / 생성자 | 설 명 |
Vector() | 10개의 객체를 저장할 수 있는 Vector인스턴스를 생성한다. 10개이상의 인스턴스가 저장되면, 자동적으로 크기가 증가된다. |
boolean add(Object o) | Vector에 객체를 추가한다. 추가에 성공하면 결과값으로 true, 실패하면 false를 반환한다. |
boolean remove(Object o) | Vector에 객체를 제거한다. 제거에 성공하면 결과값으로 true, 실패하면 false를 반환한다. |
boolean isEmpty(Object o) | Vector가 비어있는지 검사한다. 비어있으면 결과값으로 true, 비어있지 않으면 false를 반환한다. |
boolean get(int index) | 저장된 위지(index)의 객체를 반환한다. 반환타입이 Object타입이므로 적절한 타입으로의 형변환이 필요하다. |
int size() | Vetor에 저장된 객체의 개수를 반환한다. |
** 예제 1123_4 **
import java.util.Vector;
class Buyer3{
int money = 1000;
int bonusPoint = 0;
Vector item = new Vector();
void buy(Product3 p) {
System.out.println("vector size() : " + item.size());
if(money < p.price) {
System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
item.add(p);
System.out.println(p + "을(를) 구매하셨습니다.");
}
void summary() {
int sum = 0;
String itemList = "";
int i;
Product3 p = null;
if(item.isEmpty() == true) { //if(item.size()==0)
System.out.println("구입한 물건이 없습니다.");
return;
}
for(i = 0 ; i < item.size() ; i++) {
// p = (Product3)item.get(i); //p == item.get(i) ???
sum += p.price;
itemList += (i == 0) ? p : ("," + p) ; //p + ", ";
}
System.out.println("구입한 총 금액 " + sum + "만원 입니다.");
System.out.println("구입한 물품은 " + itemList + "입니다.");
}
//환불
void refund(Product3 p) {
if(item.remove(p)) {
money += p.price;
bonusPoint -= p.bonusPoint;
System.out.println(p + "을(를) 반풍하셨습니다.");
}
else {
System.out.println("해당제품이 없습니다.");
}
}
}
public class MySample1123_4 {
public static void main(String[] args) {
// Vector() 클래스
Buyer3 b = new Buyer3();
Tv4 t = new Tv4();
Computer3 com = new Computer3();
Audio audio = new Audio();
b.buy(t);
b.buy(com);
b.buy(audio);
b.summary();
System.out.println("\n");
//환불
b.refund(com);
b.summary();
b.refund(com); //이미 삭제된 상품이므로 vector에 없음. 오류발생
}
}
** 추상클래스 (abstract class) **
- 하나 이상의 추상 메소드를 포함하는 클래스를 의미함
- 추상메소드 : 자식클래스에서 반드시 오버라이딩 해야만 사용할 수 있는 메소드
- 반드시 사용되어야 하는 메소드를 추상클레스에 추상메소드로 선언을 하면, 이 클래스를 상속받는 모든 클래스에서 이 추상 메소드를 반드시 재정의 해야함
abstract class 클래스 이름 {
...
abstract 반환타입 메소드이름();
...
}
- 추상클래스는 추상메소드를 포함하고 있다는 점 이외에는 일반 클래스와 모든점이 같다. 즉 생성자와 변수, 일반 메소드도 포함 할 수 있음.
** 예제 abs패키지 _ 1123_5 **
package abs;
abstract class Animal{
int num;
void numChk() {
System.out.println("num : " + num);
}
abstract void cry(); //추상클래스에는 추상메서드가 있어야한다.
}
class Cat extends Animal{
void cry() { //추상클래스에 있는 추상메소드 오버라이딩 한 것. but 상속받는 클래스에서 오버라이딩 할 때는 abstarct 쓰지 않는다.
System.out.println("야오야옹");
}
}
class Dog extends Animal{
void cry() {
System.out.println("멍멍....");
}
}
public class MySample11223_5 {
public static void main(String[] args) {
// 추상클래스
//Animal a = new Animal(); //추상클래스는 인스턴스를 생성할 수 없음.(객체생성 불가)
Cat c = new Cat(); //Animal c = new Cat(); 가능
Dog d = new Dog(); //Animal d = new Dog(); 가능
c.cry();
d.cry();
}
}
** 예제 abs패키지 _ 1123_6 (포켓몬) **
package abs;
abstract class Pokemon
{
private String name;
// Pokemon(){
//
// }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
abstract void attack(); //공격
abstract void sound(); //소리
}
class Pikachu extends Pokemon{
Pikachu(){
super.setName("피카츄");
}
void attack() {
System.out.println("전기공격");
}
void sound() {
System.out.println("피카피카");
}
}
class Spuirtle extends Pokemon{
Spuirtle(){
setName("꼬부기");
}
void attack() {
System.out.println("물뿌리기 공격");
}
void sound() {
System.out.println("꼬북꼬북");
}
}
public class MySample1123_6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//추상클래스
Pikachu p1 = new Pikachu();
System.out.println("포켓몬 이름은 " + p1.getName());
p1.attack();
p1.sound();
Spuirtle s1 = new Spuirtle();
System.out.println("포켓몬 이름은 " + s1.getName());
s1.attack();
s1.sound();
}
}
** abs2 패키지 _ 추상클래스 상속 _ Animal 클래스 / Bird 클래스 / Cat 클래스 / Dog 클래스 **
package abs2;
public abstract class Animal {
//동물이름
protected String name; //private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//어떻게 우는지
public abstract String getCry();
//어떻게 움직이는지
public abstract String getMove();
//무엇을 먹는지
public abstract String getFood();
//출력
public abstract void print();
}
* class Bird *
package abs2;
public class Bird extends Animal{
//생성자는 이름(name)을 매개변수로 하는 것과 매개변수가 4개로 생성자를 각각 정의함.
//이름 : name, 울음 : 짹짹, 움직임 : 날아다닌다, 음식 : 벌레
private String cry;
private String move;
private String food;
Bird(String name){
this(name, "짹짹", "날아다닌다", "애벌레");
}
Bird(String name, String cry, String move, String food){
//super(); //생략되어있다.
setName(name); //super. 생략
setCry(cry);
setMove(cry);
setFood(food);
}
public String getCry() {
return this.cry;
}
public void setCry(String cry) {
this.cry = cry;
}
public String getMove() {
return this.move;
}
public void setMove(String move) {
this.move = move;
}
public String getFood() {
return this.food;
}
public void setFood(String food) {
this.food = food;
}
public void print() {
System.out.println("Bird [name : "+ getName() + ", cry : " + getCry() + ", move : " + getMove() + ", food : " + getFood() + "]");
}
}
* class Cat *
package abs2;
public class Cat extends Animal{
private String cry;
private String move;
private String food;
Cat(String name){
this(name, "야옹", "걸어댜녀요", "생선");
}
Cat(String name, String cry, String move, String food){
setName(name);
setCry(cry);
setMove(move);
setFood(food);
}
public String getCry() {
return this.cry;
}
public void setCry(String cry) {
this.cry = cry;
}
public String getMove() {
return this.move;
}
public void setMove(String move) {
this.move = move;
}
public String getFood() {
return this.food;
}
public void setFood(String food) {
this.food = food;
}
public void print() {
System.out.println("Cat [name : " + getName() + ", cry : " + getCry() + ", move : " + getMove() + ", food : " + getFood() + "]");
}
}
* class Dog *
package abs2;
public class Dog extends Animal {
//멍멍, 촐랑촐랑 뛴다. 사료
private String cry;
private String move;
private String food;
Dog(String name){
this(name, "멍멍", "촐랑촐랑 뛴다", "사료");
}
Dog(String name, String cry, String move, String food){
setName(name); //super.name = name;
setCry(cry);
setMove(move);
setFood(food);
}
public String getCry() {
return this.cry;
}
public void setCry(String cry) {
this.cry = cry;
}
public String getMove() {
return this.move;
}
public void setMove(String move) {
this.move = move;
}
public String getFood() {
return this.food;
}
public void setFood(String food) {
this.food = food;
}
public void print() {
System.out.println("Dog [name : " + getName() + ", cry : " + getCry() + ", move : " + getMove() + ", food : " + getFood() + "]");
}
}
package abs2;
public class AnimalMain {
public static void main(String[] args) {
// 추상클래스 메인
Dog dog = new Dog("재롱이");
Cat cat = new Cat("나비");
Bird bird = new Bird("짹짹이");
cat.print();
System.out.println();
dog.print();
System.out.println();
bird.print();
System.out.println();
cat.setCry("어흥");
cat.print();
System.out.println();
bird.setMove("펄럭펄럭");
bird.print();
System.out.println();
dog.setFood("건조 닭고기");
dog.print();
}
}
** 실습 abs1 패키지 **
/*
*추상클래스
*문제)Animal클래스를 추상클래스로 정의하고 이름(name), 나이(age) 변수를 정의하고 생성자(매개변수2개)를 통해 값 저장
* 이동하는 메서드(move)로 먹는 메서드(eat)로 정의하여 이동은 "이동한다", 먹는것은 "먹는다"로 출력함.
* 자식 클래스(Dog, Cat)에서 반드시 재정의 하도록 bark() 메서드로 짖는걸 구현함.
*출력예)이동한다.
* 멍멍
* 먹는다.
*
* 이동한다.
* 야옹
* 먹는다.
*/