예를 들어, '사람'이라는 클래스를 정의했다고 하자.
여기엔 사람이라면 갖고 있을 공통 속성(ex. 먹고 자고 쉬는 행위)이 존재하고, 이와 동시에 사람1과 사람2를 구분 지을 수 있는 특성(ex. 생김새)도 있다. 그렇기에 하나의 클래스로도 여러 인스턴스 생성이 가능하다.
멤버(Member) : 클래스의 구성요소
private String name;
private int age;
public void eat() {
System.out.println("밥을 먹는다.");
}
생성자(Constructor) :
class Person {
public Person (String name, int age) {
this.name = name;
this.age = age;
}
}
📢 가로(width), 세로(height)를 받아 직사각형의 넓이를 구하시오.
우선 객체를 생성한다는 건 어떤 말인가?
// 생성자 호출
Rectangle rectangle = new Rectangle();
메모리에 할당한다는 것인데, new 키워드로 생성자를 호출한다.
클래스 내에서 필드와 메서드를 만들어 주고 이를 main에서 호출해 결과값을 출력한다.
public class Rectangle {
// 필드 선언
private int width;
private int height;
// 생성자로 필드 초기화
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
// 메서드 생성
public int getArea() {
return width * height;
}
public static void main(String[] args) {
// Rectanngle 생성자는 두 개의 매개변수를 받음(width, height)
// 객체 생성 후 메서드 호출하여 넓이 구함
int area = new Rectangle(5, 7).getArea();
// 결과 출력
System.out.println(area);
}
}
상속은 클래스에서 빼놓을 수 없는 개념이다. 단어 뜻 그대로 상위 클래스의 필드와 메서드를 하위 클래스에서 상속 받는 걸 말한다. 기존 클래스를 재사용하기 때문에 코드의 변경과 유지보수에 유리하다.
사용법은 단순하다.
class Child extends Parents {
...
}
자바는 단일 상속만 가능해서 단 하나의 상위 클래스만 상속 받을 수 있다. 그렇다고 해서 바로 부모격만 상속 가능하다는 게 아니다. 예를 들어 (상위 클래스를 상속 받는) 하위 클래스1을 상속받는 하위 클래스2는 사용 가능하다.
📢 Animal 클래스를 상속받는 Cat, Dog 클래스를 만들고 각각 메서드 오버라이딩하기.
먼저 상위 클래스 Animal.java
package _04_class._04_inheritance.ex3;
public class Animal {
// 필드 선언
private String species;
private String name;
private int age;
// 메서드 정의
public void makeSound() {
System.out.println("동물 소리");
}
// 생성자로 선언한 필드 초기화
public Animal(String species, String name, int age) {
this.species = species;
this.name = name;
this.age = age;
}
// toString 오버라이딩
@Override
public String toString() {
return species + " 이름은 " + name + ", 나이는 " + age;
}
}
필드는 private
으로 설정하여 외부에서 직접 값을 변경할 수 없도록
name
, species
, age
필드 직접 접근 불가그럼 어떻게 해당 필드 값을 출력할 수 있나?
// Dog.java
package _04_class._04_inheritance.ex3;
public class Dog extends Animal {
public Dog (String name, int age) {
super("강아지", name, age);
}
@Override
public void makeSound() {
System.out.println("왈왈왈!");
}
public static void move() {
System.out.println("챡 챡 챡");
}
}
extends
로 상위 클래스 받아옴
super()
에 넘겨주어 생성자 호출makeSound를 override* 해서 덮어씌움
자바의 override
-상위 클래스의 메서드의 반환 타입, 매개변수 개수 등을 똑같이 작성하여 상위 클래스의 메서드가 아닌 하위 클래스의 메서드를 호출하게 함.
-쉽게 말해 덮어씌우는 것!
-어노테이션(@Override
)을 사용해 명시적으로 오버라이딩을 표시할 수 있음 (생략 가능)
static 키워드*로 메서드 정의
static 멤버 (필드, 메서드)
-객체마다 생성되지 않고, 클래스에 1개의 static 생성
-클래스가 생성되는 순간에 메모리를 할당 받음
ㄴ객체를 생성하지 않아도 static 멤버에 접근 가능
ㄴstatic 메서드에서 non-static 멤버에 접근 불가 (반대는 가능)
-같은 메모리 공간을 공유해서 동일한 클래스의 모든 인스턴스 값 동일
-유틸리티성 메서드 등 공유 목적으로 자주 사용
-static 메서드에서는 this 사용 불가! (대신 getter, setter)
같은 방식으로 Cat 클래스도 만들어줬다.
// Cat.java
package _04_class._04_inheritance.ex3;
public class Cat extends Animal {
public Cat(String name, int age) {
super("고양이", name, age);
}
@Override
public void makeSound() {
System.out.println("미야오옹~");
}
public static void move() {
System.out.println("자박 자박");
}
}
이 모든 내용을 호출할 AnimalEx.java
package _04_class._04_inheritance.ex3;
public class AnimalEx {
public static void main(String[] args) {
Cat cat = new Cat("연님", 5);
Dog dog = new Dog("태평", 6);
// 인스턴스 값 출력 :
System.out.println(cat.toString());
// static 변수는 인스턴스 없이 생성자로 호출 가능
Cat.move();
System.out.println(dog.toString());
Dog.move();
}
}
하나 이상의 추상 메서드(선언 O, 구현 X)를 포함하는 클래스
상속 관계에서 상위 클래스 역할
서브 클래스에서 반드시 추상 메서드를 구현해야 함
추상 클래스는 new 연산자를 통해 인스턴스 객체 생성 불가
설계와 구현을 분리함으로써 하나의 클래스에서 여러 타입을 구현할 수 있는 다형성을 갖춘다.
📢 Shape 추상 클래스를 상속 받는 Circle, Triangle 클래스 생성
🔶🔷상위 클래스 Shape
calculateArea
)로 만든다.package _04_class._05_abstract.ex3;
public abstract class Shape {
private String color;
// 생성자
public Shape(String color) {
this.color = color;
}
// 추상 메서드 : 도형 넓이 구하기 - 오버 라이드
abstract public void calculateArea();
// 일반 메서드 : 도형 색상 출력
public void getColor() {
System.out.println("도형 색상: " + color);
}
}
🔹하위 클래스1 Triangle
package _04_class._05_abstract.ex3;
public class Triangle extends Shape {
private int width;
private int height;
@Override
public void calculateArea() {
double result = width * height * 0.5;
System.out.println("도형 넓이: " + result);
}
// 생성자
public Triangle(String color, int width, int height) {
super(color);
this.width = width;
this.height = height;
}
}
생성자에 매개변수가 있는 상위 클래스를 상속 받으면, super()
*에 매개변수를 넘겨줘야 한다.
Shape에서 String color
를 받았으므로 같은 매개변수를 입력한다.
There is no default constructor available in '_04_class._05_abstract.ex3.Shape'
상위(부모) 생성자 호출하기 : super()
• 모든 객체는 생성자를 호출해야 생성된다.
• 상위 클래스가 기본 생성자라면? (=매개변수 없음)
하위 클래스 생성자 컴파일 과정에서 자동으로 추가되면서 부모 클래스의 기본 생성자를 호출.
• BUT 매개변수를 갖는 생성자만 있다면?
super()에 매개변수를 넣어주어야 한다.
calculateArea
를 오버라이드 해주어 도형 넓이를 구한다.똑같은 방식으로 Circle 클래스를 구현해준다. 다른 건 오버라이드 한 메서드 내용뿐!
🔸하위 클래스2 Circle
package _04_class._05_abstract.ex3;
public class Circle extends Shape {
private int width;
private int height;
@Override
public void calculateArea() {
System.out.println("도형 넓이: " + width * height);
}
// 생성자
public Circle(String color, int width, int height) {
super(color);
this.width = width;
this.height = height;
}
}
결과 보기
package _04_class._05_abstract.ex3;
public class ShapeEx {
public static void main(String[] args) {
Triangle triangle = new Triangle("green", 49, 5);
Circle circle = new Circle("yellow", 40, 12);
System.out.println("=== 삼각형 정보 ===");
triangle.getColor();
triangle.calculateArea();
System.out.println();
System.out.println("=== 직사각형 정보 ===");
circle.getColor();
circle.calculateArea();
}
}