본문 바로가기
java

22.11.11 상속, 다형성(Polymorphism), Override, Class 형변환

by SoulMania 2023. 2. 13.

221111.zip
0.12MB
ch07.zip
0.01MB
단원설명 및 tips.txt
0.00MB
설명.txt
0.02MB
송준호_1111.txt
0.00MB
중요한 개념!!!.PNG
0.09MB
추출.txt
0.02MB

사람은 동물이다

Human is an animal.

-> is a 관계 => 상속관계
a = 10;
Animal = Human
Animal 참조변수 = new Human();

Animal{
int age; 등
void sleep(){} 등
}

class Human extends {
int age; 등등등
void sleep(){} 등+
@Override
sound(){"말을 한다"}
write()

}


기계=new 기계
전화기=new 전화기
스마트폰=new스마트폰
클래스명 참조변수=new 클래스명()

int a;
a=10;
double b=a;

4바이트면 충분하지만 그거보다 큰8바이트 더블형에 저장이 될 수 있는 것과 비슷한 개념

기계 참조변수 =new 전화기
전화기 참조변수 =new 스마트폰
기계 참조변수=new 스마트폰

부모클래스타입의 참조변수1개에 여러개의 자식클래스의 객체가 담길 수 있다.
기계 참조변수=new 기계
기계 참조변수=new 스마트폰
기계 참조변수=new 전화기

--->상위 클래스에 없는 메소드는 사용할 수 없다.

참조변수.
부모 참변
show(Object str){

} --->모든 클래스의 부모가 Object이므로 이런방식으로 사용도 가능
show(String str){

}

동물=포유류
포유류=사람
동물=사람


Animal01
//타입-예) 개, 꾀꼬리
//무게-예) 5, 0.8
먹는다
움직인다
소리낸다

Dog01
지킨다(보호한다는 의미)
소리낸다

Bird
난다()
소리낸다()


person01
eat(){}
study(){}

Student01
play(){}
study(){}


Oracle Live Sql 로 연습

this() 예제 ch06 Car02, Car02_Main 22 11 07일짜 설명에도 있음

[학^^] [오후 5:02] SQL 추천사이트
https://www.w3schools.com/sql/default.asp
http://www.gurubee.net/oracle/sql


[학^^] [오후 5:04] DB는 깔끔한 삭제가 힘들 수 있으므로
수업시간에 다 같이 설치합니다
(향후 설치하는 날 노트북을 가져와서
강의실 데스크탑에서 설치할 때
동시에 설치하는 것도 바법)


인터페이스에 구현 객체를 대입하는 방법 (p.357~358)​

인터페이스는 생성자 따위!! 없다 ㅋㅋ

복습 꼭해야하겠다... 어휴.. 정신 없어...


package ch07;

public class Bird01_h extends Animal01_h {

//필드 //private 필드 데이터 상속안 받으면 이렇게 또 선언해주거나 getter setter를 지정
private String type;
private double weight;

//생성자
public Bird01_h(String type, double weight) { //매개변수 생성자
    this.type=type;
    this.weight=weight;
} 

public void fly() {
    System.out.println("경비견이다!!");
}

@Override
public String sound() {
    return "새소리 : 삐삐삐삐삐삐까까까까까!";
}

}


package ch07;

public class Dog01_h extends Animal01_h {

//필드

private String type;
private double weight;

//생성자
public Dog01_h(String type, double weight) { //매개변수 생성자
    this.type=type;
    this.weight=weight;
} 



public void protect() {
    System.out.println("경비견이다!!");
}

@Override
public String sound() {
    return "개소리 : 멍 멍 멍멍멍멍!!!!!!";
}

}


package ch07;

public class Animal01_h {

//필드
private String type;
private double weight;

// String a;

//생성자
public Animal01_h() {} //기본 생성자

public Animal01_h(String type, double weight) { //매개변수 생성자
    this.type=type;
    this.weight=weight;
} 


//메소드

//최상위 Animal01 에만 private로 필드데이터 선언하고 나머지 자식 클래스는 setter getter로  받아서 하고 싶지만 그냥 Dog01, Bird01에 필드데이터 각각 private로 선언!!!
//setter
public void setInfo(String type, double weight) {
    this.type=type;
    this.weight=weight;
}

//getter
public String getType() {
    return type;
}
public double getWeight() {
    return weight;
}




//먹는다
public void eat() {
    System.out.println("우걱우걱우걱!!!!");
}
//잔다
public void sleep() {
    System.out.println("잔다~~zzzzzzzzzzzzzzzzzzzzzzzzzz");
}
//소리낸다
public String sound() {
    return "어떤 동물의 소리 일까요?";
}

}


package ch07;

public class Animal01_Main_h {

public static void main(String[] args) {
    Animal01_h animal = new Animal01_h();
    animal.eat(); //먹는다
    animal.sleep(); //잔다
    System.out.println(animal.sound());//소리낸다

    System.out.println("-----------------------------------------------------------------------");

    Dog01_h dog = new Dog01_h("포유류", 8.4);
    dog.protect();
    System.out.println(dog.sound());

    System.out.println("-----------------------------------------------------------------------");

    Bird01_h bird = new Bird01_h("조류", 1.1);
    bird.fly();
    System.out.println(bird.sound());







}

}



package ch07;

/매개변수의 다형성 (p.321~323)
-매개변수가 클래스 타입일 경우
-해당 클래스의 객체 대입이 원칙이나 자식 객체 대입하는 것도 허용
-자동 타입 변환
-매개변수의 다형성
/

//이 클래스는 동물Animal01클래스를 상속받는 클래스이다
public class Bird01 extends Animal01 {
//보이지않지만 부모클래스의 필드와 메서드 존재
//단, private필드와 private메서드 제외

//필드
private String type;    //타입-예) 개, 꾀꼬리
private double weight;    //무게-예) 5, 0.8 

//생성자
public Bird01(){}
public Bird01(String type,double weight) {
    this.type=type;
    this.weight=weight;        
}

//메서드
//난다
public void fly() {
    System.out.println("Bird01-fly()호출");
}

//소리낸다(클래스타입 매개변수명)
//Animal클래스의 메서드를 재정의
@Override

// public void sound(String o) {
public void sound(Object o) {
System.out.println("Bird01의 sound():"+o);
}
}


package ch07;

/매개변수의 다형성 (p.321~323)
-매개변수가 클래스 타입일 경우
-해당 클래스의 객체 대입이 원칙이나 자식 객체 대입하는 것도 허용
-자동 타입 변환
-매개변수의 다형성
/

//이 클래스는 동물Animal01클래스를 상속받는 클래스이다
public class Dog01 extends Animal01 {
//보이지않지만 부모클래스의 필드와 메서드 존재
//단, private필드와 private메서드 제외

//필드
private String type;    //타입-예) 개, 꾀꼬리
private double weight;    //무게-예) 5, 0.8 

//생성자
public Dog01() {}
public Dog01(String type,double weight) {
    this.type=type;
    this.weight=weight;        
}

//메서드
//지킨다(보호한다는 의미)
public void guard() {
    System.out.println("Dog01-guard()호출");
}

//소리낸다(클래스타입 매개변수명)
//Animal클래스의 메서드를 재정의
@Override

// public void sound(String o) {
public void sound(Object o) {
System.out.println("Dog01의 sound():"+o);
}

}


package ch07;

/매개변수의 다형성 (p.321~323)
-매개변수가 클래스 타입일 경우
-해당 클래스의 객체 대입이 원칙이나 자식 객체 대입하는 것도 허용
-자동 타입 변환
-매개변수의 다형성
/

//이 클래스는 동물클래스이다
public class Animal01 {
//필드
private String type; //타입-예) 개, 꾀꼬리
private double weight; //무게-예) 5, 0.8

//생성자
public Animal01() {}
public Animal01(String type,double weight) {
    this.type=type;
    this.weight=weight;
}

//메서드
//먹는다
public void eat() {}
//잔다
public void sleep() {}
//소리낸다(클래스타입 매개변수명)

// public void sound(String o) {
public void sound(Object o) {//오브젝트는 최상위라서 이것도 됨.
System.out.println(o);
}
}


package ch07;

/매개변수의 다형성 (p.321~323)
-매개변수가 클래스 타입일 경우
-해당 클래스의 객체 대입이 원칙이나 자식 객체 대입하는 것도 허용
-자동 타입 변환
-매개변수의 다형성
/

/*이 클래스는
Animal01-Dog01
Animal01-Bird01 들과의 실행클래스이다 */
public class Animal01_Main {

public static void main(String[] args) {
    //클래스 참조변수 = new 클래스명();
    Animal01 animal=new Animal01();
    animal.eat();
    animal.sound("동물소리");
    System.out.println();//빈줄

    System.out.println("-------------------------------------------------------------");

    System.out.println();//빈줄
    Dog01 dog=new Dog01();
    dog.guard();
    dog.sound("강아지 소리");
    System.out.println();//빈줄

    System.out.println("-------------------------------------------------------------");

    System.out.println();//빈줄
    Bird01 bird=new Bird01();
    bird.fly();
    bird.sound("새 소리");
    System.out.println();//빈줄

    System.out.println("-------------------------------------------------------------");

    System.out.println();//빈줄


    //부모클래스 참조변수=null;
    Animal01 ani=null;
    //참조변수=new 자식클래스명();
    ani=new Dog01(); //동물의 껍데기를 쓰고있는 강아지 
    ani.sound("왕왕");  //Dog01 의 메소드가 호출                                    => Bird01의 sound():왕왕
    ani.sound(new String("왕왕"));  //위에 것과 동일한 형태다...
    //--->sound는 오버라이딩 된 값 이라 마지막 Dog01 것 출력
    ani.sound(new Dog01());  //--->sound는 오버라이딩 된 값 이라 마지막 Dog01 것 출력         =>Dog01의 sound():ch07.Dog01@15db9742 //방금 new 해서 출력한것
                                                                                //개의 참조변수에 Dog01에 대한 객체 주소지가 들어가서 출력되는것.
    ani.sound(dog);            //                                                =>기존에 new 했던 객체에 대한 주소지

    System.out.println("-------------------------------------------------------------");

    ani=new Bird01();
    ani.sound("쨱쨱");  //Bird01 의 메소드가 호출                                     => Bird01의 sound():짹짹
    ani.sound(new Bird01());  //Bird01 의 메소드가 호출                             => Bird01의 sound():ch07.Bird01@6d06d69c
                                                                                //새의 참조변수에 Bird01에 대한 객체 주소지가 들어가서 출력되는것. //방금 new 해서 출력한것
    ani.sound(bird);        //                                                =>기존에 위에서 new 했던 객체에 대한 주소지
    System.out.println();//빈줄
    System.out.println("-------------------------------------------------------------");
    System.out.println();//빈줄

    /*객체 타입 확인(instanceof) (p.326~329)​
     - 부모 타입이면 모두 자식 타입으로 강제 타입 변환할 수 있는 것 아님​
     - ClassCastException 예외 발생 가능​
    참조변수 instanceof 클래스명 */
    //부모클래스 참조변수 = new 자식클래스명();
    Animal01 animals = new Dog01();
    System.out.println("animals = new Dog01()면 : "+animals); //ch07.Dog01@70dea4e
    if(animals instanceof Dog01) {
        System.out.println("animals참조변수에는 Dog01클래스의 객체주소가 들어있다");
    }else {
        System.out.println("animals참조변수에는 Dog01클래스의 객체주소가 들어있지 않다");
    }

    System.out.println("-------------------------------------------------------------");

    animals = new Bird01(); //자동클래스 형변환(up class casting): 하위 클래스 -> 상위클래스 변환    //이걸 해야 밑에 강제 형변환이 된다.
    System.out.println("animals = new Bird01()면 : "+animals); //ch07.Bird01@5c647e05
    if(animals instanceof Dog01) {
        System.out.println("animals참조변수에는 Dog01클래스의 객체주소가 들어있다");
        //animals.fly(); //-->강아지 객체주소가 있고 애니멀즈에도  메소드도 없다.
        ((Dog01)animals).guard(); // -->가드를 실행할 수 있는 Dog로 강제 형변환을 한 다음에 가드를 호출!!! 클래스간의 강제 형변환 //
        //강제 클래스 형변환(down class Casting),  상위 클래스 -> 하위클래스 변환 
        //다운캐스팅을 한 후 -> 여기에서는 Dog01클래스로 변환 후 -> Dog01클래스.guard()호출 
        //근데 여기서는 버드01 객체주소가 들어있으므로 출력 안된다.

    }else if(animals instanceof Bird01){
        System.out.println("animals참조변수에는 Bird01클래스의 객체주소가 들어있다");

        ((Bird01) animals).fly(); //이클립스가 자동으로 강제형변환 해버린다.
    }

    /*★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    만약 Object o를 Animal01 o로 바꿔도 되는데 그러면  ani.sound("왕왕"); 이것이 출력이 안된다. 왜냐하면 Animal01 클래스와 String은 별개의 관계이기 때문에.즉 상속관계가 아니다.
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★*/


}

}



package ch07;

/추상 클래스 개념​
추상(abstract)​
실체들 간에 공통되는 특성을 추출한 것​
예1: 새, 곤충, 물고기 동물 (추상)​
예2: 삼성, 현대, LG  회사 (추상)​
/

/추상 클래스(abstract class)​
- 실체 클래스들의 공통되는 필드와 메소드 정의한 클래스​
- 추상 클래스는 실체 클래스의 부모 클래스 역할 (단독 객체 X) ​
/

public abstract class Person01 {
//필드
//생성자
Person01() {//생략하면 기본생성자 생성.
System.out.println("기본생성자 Person01()호출");
}
//메소드
//[접근제한자][제어자] 리턴유형 메소드명(매개변수리스트){} //{} 컬리브레이스는 구현부라고 한다.
public void eat() {
System.out.println("Person01-eat()");
}
//void study();
//This method requires a body instead of a semicolon 앱스트랙트 안넣으면 세미콜론 에러..

abstract void study(); //abstract  는 제어자 자리에 들어간다.
// *The abstract method study in type Person01 can only be defined by an abstract class*
//위와 같은 에러를 없애려면 클래스 선언부 제어자에도 abstract를 선언해야한다. ---> public abstract class Person01 {
//추상클래스가 있어야 추상 메소드 사용가능하다는 뜻.
//하지만 추상클래스로 선언하더라도 일반메소드만으로 구성 될 수 있다.

}


package ch07;

//Person01의 상속받은 하위클래스이다.
//The type Student01 must implement the inherited abstract method Person01.study()
public class Student01 extends Person01 {

//필드


//생성자 //생략하면 기본생성자 Person01(){} 
Student01(){
    super();//부모클래스 생성자 호출 /// 기본적으로 호출된다.  //반드시 생성자 첫번쨰 줄에서 작성!!
    System.out.println("Student01() 생성자 호출");
}
//this(), super() 호출 주의점과 동일
//1. 반드시 생성자내에서 호출
//2. 반드시 첫 번째 줄에서 작성
//=> 반드시 생성자내 첫 번째 줄에서 작성



//메소드

public void play() {
    System.out.println("즐겁게 논다.");
}


@Override
public void study() {  //-->실체클래스의 메소드 정의할때는 무조건 오버라이드!!!!
    System.out.println("복습, 암기, 코딩으로 공부한다.");
}

//부모클래스가 추상클래스 선언 후에 추상 메소드를 선언하면 자식클래스에서 그 메소드를 무조건 작성해야한다. 추상클래스의 하위클래스는 무조건 추상메소드를 오버라이딩 하라는 뜻이기도하다.
//자식클래스에는 abstract를 붙이면 안된다. 추상적인게 아니라 구체적으로 작성을 해야하므로

}


package ch07;

//이 클래스는 추상클래스에 관한 실습용 클래스이다.
//추상클래스는 ch07.Person01이다.
public class Person01_Main {

public static void main(String[] args) {
    //Person01 p = new Person01(); //-->>이런형태로 다이렉트 객체생성은 못한다.기본생성자를 호출할수없다는 말이기도하다.우회방법 을 써야한다.
    //기본생성자는 존재하지만 호출할 수 없다!!!!
    // Cannot instantiate the type Person01
    // Person01클래스는 인스턴스화 할 수 없다는 에러 -->Person01 클래스의 객체를 생성하지 못한다는 뜻.
    // 왜냐하면 New 연산자로 객체 생성하지 못하고 상속 통해 자식 클래스만 생성 가능

    //Person01을 상속받는 Student01객체 생성
    Student01 s = new Student01();
    //★★★★★★★★★★★★★ 상위클래스가 있는 자식클래스의 생성자를 호출하면
    //내부적으로 상위클래스의 기본생성자가
    //자동으로 호출된다
    //부모생성자 호출 -> 자식생성자호출 순

    s.play();
    s.study();
    /*기본생성자 Person01()호출
    즐겁게 논다.
    복습, 암기, 코딩으로 공부한다.*/

    /*(위와같이 출력되는 것이 상속이라서가 아니다. 생성자는 상속되지 않는다.
    하지만 기본생성자에 super();가 기본적으로 묵시적으로 호출되기 때문에 Person01의 생성자 프린트문이 호출되는 것.*/

    s.eat(); //상속관계 부모클래스라 호출 가능. 부모로부터 메소드를 물려받기 때문에 호출가능. 따라서 추상클래스는 상위클래스 말고 하위클래스 객체생성해서 이런식으로 상속을 통해서 메소드를 호출해야한다.











}

}