일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- edwith
- CS50
- Compute Science
- 관계형 데이터베이스
- 모두를 위한 컴퓨터 과학(CS50)
- exception
- WebProgramming
- 기초프로그래밍
- 이진법
- CS기초지식
- 예외처리
- 알고리즘
- ERD
- 면접을 위한 CS 전공지식 노트
- Computer Science
- 모두를 위한 컴퓨터 과학
- til
- 부스트코스
- 상속
- ssafy
- 객체지향
- CS 기초지식
- SW
- Java Programming
- java
- 삼성청년SW아카데미
- CS 기초
- w3schools
- SSAFY 9기
- 데이터베이스 모델링
- Today
- Total
Joslynn의 하루
대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -10일차 노트 필기_ 상속, 다형성_220729 본문
대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -10일차 노트 필기_ 상속, 다형성_220729
Joslynn 2022. 7. 29. 18:37Inheritance(상속)
1) 부모 class의 속성과 method를 상속받는 것
2) 부모 class의 생성자(constructor)와 private 요소를 제외한 모든 것을 상속 받음
: 생성자는 객체 생성시 딱 한 번만 실행되기 때문;
3) 부모 class의 method와 속성을 별도의 선언 없이 내안에 있는 것처럼 접근하여 사용
4) extends 키워드
class A extends B { }: A가 B를 상속 받는다.// B: 부모 class
5) 단일 상속, 그러나 부모의 부모 class는 내려 받을 수 있음(대물림)
6) java의 모든 class는 Object(class)를 상속받는다
7) java의 최고 조상: Object (java의 모든 class는 Object를 상속 받음;)
: 굳이 상속이라는 단어 사용 필요 없음;
8) 자식 class는 부모class의 속성과 method를 사용하지만, 부모class는 자식 class의 속성과 method 사용 불가
class Car{
public String carname;
public int cost;
protected void printAttributes(){
System.out.println("carname="+carname+"\tcost="+cost);
}
}
//Car를 상속받는 EfSonata
class EfSonata extends Car {
EfSonata(){
super.carname = "Sonata"; // super는 부모를 의미;
this.cost = 20000000 ; // super, this, 생략 3가지 다 가능
}
// Car 내부의 메소드 활용
public class InheritanceExam{
public static void main (String [] args) {
new Car().printAttributes();
new EfSonata().printAttributes();
}
결과값:
예시 2)
class Car{
public String carname;
public int cost;
protected void printAttributes(){
System.out.println("carname="+carname+"\tcost="+cost);
}
}
//Car를 상속받는 EfSonata, Excel, Carnival 3개 클래스 작성
class EfSonata extends Car {
EfSonata(){
// 중요 포인트!! efSonata의 객체 안에는 Car 객체 영역과 EfSonata 영역이 같이 생성;
this.carname = "Sonata";
this.cost = 20000000 ;
}
}
class Excel extends Car {
Excel(){
this.carname = "페라리";
this.cost = 20000000;
}
}
class Carnival extends Car {
Carnival(){
this.carname = "카니발";
this.cost = 30000000;
}
}
// Car calss에있는 printAttributes()메소드를 호출
public class InheritanceExam{
public static void main (String [] args) {
new Car().printAttributes();
// 중요 포인트!! Car 객체의 접근자가 허용하는 범위내에서 ef.으로 Car 객체의 필드, 메소드 호출 가능
new EfSonata().printAttributes();
new Excel().printAttributes();
new Carnival().printAttributes();
}
}
중요 Point
: EfSonata, Carnival, Excel 이 세 class는 각각 Car 객체로부터 상속 받음;
상속 시, Car 객체는 공유 되지 않으며, EfSonata, Carnival, Excel 객체 생성 시, 각각 생성된다.
: 위의 예제에서 Car 객체의 접근자가 허용하는 범위내에서 ef.으로 Car 객체의 필드, 메소드 호출 가능
상속의 효용
: 공통의 속성 또는 기능을 가지는 class들 → 공통 속성, 기능을 하나의 부모 클래스에 정의해두고 extends로 내 것처럼 사용 가능;
: 반복 코드 감소, 속성 및 기능 변경, 유지보수에 유리
Polymorphisom (다형성)
1) 반드시 상속 관계에서 성립
2) class A extends B { }일 때, A를 A라 부를 수 있고, A를 B라 부를 수 있다. // A를 부르는 호칭 변경;
: 호칭에 따라 접근할 수 있는 영역에 제한이 생김; B라고 부르면, B의 영역만 접근 가능;
3) : 부모클래스의 참조 변수는 자식 객체를 참조할 수 있다. // Promotion 일어나기 때문; 부모 class는 자식 class의 상위 class // Upcasting(업캐스팅)
4) 여러 타입의 객체를 하나의 타입으로 관리할 수 있음;
class A extends B {
A a = new A(); // 가능
B b = new A(); // 가능
B c = new B(); // 가능
A d = new B(); //컴파일 에러
}
Polymorphisom (다형성)의 효용
: 다형성이 없으면, 함수 OverLoading을 계속해야 할 수 있음; (아래 예제 참고)
: 아래 예제에서 만약 새로운 차(Car) 타입이 등장해도 engineer 메소드를 수정할 필요 없이, Car class를 상속 받는 class를 만들기만 하면 됨; // Code 유지 보수에 유리
다형성 예제)
class CarCenter{
public void engineer(Car cd){
System.out.print(cd.carname+" 수리완료!\t");
System.out.println("청구비용"+cd.cost+" 원");
}
}
public class PolymorphismExam{
public static void main(String[] args) {
CarCenter cc=new CarCenter();
EfSonata ef=new EfSonata();
Carnival ca=new Carnival();
Excel ex=new Excel();
Car car= new Car();
cc.engineer(car);// Car 객체의 주소값을 cd의 engineer 메소드의 인수로; Car cd = car(주소값)
cc.engineer(ef);// engineer 메소드는 EfSonata 객체가 상속 받은 Car 객체를 가르킴;
cc.engineer(ca);//
cc.engineer(ex);//
}
}
만약 다형성이 없다면)
class CarCenter{
public void engineer(Car cd){
System.out.print(cd.carname+" 수리완료!\t");
System.out.println("청구비용"+cd.cost+" 원");
}
public void engineer(EfSonata ef){ // 인수는 같은 타입만 받을 수 있음; 따라서 앞선 메소드와 다른 인수 타입으로 함수 오버로딩
System.out.print(cd.carname+" 수리완료!\t");
System.out.println("청구비용"+cd.cost+" 원");
}
public void engineer(Carnival ca){
System.out.print(cd.carname+" 수리완료!\t");
System.out.println("청구비용"+cd.cost+" 원");
}
public void engineer(Excel ex){
System.out.print(cd.carname+" 수리완료!\t");
System.out.println("청구비용"+cd.cost+" 원");
}
}
public class PolymorphismExam{
public static void main(String[] args) {
CarCenter cc=new CarCenter();
EfSonata ef=new EfSonata();
Carnival ca=new Carnival();
Excel ex=new Excel();
Car car= new Car();
cc.engineer(car);
cc.engineer(ef);
cc.engineer(ca);
cc.engineer(ex);
}
}
업캐스팅 (UpCasting)
: 위의 예시에서 s2변수는 부모 객체를 참조(UpCasting), 하위에 있는 자식 멤버는 접근할 수 없음; // 단, 재정의된 메소드만 자식부분 접근가능 (Overriding)
→ 하나의 타입으로 여러 객체(부모, 자식 class에서 생성된 객체)들을 관리할 수 있으며, 같은 타입일지라도 재정의된 메소드로 인해 실행 결과가 다를 수 있다. // 재정의된 자식 메소드가 호출되기 때문; (동적 바인딩)
다운캐스팅 (DownCasting)
: Upcasting된 대상 객체를 다시 해당 type으로 참조시키는 것;
Ex> Sub s3 = (Sub) s2 ; => ObjectDownCasting
: 형 변환 - 객체가 변하는 것이 아니라 참조변수의 타입에 따라 참조하는 객체의 볼 수 있는 멤버 범위가 달라짐;
*참조사항*
Object(객체) 타입의 명시적 형 변환: 객체 타입은 크기를 비교할 수 없으나, 상속관계에서 명식적인 형 변환(Casting)이 가능;
* instanceof(연산자)
: 상황에 맞춰서 해당 객체를 확인하고, DownCasting을 하는 방법도 존재;
: (Object변수) instanceof (ObjectType) ⇨ 왼쪽의 참조변수가 오른쪽의 Type이 될 수 있는지?
Ex> s3 instanceof Sub
instance: 메모리에 생성된 객체;
즉, 참조 변수 s3가 Sub class를 이용해 만들어진 객체인지 확인
== 참조변수 객체가 어떤 타입으로 형 변환이 가능한지 확인하는 것;
: 반드시 상속관계일 때 사용한다. (아니면 컴파일 오류)
: 왼쪽의 변수형이 오른쪽의 Type과 같거나 서브 class일 때 true이다.
class CarCenter{
public void engineer(Car cd){
System.out.println("cd = "+cd);
System.out.println("cd.carname = "+cd.carname);
//System.out.println(cd.color); // 부모 타입 변수로는 자식 부분접근 불가
/*아래 ex와 cd를 가르키는 주소값은 동일하지만 Car 타입 변수에 담은 cd는 자식 타입의 필드에 접근 불가 */
// 위 문자 에러: 부모 타입을 자식 타입으로 형변환 해서 접근 가능하도록 한다.
Excel ex2 = (Excel) cd; // 부모 타입을 자식 타입으로 변경하려 함; 더 작은 type으로 형 변환은 Casting 연산자 필요 === 객체를 DownCasting (ObjectDownCasting)
System.out.println("ex2= "+ex2);
System.out.println("ex2.color= "+ex2.color);
}
}
public class PolymorphismExam{
public static void main(String[] args) {
CarCenter cc=new CarCenter();
Car car= new Car();
Excel ex=new Excel();
System.out.println("ex= "+ex);
System.out.println("ex.carname= "+ex.carname);
System.out.println("ex.color= "+ex.color);
System.out.println("-------------------engineer메소드 호출---------------");
cc.engineer(ex);//
}
}
: 객체는 변경되지 않았으나, 객체를 가르키는 참조 변수가 누구인지에 따라 부모, 자식 객체의 멤버 접근 가능 범위가 달라짐;
다형성의 한계점: 부모 class에서 자식 class로 접근하기 위해 빈번한 ObjectDownCasting 일어나야 함
// 유연한 사용을 위해 Overriding(재정의) 개념을 사용
: Overriding: 상속 관계에서 modifier(abstract)만 다를 수 있음;
↔ OverLoading: 하나의 class 내에서 인수 타입, 개수, 순서가 다르나 이름이 같은 method;
(제한자, retrun type달라도 상관없음;)
**Java의 중요한 문법**
동적 바인딩: 재정의된 메소드는 부모 타입의 변수에 받았을 지라도 자식부분이 호출된다.
정의된 자식 메소드가 호출;
super 기능 3가지
1) super.변수이름 → 자식class에서 부모 class의 전역변수 호출
// 자식class의 변수이름과 부모class의 변수이름 같을 때 구분
2) super.method이름( [값, 값, ...] ); → 자식class에서 부모class의 method호출
3) super( [값, 값, ... ] ); → 자식 class의 생성자구현부 첫 번째 줄에서 부모 class의 생성자 호출
생성자 예제 1)
class Parent{
1. Parent(){
}
2. Parent(int i){
}
3. Parent(String str){
}
}
//------------------------
class Child extends Parent{
4. Child(){}
5. Child(int i){
}
6. Child(boolean b){
}
}
//------------------------
new Child (); // 4 → 1 → 4
new Child (5); // 5 → 1 → 5
new Child (true); // 6 → 1 → 6
// new Child ("o") // 컴파일 에러
//만약 1,2,3이 없다면,
new Child (); // Super ();자동으로 호출
new Child (5);
//만약 1 없고, 2,4 있다면,
//new Child(); // 컴파일 에러, 자식 class는 생성 시 부모의 기본생성자 자동 호출함;
//new Child(5); // 컴파일 에러
//해결 방법------------------------
class Child extends Parent{
Child(){
this(3);
}
Child(int i){
super(5);
}
Child(boolean b){
super("O");
}
}
중요 포인트
: 자식 class가 인수가 있는 생성자를 호출하더라도 부모 class의 기본 생성자가 필요;
package VS import
1) package
2) import
: package는 문서에 첫번째 줄에 한개 선언 ↔ import는 여러 개 선언 가능
: 다른 폴더에 있는 class를 사용할 때는 반드시 "import"를 붙여줘야 함;
최종 정리 예시>
class Animal{
// 공통의 속성
int leg;
String name;
// 공통의 기능
public void sound(){ }
public void eat(){ }
public void run(){ }
}
class Pig extends Animal{
/* int leg;
String name;*/
//Animail이 가진 속성, 기능 다 사용할 수 있음;
public void sound(){ // Overriding
"꿀꿀";
}
}
class Dog extends Animal{
public void sound(){ // Overriding
"멍멍";
}
}
class Cat extends Animal{
public void sound(){ // Overriding
"야옹";
}
}
/*--------------------------------------------------------------------*/
// 필드를 이용한 다형성 == 타입 하나만 두고 갈아끼우는 것;
Animal an = new Cat();
new Pig();
new Dog();
// 매개변수를 이용한 다형성
public void test(Animal an){ // 인수로 Cat, Pig, Dog 가능
an.eat( );
an.run( );
an.sound( );
}
필드의 다형성: 한 가지의 타입에 어떤 객체를 필드로 저장하느냐에 따라 실행결과가 달라질 수 있다
매개변수의 다형성 : 메소드의 매개변수에 자식타입의 객채를 대입할 수 있다
Overriding의 효용
: 사용자의 이용을 편리하게 함; → 같은 기능을 하는 메소드의 이름이 모두 다를 경우, 사용자가 알아야 할 메소드의 이름이 너무 많아짐;
: 같은 타입으로 여러 객체를 관리할 수 있지만, 각 객체별 실행결과는 달라질 수 있도록 하는 다형성의 중요 개념
super 기능 3가지
1) super.변수이름 → 자식class에서 부모 class의 전역변수 호출
// 자식class의 변수이름과 부모class의 변수이름 같을 때 구분
2) super.method이름( [값, 값, ...] ); → 자식class에서 부모class의 method호출
3) super( [값, 값, ... ] ); → 자식 class의 생성자구현부 첫 번째 줄에서 부모 class의 생성자 호출
Object class
: Java class의 최고 조상인 Object는 속성과 method를 가지고 있음;
: 모든 class들은 Object class의 속성과 method를 상속 받는다.