210712 월
상속
: 다른 클래스가 가지고 있는 멤버들을 새로 작성할 클래스에서 직접 만들지 않고 상속을 받음으로써 새 클래스가 자신의 멤버처럼 사용할 수 있는 기능
1) 목적
: 클래스의 재사용, 연관된 일련의 클래스에 대한 공통적인 규약 정의
-코드의 양이 줄어들 수 있음.
2) 장점
-보다 적은 양의 코드로 새로운 클래스 작성 가능
-코드를 공통적으로 관리하기 때문에 코드의 추가 및 변경 용이
-중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여할 수 있다
3) 특징
(1) 모든 클래스는 Object 클래스의 후손
-Object클래스가 제공하는 메소드를 오버라이딩하여 메소드 재구현 가능
*오버라이딩
: 부모가 가진 기능을 자식이 고쳐서 사용하는 것
ex) java.lang.String 클래스의 equals()와 toString()
(2) 부모 클래스의 생성자, 초기화 블록은 상속 안됨
=> 따라서 자식 클래스 생성자 안에서 부모 클래스 생성자 호출을 명시하고 싶으면 super()활용
(3) 부모의 private멤버는 상속은 되지만 직접 접근이 불가능하다
=> 따라서 super()을 이용하여 전달받은 부모 필드 값을부모 생성자 쪽으로 넘겨서 생성하거나 setter, getter메소드를 이용하여 접근
1> 부모 클래스 - Product
package com.kh.chap01_inherit.after.model.vo;
public class Product {
private String brand; //브랜드
private String pCode; //상품번호
private String pName; //상품명
private int price; //가격
public Product() {}
public Product(String brand, String pCode, String pName, int price) {
super();
//Q. 자동으로 만들어줄 경우 왜 super가 생길까?
//A. Object 클래스가 모든 클래스의 부모이므로 Object 클래스의 생성자를 호출한다
//super : 부모를 읽는 키워드, this : 자기 자신의 객체를 읽는 키워드
this.brand = brand;
this.pCode = pCode;
this.pName = pName;
this.price = price;
}
public String getBrand() {
return brand;
}
public String getpCode() {
return pCode;
}
public String getpName() {
return pName;
}
public int getPrice() {
return price;
}
public void setBrand(String brand) {
this.brand = brand;
}
public void setpCode(String pCode) {
this.pCode = pCode;
}
public void setpName(String pName) {
this.pName = pName;
}
public void setPrice(int price) {
this.price = price;
}
public String information() {
return "brand : " + brand + ", pCode : " + pCode + ", pName : " +
pName + ", price : " + price;
}
public void print() {
System.out.println("나 Product 객체야!");
}
}
2-1> 자식 클래스 - Desktop
package com.kh.chap01_inherit.after.model.vo;
//Product를 상속받는 Desktop 클래스
public class Desktop extends Product{
//Desktop이 자식, Product가 부모
//extends : 확장한다는 뜻
//부모의 것을 물려받고 자신의 것을 추가하여 클래스를 확장한다
private boolean allInOne;
public Desktop() {}
//super();가 내포되어 있음, 명시적으로 표기하지 않아도 동작한다
//Product의 기본 생성자가 명시되지 않았을 시 오류가 발생한다
public Desktop(String brand, String pCode,
String pName, int price, boolean allInOne) {
//Q. 왜 다 써줘?
//A. new Desktop하는 순간 내가 전달받은 필드값을 초기화 하려고.
//Q. allInOne을 중간에 넣어줘도 되나?
//A. 문제 없음. 근데 순서 바뀜
super(brand, pCode, pName, price);
//부모객체가 가진 생성자를 받아오는 것을 의미 / 줄바꾸면 오류남
//후손 생성자 안에 포함 시키며 반드시 첫 줄에 표기
//this.brand = brand; 이건 안됨
this.allInOne = allInOne; //이건 가능
}
public boolean isAllInOne() {
return allInOne;
}
public void setAllInOne(boolean allInOne) {
this.allInOne = allInOne;
}
@Override //이걸 붙이면 오버라이드가 명확해짐, 왼쪽의 초록색은 오버라이드라는 뜻
public String information() {
return super.information() + ", allInOne : " + allInOne;
}
//Product 클래스의 print 메소드 오버라이딩
//위에 @Override를 기록해주면 상속이 명확해진다.
public void print() {
System.out.println("나 Desktop 객체야!");
}
}
2-2> 자식 클래스 - Smartphone
package com.kh.chap01_inherit.after.model.vo;
public class SmartPhone extends Product {
private String mobileAgency;
public SmartPhone() {}
public SmartPhone(String brand, String pCode,
String pName, int price, String mobileAgency) {
super(brand, pCode, pName, price);
this.mobileAgency = mobileAgency;
}
public String getMobileAgency() {
return mobileAgency;
}
public void setMobileAgency(String mobileAgency) {
this.mobileAgency = mobileAgency;
}
@Override
public String information() {
return super.information() + ", mobileAgency : " + mobileAgency;
}
//Product 클래스의 print 메소드 오버라이딩
public void print() {
System.out.println("나 SmartPhone 객체야!");
}
}
2-3> 자식 클래스 - Tv
package com.kh.chap01_inherit.after.model.vo;
public class Tv extends Product{
private int inch;
public Tv() {}
public Tv(String brand, String pCode, String pName, int price, int inch) {
super(brand, pCode, pName, price);
this.inch = inch;
}
public int getInch() {
return inch;
}
public void setInch(int inch) {
this.inch = inch;
}
@Override
public String information(){
return super.information() + ", inch : " + inch;
}
//Product 클래스의 print 메소드 오버라이딩
public void print() {
System.out.println("나 Tv 객체야!");
}
}
<실행>
package com.kh.chap01_inherit.after.run;
import com.kh.chap01_inherit.after.model.vo.Desktop;
import com.kh.chap01_inherit.after.model.vo.SmartPhone;
import com.kh.chap01_inherit.after.model.vo.Tv;
public class Run {
public static void main(String[] args) {
//해당 클래스를 객체(인스턴스)화 시켜준다.
//Desktop 객체 생성
Desktop d = new Desktop("삼성", " d-01", "짱짱데스크탑", 20000000, true);
//기본 생성자로 만들지 않고 매개변수 생성자로 만들어 준다
//SmartPhone 객체 생성
SmartPhone s = new SmartPhone("사과", "s-01", "아이폰", 1500000, "Kr");
//Tv 객체 생성
Tv t = new Tv("LG", "t-01", "겁나 얇은 티비", 3500000, 46);
System.out.println(d.information());
System.out.println(s.information());
System.out.println(t.information());
//오버라이딩 테스트
//부모 클래스의 메소드를 자식 클래스에서 재정의
//오버라이딩 규칙을 잘 지켜서 작성했을 경우 @Override 어노테이션 없이 적용되지만
//@Override 어노테이션 작성 시 컴파일러가 체크해주기 때문에 명시 권장
d.print();
s.print();
t.print();
}
}
4) 방법
extends 사용
5) 표현식
[접근제한자] class 클래스명 extends 클래스명 {}
public class 자식 extends 부모{}
6) 단일 상속과 다중 상속
(1) 단일상속
=> 자바에서는 단일 상속만 가능하다
예) extends A, B, C 불가능
(2) 다중상속
=> A 클래스와 B클래스에 똑같은 기능이 있을 때 C가 누구의 것을 가져오는지 모호하기 때문에 자바에서는 단일 상속만 허락한다
*super()와 super
1> super()
부모 객체의 생성자
2> super.
상속을 통한 자식 클래스 정의 시 해당 자식 클래스의 부모 객체를 가리키는 참조 변수
7) 오버라이딩
: 자식 클래스가 부모 메소드를 재작성하는 것
-후손이 부모를 일부 고쳐서 사용하겠다는 것
-자식 객체를 통한 실행 시 후손 것이 우선권을 가짐
(1) 특징
-메소드 헤드라인 위에는 반드시 Annotation, @Override 표시
-접근 제어자를 부모 것보다 같거나 넓은 범위로 변경 가능, But 좁은 범위로 변경하는 것은 불가능하다
(2) 성립 조건
=> 부모 클래스의 메소드와 자식 클래스의 메소드 비교
-메소드 이름 동일
-매개변수의 개수, 타입 동일
-리턴 타입 동일
-private 메소드는 오버라이딩이 불가능하다
*오버로딩
: 한 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것
(이름이 헷갈릴 수 있으니, 면접에서 물어보는 경우가 왕왕 있다)
<성립 조건>
-같은 메소드 이름
-다른 매개변수 선언부(매개변수 타입, 개수, 순서)

1> 조상 - Vehicle
package com.kh.chap01_inherit.model.vo;
//조상 클래스로 선언하자
public /*final*/ class Vehicle {
//final을 붙여줄 경우 상속관련한 문제가 생긴다
private String name; //이름
private double mileage; //연비
private String kind; //종류
public Vehicle() {}
//3개의 필드값을 매개변수로 받는 매개변수 생성자
public Vehicle(String name, double mileage, String kind) {
super();//Object의
this.name = name;
this.mileage = mileage;
this.kind = kind;
}
public String getName() {
return name;
}
public double getMileage() {
return mileage;
}
public String getKind() {
return kind;
}
public void setName(String name) {
this.name = name;
}
public void setMileage(double mileage) {
this.mileage = mileage;
}
public void setKind(String kind) {
this.kind = kind;
}
public String information() {
return "name=" + name + ", mileage=" + mileage + ", kind=" + kind;
}
public void howToMove() {
System.out.println("이렇게 움직이면 되지");
}
/*public final void howToMove() { => 이렇게 만들면 override 할수 없다
System.out.println("이렇게 움직이면 되지");
// 따라서 오버라이딩을 막고 싶으면 final을 쓰면 됨
}*/
}
2-1> 후손 - Airplane
package com.kh.chap01_inherit.model.vo;
public class Airplane extends Vehicle{
private int tire;
private int wing;
public Airplane() {}
public Airplane(String name, double mileage,
String kind, int tire, int wing) {
//this.name = name;//(O) protected String name;로 바꿀 경우의 예시
//super.name = name;//(O)
//this.kind = kind;//(X)
super(name, mileage, kind); //부모쪽에서 초기화할 값은 해주고
this.tire = tire; //자손에서 해줘야 할 부분은 따로 해준다
this.wing = wing;
}
public int getTire() {
return tire;
}
public int getWing() {
return wing;
}
public void setTire(int tire) {
this.tire = tire;
}
public void setWing(int wing) {
this.wing = wing;
}
@Override
public String information() {
return "Airplane [" + super.information() + ", tire=" + tire + ", "
+ "wing=" + wing + "]";
}
@Override
public void howToMove() {
System.out.println("나는 뱅기");
}
}
2-2> 후손 - Car
package com.kh.chap01_inherit.model.vo;
public class Car extends Vehicle {
private int tire;
public Car() {}
public Car(String name , double mileage, String kind, int tire) {
super(name, mileage, kind);
this.tire = tire;
}
public int getTire() {
return tire;
}
public void setTire(int tire) {
this.tire = tire;
}
@Override
public String information() {
return "Airplane [" + super.information() + ", tire=" + tire + "]";
}
@Override
public void howToMove() {
System.out.println("나 카야");
}
}
2-3> 후손 - Ship
package com.kh.chap01_inherit.model.vo;
public class Ship extends Vehicle{
private int propeller;
public Ship() {}
public Ship(String name , double mileage, String kind, int propeller) {
super(name, mileage, kind);
this.propeller = propeller;
}
public int getpropeller() {
return propeller;
}
public void setpropeller(int propeller) {
this.propeller = propeller;
}
@Override
public String information() {
return "Airplane [" + super.information() + ", propeller=" + propeller + "]";
}
@Override
public void howToMove() {
System.out.println("나 쉽이거든?");
}
}
<실행>
package com.kh.chap01_inherit.run;
import com.kh.chap01_inherit.model.vo.Airplane;
import com.kh.chap01_inherit.model.vo.Car;
import com.kh.chap01_inherit.model.vo.Ship;
public class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
Airplane airplane = new Airplane("비행기1", 0.021, "제트기", 16, 5);
Car car = new Car("BMW", 12.5, "세단", 4);
Ship ship = new Ship("낚시배", 3, "어선", 1);
//information도 Override된 메소드
System.out.println(airplane.information());
System.out.println(car.information());
System.out.println(ship.information());
//Vehicle 클래스 - public void howToMove() 메소드 만들고
//나머지 클래서에서 오버라이딩해서 어떻게 움직이는지 출력문 각자 알맞게 작성하기
airplane.howToMove();
car.howToMove();
ship.howToMove();
}
8) 예약어 - final
(1) final 클래스
: 상속이 불가능한 클래스
public final class FinalClass{}
(2) final 메소드
: 상속시 오버라이딩이 불가능한 메소드
public final void method(){}
예)
final int NUM = 10;
=> 변할 수 없는 값
public static final double PI = 3.141592....;
9) 제어자, 예약어
-지역 변수 : 지역변수 앞에 쓸 수 있는 예약어는 final
-변수(필드부의 멤버 변수를 의미) : 모든 접근 제한자, final, static
-메소드 : 모든 접근 제한자, final, abstract, static
-클래스 : public, default, final, abstract
*abstract는 다형성에서 배울 것이다.
<유의사항>

-abstract는 미완성이라는 의미. <=> final과 반대.
-static은 할당의 의미, abstract은 미완성의 의미이므로 나를 상속받아서 완성시켜달라는 뜻을 내포하므로 동시에 사용 불가능. (대척점에 있으므로)
10) for each문
// 향상 된 for문, for each 배우기
//1. 배열의 경우
double[] arr = {0.1, 0.2, 0.3, 0.4, 0.5};
for(int i = 0 ; i < arr.length ; i++) {
System.out.print(arr[i]);
}
System.out.println();
for(double num :arr) {
System.out.print(num);
}
System.out.println();
//2. 객체 배열의 경우
Airplane[] list = { new Airplane("p=01", 0.03, "여객기", 16 , 5),
new Airplane("p=02", 0.03, "여객기", 16 , 5),
new Airplane("p=03", 0.03, "여객기", 16 , 5)};
for(int i = 0 ; i < list.length ; i++) {
System.out.print(list[i].information());
System.out.println();
}
for(Airplane ap:list) {
System.out.print(ap.getName());
}
}
답 0.10.20.30.40.5 0.10.20.30.40.5 Airplane [name=p=01, mileage=0.03, kind=여객기, tire=16, wing=5] Airplane [name=p=02, mileage=0.03, kind=여객기, tire=16, wing=5] Airplane [name=p=03, mileage=0.03, kind=여객기, tire=16, wing=5] p=01p=02p=03 |
'웹개발 수업 > JAVA' 카테고리의 다른 글
[Day +16] 자바 1차 시험 (0) | 2021.07.14 |
---|---|
[Day +15]상속, 다형성 / 오버라이딩, toString, equals, hashcode, instanceof, 캐스팅, 바인딩 (0) | 2021.07.13 |
[Day +13]객체 / 오버로딩, 메소드, 객체배열 (0) | 2021.07.11 |
[Day +12]객체 / 필드, 전역변수, 지역변수, 매개변수, 예약어(static, final), 생성자, 오버로딩 (0) | 2021.07.11 |
[Day +11]객체 / 객체지향언어, 클래스, 캡슐화, 추상화, 접근 제한자, 필드 (0) | 2021.07.11 |