일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- math
- c#
- string
- Apache
- PANDAS
- dataframe
- PostgreSQL
- google apps script
- PySpark
- Mac
- Tkinter
- Java
- Python
- Kotlin
- numpy
- django
- matplotlib
- Excel
- GIT
- hive
- SQL
- array
- 파이썬
- Google Excel
- gas
- Github
- list
- Redshift
- Google Spreadsheet
- Today
- Total
달나라 노트
Java - class의 상속 본문
public class James extends People {
public void introduce() {
System.out.println("Hello. I am " + this.name + "." + "I live in " + this.planet + ".");
}
public static void main(String args[]) {
James james = new James();
james.setName("James");
System.out.println(james.name);
System.out.println(james.planet);
james.introduce();
}
}
-- Result
James
Earth
Hello. I am James.I live in Earth.
Java class의 상속에 대해 알아봅시다.
상속은 어떤 class를 다른 class에 복붙해주는 기능이라고 보시면 됩니다.
class A를 작성해두고 class B에서 class A를 상속받는다면 class A는 부모 class, class B는 자식 class라고 부릅니다.
People.java
public class People {
String name;
String planet = "Earth";
public void setName(String name) {
this.name = name;
}
}
먼저 위처럼 People.java 파일에 People class를 적어둡시다.
People class는 부모 class가 될 예정입니다.
James.java
public class James extends People {
public static void main(String args[]) {
James james = new James();
james.setName("James");
System.out.println(james.name);
System.out.println(james.planet);
}
}
-- Result
James
Earth
그리고 위처럼 James.java 파일을 만들고 코드를 작성해줍시다.
위 코드의 특이점은 바로 public class 선언 부분입니다.
원래는 public class class_name {} 이런 방식으로 선언하였지만 이번엔 extends 키워드를 사용하였습니다.
이렇게 class를 상속받을때는 자식class extends 부모class 의 형태로 작성해야 합니다.
(참고로 People.java와 James.java는 동일한 디렉토리 동일 폴더 안에 있습니다.)
객체가 생성되는 과정을 봅시다.
James james = new James()
객체는 위 코드에서 생성되는데 위 내용의 의미를 보면 다음과 같습니다.
James james
james라는 이름의 객체를 생성하며 이 객체의 type은 James class와 같습니다.
new James()
james 객체의 내용은 James class와 같습니다.
저희는 james 객체에 James class의 내용을 부여할 예정이죠.
그러면 james 객체의 data type은 당연히 James class와 동일해질 겁니다.
따라서 James james의 형식으로 james 객체의 data type을 정해준 겁니다.
객체를 만들 때에도 일반 변수를 선언할 때 처럼(e.g. int Num, String name 등) data type을 명시해줘야 하는데 객체의 data type은 위처럼 class 이름을 적어주면 됩니다.
근데 여기서 주의할 사항이 있습니다.
객체를 만들 때에는 다음 3가지 경우만 허용됩니다.
parent_class object_name = new parent_class(); -> 객체의 data type class(왼쪽)와 부여할 class(오른쪽)이 동일한 class인 경우
child_class object_name = new child_class(); -> 객체의 data type class(왼쪽)와 부여할 class(오른쪽)이 동일한 class인 경우
parent_class object_name = new child_class(); -> 왼쪽이 부모 class이고 오른쪽이 자식 class인 경우
그리고 다음의 경우는 허용되지 않습니다.
child_class object_name = new parent_class(); -> 왼쪽이 자식 class이고 오른쪽이 부모 class인 경우
정리해보면 객체 생성시에는
1. data type(왼쪽)과 부여할 class(오른쪽)를 동일하게 적는 경우
2. data type(왼쪽)은 부모 class이고 부여할 class(오른쪽)은 자식 class인 경우
위 2 경우만 허용되고
2번의 반대인 data type(왼쪽)은 자식 class이고 부여할 class(오른쪽)은 부모 class인 경우는 불가능합니다.
이를 좀 더 체크해봅시다.
public class James extends People {
public static void main(String args[]) {
People james = new People(); -> 가능
James james = new James(); -> 가능
People james = new James(); -> 가능
James james = new People(); -> 불가
james.setName("James");
System.out.println(james.name);
System.out.println(james.planet);
}
}
위 코드에서 객체 생성 부분을 봅시다.
(단지 4가지 경우를 명시했을 뿐 실제 위 코드가 작동하는건 아닙니다.)
extends 키워드 쪽의 상속 관계를 보면 People class의 정보를 James에 extends하고있으므로
People이 부모 class이며 James가 자식 class입니다.
People james = new People(); -> People data type에 People class를 넣고 있습니다. 동일한 class data type에 동일한 class를 넣고 있으니 가능합니다.
James james = new James(); -> James data type에 James class를 넣고 있습니다. 동일한 class data type에 동일한 class를 넣고 있으니 가능합니다.
People james = new James(); -> People data type에 James class를 넣고 있습니다. People은 부모 class이니 부모 class의 data type을 가진 james 객체는 자식 class인 James class를 받아들일 수 있습니다.
원래는 data type class와 할당할 class가 동일해야 하지만 특수하게 People과 James class가 부모 자식 관계인 경우 부모 data type을 가진 객체는 자식 class를 받아들일 수 있습니다.
James james = new People(); -> James data type에 People class를 넣고 있습니다. James는 자식 class이고 People은 부모 class입니다. 이것은 자식 class data type을 가진 james 객체에 부모 class인 People을 넣으려하고있습니다. 이 경우는 불가능합니다. 왜냐면 부모 class가 더 큰 개념이기 때문에 더 큰 부모 class를 더 작은 자식 class data type에 넣는 것은 불가능합니다.
class PeopleInfo {
String name;
String planet;
public void setName(String name) {
this.name = name;
}
public void setPlanet(String planet) {
this.planet = planet;
}
public void introduce() {
System.out.println("Hello. I'm " + this.name + ". I live in " + this.planet + ".");
}
public void introduce(int x) {
System.out.println("Hello. I'm " + this.name + ". I live in " + this.planet + ". And I'm " + x + " years old.");
}
}
public class Personal {
public static void main(String args[]) {
PeopleInfo lisa = new PeopleInfo(); -> Case 1
Personal lisa = new Personal(); -> Case 2
PeopleInfo lisa = new Personal(); -> Case 3
Personal lisa = new PeopleInfo(); -> Case 4
lisa.setName("Lisa");
lisa.setPlanet("Earth");
lisa.introduce();
lisa.introduce(15);
}
}
위 코드는 잠깐 별도로 작성한 코드입니다.
위 코드를 보면 Personal class에서 lisa라는 객체를 생성하고있습니다.
마찬가지로 총 4가지 경우를 적어놨습니다.
이것도 위에서 봤던것처럼 부모/자식 class의 관계를 이용하여 어떤 객체 생성이 에러 없이 성공할지 판단해야 할까요?
정답은 '아니다' 입니다.
왜냐면 위 코드에선 Personal class가 PeopleInfo class의 상속을 받는다거나 하지 않기 때문입니다.
(-> extends 키워드가 없기 때문에 상속받지 않는다고 볼 수 있죠.)
따라서 Personal class와 PeopleInfo class는 부모 자식 관계가 아니라 그냥 동등한 별도의 class입니다.
따라서 위 4개 case에서 에러 없이 성공하는 경우는 data type class와 할당 class가 동일한 Case 1, Case 2 뿐이며,
Case 3, Case 4는 에러를 일으킵니다.
또한 Personal은 별도의 class이고 PeopleInfo class의 정보를 하나도 상속받지 못했기 때문에
Case 2처럼 Personal class로 lisa 객체를 생성하면 코드 아래쪽에 있는 lisa.setName, lisa.introduce 등의 method를 사용하지 못합니다.
즉, 객체 할당에 성공하는건 Case 1, Case 2이며
list.setName 등 PeopleInfo class의 정보를 제대로 사용하려면 PeopleInfo class를 이용해서 객체를 만든 Case 1만 가능하다는 뜻입니다.
이제 다시 본래 얘기로 돌아와서 new James 부분을 봅시다.
James class의 내용을 이용하여 객체를 생성한다고 했는데 James class는 People class를 상속받았죠?
따라서 결국 People class를 이용하여 객체를 만들게 되는 것과 같습니다.
이렇게 People class를 상속받은 James class는 People class의 attribute와 method를 사용할 수 있습니다.
그래서 James class는 planet 변수를 직접 선언하지 않았어도 People class로부터 상속받은 planet attribute를 가지고 있게 되며,
setName이라는 method를 이용하여 name 속성에 값을 할당할 수 있습니다.
James.java
public class James extends People {
public void introduce() {
System.out.println("Hello. I am " + this.name + "." + "I live in " + this.planet + ".");
}
public static void main(String args[]) {
James james = new James();
james.setName("James");
System.out.println(james.name);
System.out.println(james.planet);
james.introduce();
}
}
-- Result
James
Earth
Hello. I am James.I live in Earth.
위 코드를 봅시다.이전 예시와 거의 동일하지만 딱 한가지 다른 점은 James에 introduce라는 method가 추가되었습니다.
위처럼 James class는 People class를 상속받아 People class의 attribute, method를 사용할 수 있지만
introduce처럼 James class 고유의 method를 추가할 수도 있습니다.
이 상태에서 james 객체를 만들면 james 객체는 People class에게서 상속받은 name, planet attribute와 setName method를 사용할 수 있음과 동시에 James class 고유의 method인 introduce method도 사용할 수 있게 됩니다.
Lisa.java
public class Lisa extends James {
public static void main(String args[]) {
Lisa lisa = new Lisa();
lisa.setName("Lisa");
System.out.println(lisa.name);
System.out.println(lisa.planet);
lisa.introduce();
}
}
-- Result
Lisa
Earth
Hello. I am Lisa.I live in Earth.
Planet class를 James class에 상속시켰습니다.
그러면 만약 James class를 다른 class에 상속시키면 어떻게 될까요?
Lisa.java라는 파일을 새로 생성해 위 코드를 작성했습니다.
Lisa class는 James class를 상속받고 있음을 extends 키워드를 통해 알고있죠.
그리고 main method 부분을 봅시다.
lisa 객체를 Lisa class를 이용하여 생성하였고 Lisa class는 James class를 상속받았으니 lisa 객체는 James class의 내용을 모두 사용할 수 있습니다.
따라서 setName method, name/planet attribute, introduce method 모두를 사용할 수 있죠.
이렇게 상속의 상속을 해서 여러 class를 만들 수 있습니다.
public class Lisa extends James {
public void introduce() {
System.out.println("Hi. I'm " + this.name + ". My home town is " + this.planet + ".");
}
public static void main(String args[]) {
Lisa lisa = new Lisa();
lisa.setName("Lisa");
lisa.planet = "Mars";
System.out.println(lisa.name);
System.out.println(lisa.planet);
lisa.introduce();
}
}
-- Result
Lisa
Mars
Hi. I'm Lisa. My home town is Mars.
만약 상속받은 class의 정보를 변경하고싶으면 어떻게 해야할까요?
그 답은 위 코드에 있습니다.
Lisa는 James class를 상속받고 있습니다.
그런데 Lisa class에서도 introduce라는 method를 정의하고있죠.
James class에서도 introduce method가 있습니다.
이런 경우 상속 받는 자식 class(=Lisa class)에 있는 introduce가 부모 class(=James class)의 introduce method를 덮어씌웁니다.
또한 lisa.planet = "Mars" 부분을 보면 부모 class의 planet attribute를 Earth에서 Mars로 재설정 하고있습니다.
이런식으로 상속받는 과정과 상속받은 class를 내 맘대로 변경하는 방법을 알아봤습니다.
'Java' 카테고리의 다른 글
Java - 생성자 (Constructor) (0) | 2021.03.14 |
---|---|
Java - class overloading (0) | 2021.03.14 |
Java - ArrayList (0) | 2021.03.13 |
Java - 2개의 class 선언, 객체 parameter (0) | 2021.03.13 |
Java - object (객체) (0) | 2021.03.13 |