일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- opener
- 파일 호출
- session.setAttribute
- session.getAttribute
- static
- \
- 버리자
- 팝업창
- Alert
- scanner
- 데이터사이언스
- 미래직장
- target
- javaBeans
- session.removeAttribute
- BEANS
- 파일호출
- iframe
- Import
- 향상된 for문
- 동기부여
- 빈즈
- 자바빈즈
- 동기 부여
- 페이지이동
- 로그인화면
- ;
- 영감
- "
- 페이지 이동
- Today
- Total
갈림길 이정표
[7. 상속] 본문
7.0 포함관계 (has a)
package pack1;
public class PohamHandle {
//자체적으로는 의미 없음 (부품), 다른 클래스의 멤버로 사용할 목적
int quantity; //회전량 +오른쪽, -왼쪽, 0 직진
public PohamHandle() {
quantity = 0;
}
String leftTurn(int q) { //지역변수
quantity = q;
return "좌회전";
}
String rightTurn(int q) {
quantity = q;
return "우회전";
}
String straight(int q) {
quantity = q;
return "직진";
}
// 따로 만든 이유 PohamHandle class를 다른 class에도 활용하고 싶어서 (재활용)
}
package pack1;
public class PohamCar { //완성차 class
int speed = 0;
String ownerName, turnShow; //모두 PohamCar의 멤버
//기본값 = null
PohamHandle handle;
//외부 클래스를 멤버필드로 사용: 클래스의 포함관계(has a)
//객체 선언 안한 상태라 주소 없음
public PohamCar() {
}
public PohamCar(String name) {
ownerName = name; //외부 값으로 받을 수 있음
handle = new PohamHandle(); // new class를 class 안에서 선언 (instance)
}
void turnHandle(int q) { //회전량을 인수로 받을 거임 //마치 자신의 멤버인냥 불러옴
if(q > 0) turnShow = handle.rightTurn(q); //객체 생성하는 데 PohamHandle class에서 rightTurn멤버 부르고
if(q < 0) turnShow = handle.leftTurn(q); //int q값을 받으면 String으로 받아들이기 때문에 "우회전"을 받아들여
if(q == 0) turnShow = handle.straight(q); //String 데이터 타입(기본값 null) turnShow 에 치환
//PohamCar 가 아닌 PohamHandle값 참조
}
}
package pack1;
public class PohamCarMain {
public static void main(String[] args) {
//class의 포함관계 연습
PohamCar tom = new PohamCar("톰"); //PohamHandle 은 필요없음
tom.turnHandle(20);
System.out.println(tom.ownerName + "의 회전량은 " + tom.turnShow + " " + tom.handle.quantity); //tom.quantity 바로 갈 수 없음
tom.turnHandle(-10);
System.out.println(tom.ownerName + "의 회전량은 " + tom.turnShow + " " + tom.handle.quantity); //tom.quantity 바로 갈 수 없음
tom.turnHandle(0);
System.out.println(tom.ownerName + "의 회전량은 " + tom.turnShow + " " + tom.handle.quantity); //tom.quantity 바로 갈 수 없음
System.out.println();
PohamCar kildong = new PohamCar("길동"); //또다른 instance 선언
kildong.turnHandle(0);
System.out.println(kildong.ownerName + "의 회전량은 " + kildong.turnShow + " " + kildong.handle.quantity);
//구두점(.)이 두 개면 포함 관계구나라고 알면 됨
//out은 파란 기울임체 = static
//API(Application Programming Interface) document: 전문가와 개발자(사용자) 사이 소통을 위한 설명 문서
//https://docs.oracle.com/en/java/javase/14/docs/api/index.html
//https://docs.oracle.com/javase/8/docs/api/
}
}
7.1 상속개념 (is a) .......................................................................................................................
7.2 클래스 상속.....................................................................................................................
7.3 부모 생성자호출 '
7.4 메소드 재정의...............
7.5 final 클래스와 final 메소드 ........................................................................................
7.6 protected 접근 제한자 ...........................................................................................
7.7 타입 변환과 다형성.........................................................................................................
7.8 추상클래스.....................................................................................................................
package pack2;
public class GrandFa {
private int nai = 80;
public String gabo = "상감청자";
protected String gahun = "착하게 살자"; //자식class의 존재를 암시
public GrandFa() { //class[대문자]명 () 는 생성자
System.out.println("할아버지 생성자");
}
public GrandFa(int nai) { //public: 다른 package 내 호출 가능
this(); //자신의 또 다른 생성자를 호출 (다른 statement 보다 먼저 적기)
this.nai = nai; //자기 멤버 호출 // overloading 생성
//생성자 호출 방법: ①new ②다른 생성자로 호출
}
protected String say() { //변수[소문자]()는 메소드
//protected: 다른 package 내에선 자식 class이라면 호출 가능!
return "할아버지 말씀: 자바에 미쳐라";
}
void eat() { //defualt: 같은 package 내 호출 가능
System.out.println("밥은 맛있게...");
}
public int getNai() { //final 붙이면 Father class의 getNai가
return nai; //왜냐면 override 불가이기 때문 (수정불가)
}
}
package pack2;
public class Father extends GrandFa{
//extend = (단일)상속: private 멤버를 제외한 나머지 자원을 자기자식에게 제공!(자원의 재활용)
private int nai = 55; //캡슐화 (private 으로 데이터 숨김)
public String gabo = "꽃병"; //부모 (GrandFa) class 멤버와 같은 멤버 필드 (은닉화: 자식에 의해 부모의 멤버가 숨어버림) = 덮어쓰기(?)
private final int house = 1; //Father class 고유 멤버 (final = 수정 불가)
//부모보다는 자식이 멤버 수가 더 많음
//멤버 가짓 수는 자식이 많지만 상속 개념에서 큰 것은 부모
public Father() {
super(); //this:자신의 생성자 호출, super: 부모 생성자 호출, 생략 가능
// 항상 먼저 //생성자 overloading 한 상태에서는 생략 불가 (그냥 습관적으로 적어라!)
System.out.println("아버지 생성자~~~~~");
}
public Father(int n) { //생성자를 여러개 만드는 행위 overloading
//괄호안은 argument
super(n); //부모class 생성자 (argument) 중 데이터 타입이 같은 int nai 를 호출
System.out.println("아버지 생성자~~~~~");
}
@Override //annotation(주석) - 밑에 있는 정보가 override 된 것임을 알림 (가독성 위해: 개발자 간 소통)
public int getNai() { //method override(재정의) -> 다형성 (내용 다름)
// public int getNa() { -> 한 글자만 차이나도 자식 고유 메소드로 되버림
System.out.println("자식이 부모 메소드를 재정의 함");
return nai; //부모와 자식이 똑같은 메소드를 가지고 있는 것 (내용은 달라도 메소드명은 같아야 됨)
}
public int getHouse() { //getH까지만 쓰고 ctrl+space bar 눌러도 자동 생성
return house;
}
public void showData() {
String gabo = "컴퓨터"; //찾는 순서: showData 안의 gabo -> (없으면) Father class 의 gabo -> (없으면) GrandFa class의 gabo
System.out.println("가보: " + gabo);//찾는 순서: showData 안의 gabo -> (없으면) Father class 의 gabo -> (없으면) GrandFa class의 gabo
System.out.println("가보: " + this.gabo);//찾는 순서: Father class 의 gabo -> (없으면) GrandFa class의 gabo
System.out.println("가보: " + super.gabo);//찾는 순서: GrandFa class의 gabo
// super가 가장 상위, 그외 부모 class 위 class를 바로 호출 불가!
getNai();
this.getNai();
super.getNai();
}
}
package pack2;
public class Me extends Father {
public Me() {
System.out.println("재생성자임을 선언 하노라");
}
@Override
public void showData() {
System.out.println("Me의 showData");
}
}
//final class(상속 불가[subclass의 작성 불가)
//final method(오버라이딩 불가)
//final 멤버 변수 (값 변경 불가)
package pack2;
public class MyFamily {
public static void main(String[] args) {
//상속 (is a 관계)
GrandFa gr = new GrandFa(); //new class[대문자](): 객체(instance) 생성
//기본 나이값 80
//생성자 호출 방법: ①new ②다른 생성자로 호출
System.out.println("가보: " + gr.gabo);
System.out.println("가훈: " + gr.gahun);
// System.out.println("나이: " + gr.nai);
System.out.println(gr.say());
gr.eat();
System.out.println("할아버지 나이: " + gr.getNai());//public: 다른 package 내 호출 가능
System.out.println("------------");
GrandFa gr2 = new GrandFa(82); //나이값이 있는 또다른 gr2
System.out.println(gr2.say());
gr2.eat();
System.out.println("할아버지2 나이: " + gr2.getNai());
System.out.println("\nFather------------");
Father fa = new Father();
// fa. 그냥 ctrl + space bar 하면 superclass(java.Object)만 나옴
//extend 부모class한 후면 상속됨(private 멤버 빼고 복제)
System.out.println("가보: " + fa.gabo); //Father class에서 찾아 (지역) 없으면 GrandFa class에서 찾아 (상위 개념)
System.out.println("가훈: " + fa.gahun);
System.out.println(fa.say());
fa.eat();
System.out.println("아버지 나이 : " + fa.getNai());
System.out.println("집은 " + fa.getHouse());
fa.showData(); //찾는 순서: showData 안의 gabo -> (없으면) Father class 의 gabo -> (없으면) GrandFa class의 gabo
// System.out.println();
// Father fa2 = new Father(77);
// System.out.println("아버지2 나이 : " + fa2.getNai());
System.out.println("\nMe------------");
Me me = new Me();
// 할아버지 생성자
// 아버지 생성자~~~~~
// 재생성자임을 선언 하노라
System.out.println("가보: " + me.gabo); //Father class에서 찾아 (지역) 없으면 GrandFa class에서 찾아 (상위 개념)
// 가보: 꽃병(Father class)
System.out.println("가훈: " + me.gahun);
// 가훈: 착하게 살자(GrandFa class) ->Father class를 통해 상속 가능
System.out.println(me.say());
// 할아버지 말씀: 자바에 미쳐라
System.out.println(me.getHouse());
// 1(Father class)
me.eat();
// 밥은 맛있게...(GrandFa class)
}
}
package pack2;
//import java.lang.Object; (모든 클래스 기본)
public class MyObj { // extends Objects (모든 클래스 기본)
public MyObj() {
System.out.println("MyObj");
}
@Override
public String toString() { //toString의 기능 바꿈 (다형성)
return "자격증만세";
}
public static void main(String[] args) {
MyObj obj = new MyObj();
System.out.println(obj); //-> 주소가 찍히도록 기본 세팅
System.out.println(obj.toString()); //-> 주소가 찍히도록 기본 세팅 (생략)
}
}
package pack2;
public class Dog { //개과의 파생 클래스(sub class)를 위한 super class
private String name = "댕댕이";
public Dog() {
// TODO Auto-generated constructor stub
}
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String callName() {
return "종류: " + name;
}
public void print() {
System.out.println(name + " : 땅 위에 산다");
}
}
package pack2;
public class DogMain {
public static void main(String[] args) {
Dog dog = new Dog();
dog.print();
System.out.println(dog.callName());
System.out.println("---------------");
HouseDog hd = new HouseDog("집개");
hd.print();
hd.show();
System.out.println(hd.callName());
System.out.println("---------------");
WolfDog wd = new WolfDog("늑대");
wd.print();
System.out.println(wd.callName());
wd.display();
System.out.println("^^^^^^^^^^^^^^^");
WolfDog bushdog = wd; //(WolfDog타입) bushdog (wd주소 참조) = 값이 같다
bushdog.print();
System.out.println();
Dog dog2 = hd; //subclass 객체(wd = Dog 의 subclass)주소를 superclass에 치환할 수 있다 (Promotion)
//자식객체의 주소를 부모 개체에 치환 (Promotion)
dog2.print();
// dog2.display(); //superclass 타입 변수를 subclass 주소 참조하여 치환
//err. 불간섭의 원칙(overriding 된 메소드만 가능)(고유메소드는 부를 수 없음)
System.out.println();
dog2 = wd;
dog2.print(); //동일한 statement로 다양한 결과를 얻을 수 있음 (다형성 polymorphism)
System.out.println();
// WolfDog bushdog2 = dog2;//err.부모 객체의 주소를 자식 개체에 치환은 불가 (원래 부모의 성격을 가졌기 때문?)
WolfDog bushdog2 = (WolfDog)dog2; //Casting (자식의 주소를 가질 수 있다면 가능)
bushdog2.print();
// 자주쓰는 기능
System.out.println("%%%%%%%%%%%%%%%%%");
Dog coyote = new Dog("코요테");
coyote.print();
System.out.println();
coyote = bushdog;
coyote.print();
System.out.println();
coyote = hd;
coyote.print();
}
}
package pack2;
public class HouseDog extends Dog{
private String where = "집";
public HouseDog(String name) {
super(name);
}
public void show() {
System.out.println("어디 사니?" + where);
}
@Override
public void print() {
System.out.println("...");
System.out.println(getName() + " : " + where + "에 산다");
System.out.println("~~~");
}
}
package pack2;
public class WolfDog extends Dog{
private String where = "산";
public WolfDog(String name) {
super(name);
}
public WolfDog(String name, String where) { //어디 변수에 값을 대입
super(name);
this.where = where;
}
@Override
public void print() { //변수에 값 대입 없이 그냥 메소드 실행
System.out.println("늑대 만세!~~~");
System.out.println(getName() + " : " + where + "에 산다");
}
public void display() {
print(); //늑대 만세!~~~ \n 늑대 : 산에 산다
this.print();
super.print();
}
}
package pack2;
//다형성(Polymorphism) 연습
public class PolyCar {
protected int speed = 30; // protected : 자식이 있어
public PolyCar() {
System.out.println("난 자동차야!~~~");
}
public void dispData() {
System.out.println("속도: " + speed);
}
public int getSpeed() {
return speed;
}
}
package pack2;
public class PolyBus extends PolyCar{
private int passenger = 10;
public void show() { //부모 객체 변수 이름으로 호출 당할 수 없음
System.out.println("버스 show"); //PolyBus 의 고유 메소드
}
@Override //부모 객체 변수 이름으로 호출 당할 수 있음
public void dispData() {
System.out.println("버스 승객은 " + passenger);
System.out.println("버스 속도은 " + speed); //super. 또는 this. 쓰지마
}
}
package pack2;
public class PolyTaxi extends PolyCar{
private int passenger = 2;
public PolyTaxi() {
System.out.println("난 택시라고 해");
}
@Override //부모 객체 변수 이름으로 호출 당할 수 있음
public void dispData() {
System.out.println("택시를 이용하고 있는 인원 수 " + passenger);
}
}
package pack2;
public class PolyMain {
public static void main(String[] args) {
//다형성 연습
PolyCar car1 = new PolyCar(); //난 자동차야!~~~
PolyBus bus1 = new PolyBus(); //난 자동차야!~~~
PolyTaxi taxi1 = new PolyTaxi(); //난 자동차야!~~~ \n 난 택시라고 해
car1.dispData(); //속도: 30
System.out.println(car1.getSpeed());//30
System.out.println("======");
bus1.dispData(); //버스 승객은 10 \n 버스 속도은 30
bus1.show(); //버스 show
System.out.println(bus1.getSpeed());//30 (superclass참조)
System.out.println("======");
taxi1.dispData(); //택시를 이용하고 있는 인원 수 2
System.out.println(taxi1.getSpeed());//30 (superclass참조)
System.out.println("\n************************");
PolyCar car2 = new PolyBus(); //[Promotion] subclass를 superclass에 치환
//난 자동차야!~~~
car2.dispData(); //버스 승객은 10 \n 버스 속도은 30 (PolyCar 아닌 PolyBus 참조!!!)
// car2.show(); //[불간섭의 원칙] subclass 고유메소드이므로 에러
System.out.println(car2.getSpeed());//30 (PolyBus에 메소드 없음-> PolyCar 참조)
PolyCar car3 = taxi1; //[Promotion] subclass를 superclass에 치환
car3.dispData(); //택시를 이용하고 있는 인원 수 2
System.out.println(car3.getSpeed());//30
System.out.println("@@@@@@@@@@@@@@@@");
// PolyBus bus2 = new PolyCar(); //[err]superclass 타입 subclass로 치환 불가능
// PolyBus bus2 = new car2; //[err]superclass 타입 "
PolyBus bus2 = (PolyBus)car2; //[Casting]
bus2.dispData(); //버스 승객은 10 \n 버스 속도은 30
bus2.show(); //버스 show
System.out.println(bus2.getSpeed());//30
System.out.println();
// PolyTaxi taxi2 = new PolyCar();
PolyTaxi taxi2 = (PolyTaxi)car3;
taxi2.dispData();
// PolyTaxi taxi3 = (PolyTaxi)car1; //[syntax err 없음][Runtime err(실행 오류).] ClassCastException
System.out.println("\n\n#######################");
PolyCar p[] = new PolyCar[3]; //[배열 선언] 배열변수는 성격이 같은 애들끼리만 들어올 수 있음 (subclass도 가능)
p[0] = car1;
p[1] = bus1;
p[2] = taxi1;
System.out.println("p.length : " + p.length);//p.length : 3
for(int a = 0; a < p.length; a++) { //속도: 30(car1)
p[a].dispData(); //버스 승객은 10 \n 버스 속도은 30
} //택시를 이용하고 있는 인원 수 2
System.out.println("\n여기까지 -------------------\n");
//향상된 for -> 참조형 변수에서만 가능
for(PolyCar hi:p) { //속도: 30(car1) \n
hi.dispData(); //버스 승객은 10 \n 버스 속도은 30 \n
System.out.println(); //택시를 이용하고 있는 인원 수 2
}
// statement 는 똑같은 데 결과는 다양하게 나온다 = [다형성]
}
}
'Programming Language > Java 마스터하기(feat. 이것이 자바다)' 카테고리의 다른 글
Call by Value vs. Call by Reference (0) | 2020.07.20 |
---|---|
[8. 인터페이스] (0) | 2020.07.19 |
[6. 클래스] (5) | 2020.07.19 |
[5. 참조 타입] (0) | 2020.07.19 |
[4. 조건문과 반복문] 반복문 problem 1~3 (0) | 2020.07.19 |