헬린코린이
[JAVA] 상속,super, 오버라이딩 본문
상속에 대해서 이야기하겠다
상속은 쉽게 말해 우리가 말하는 그 상속하고 비슷하다고 생각하면 된다.
상속에는 부모 클래스와 자식 클래스가 있다.
부모 클래스가 자식 클래스에게 상속해주는 것이다. 하는 방법은 코드를 보겠다.
public class Test01 {
public static void main(String[] args) {
Student s1 = new Student();
s1.info();
}
}
class Person{
String name = "홍길동";
}
class Student extends Person{
void info() {
System.out.println(super.name);
}
}
간단한 코드를 만들어 봤다.
자식 클래스가 부모 클래스를 상속받는 방법은 클래스명 뒤에 extends를 붙여주고
상속받을 클래스명을 적어주면 된다.
이렇게 하고 실행했을 때 "홍길동"이라고 콘솔에 출력될 것이다.
여기서 눈여겨볼 것은 Student에는 name이라는 변수가 없다는 것이다.
그런데도 출력이 됐다 어떻게 된 것일까
자식 클래스는 부모 클래스를 상속받을 때 부모 클래스에 있는 모든 변수를 다 상속받는다.
우리 눈에는 보이지는 않지만 Student 클래스에는 String name이라는 변수가 있는 것이다.
변수 이외에도 메서드도 상속받을 수 있다.
상속의 기본적인 것은 끝이다.
package class04;
public class test01 {
public static void main(String[] args) {
Shape s = new Shape("모양이름");
Shape s1 = new Shape("모양이름",12.3);
Circle c1 = new Circle(1);
Rectangle r1 = new Rectangle(3);
Rectangle r2 = new Rectangle(2,3);
s.draw();
s1.draw();
c1.draw();
r1.draw();
r2.draw();
}
}
class Shape1{
String name;
double area;
void draw() {
System.out.println(this.name+" 그리는 중....");
System.out.println(this.name+": "+this.area);
}
Shape(String name){
this(name, 0);
}
Shape(String name, double area){
this.name = name;
this.area=area;
}
Shape(){
}
}
class Circle1 extends Shape{
int radius;
static double PI=3.14;
void drawCircle() {
super.draw();
}
Circle(int radius){
super("원",radius*radius*PI);
}
}
class Rectangle1 extends Shape{
int x;
int y;
void drawRectangle() {
super.draw();
}
Rectangle(int x){
this(x, x);
}
Rectangle(int x, int y){
super("사각형",x*y);
}
}
상속을 활용한 간단한 예제이다 상속을 제대로 이해했다면 어렵지 않을 것이다.
여기서 보면 super. 와 super()가 있는데
이건 this와 비슷하다고 보면 된다.
앞에서 this. 와 this()를 설명했는데
간단하게 설명하자면
this. 와 this()는 자기 클래스의 변수를 가리키거나 생성자를 호출하는 것이고
super. 와 super() 부모 클래스의 변수나 부모 클래스의 생성자를 호출하는 것이다.
package class04;
public class Test03 {
public static void main(String[] args) {
Book b1 = new Book("","");
Cartoon b2 = new Cartoon("스파이패밀리");
Major b3 = new Major("Java");
b1.info();
b2.info();
b3.info();
}
}
class Book{
String title;
String category;
void info() {
System.out.println(this.title+" - "+this.category);
}
Book(String title, String category){
this.title=title;
this.category=category;
}
}
class Cartoon extends Book{
void info() {
super.info();
}
Cartoon(String title){
super(title, "애니메이션");
}
}
class Major extends Book{
void info() {
super.info();
}
Major(String title){
super(title, "프로그래밍");
}
}
부모 클래스를 하나 정의해주고 나머지 클래스들은 부모 클래스를 상속받게 했다.
자식 클래스에는 생성자를 정의하고 생성자를 통해 부모 클래스의 생성자에 접근하게 작성했다.
이렇게 되면 main에서 호출하면 입력값이 그대로 부모 클래스로 흘러들어 가 입력값에 맞게 출력될 것이다.
여러 개 상속을 받을 수 없다는 단점이 있다.
마지막으로 오버 라이딩에 이야기하겠다
앞서 오버 로딩을 배웠는데 다시 이야기하면 오버 로딩은 쉽게 말해 중복 정의이다.
오버 라이딩은 메서드 재정의 이다.
상속에서만 일어나야 한다.
오버 라이딩을 하는 이유는 부모의 메서드 기능이 마음에 들지 않아서 새롭게 정의하고 싶을 때 사용합니다.
package class06;
public class Test01 {
public static void main(String[] args) {
Pikachu p = new Pikachu();
p.hello();
p.attack();
}
}
class Monster{
String name;
void attack(){
System.out.println("기본 공격");
}
void hello(){
System.out.println("ㅎㅇㅎㅇ");
}
Monster(String name){
this.name=name;
}
}
class Pikachu extends Monster{
Pikachu(){
super("피카츄");
}
void attack() { //메서드 오버라이딩 == 메서드 재정의
System.out.println("백만 볼트!~~");
}
void hello() {
System.out.println("피카피카");
}
}
오버 라이딩을 하지 않은 상태에서 Pikachu클래스를 호출하면 Monster클래스에 정의되어있는 attack, hello메서드가 출력되지만 Pikachu클래스의 있는 메서드처럼 부모 클래스의 메서드를 가지고와 재정의하고 다시 출력하면 Pikachu클래스의
정의되어있는 attack, hello메서드가 출력될 것이다.\
오버 라이딩은 메서드 안에 내용만 다를 수 있지 반환 타입이나 매개변수가 달라지면 그건 오버 라이딩이 될 수가 없다.