웹사이트 검색

Java 예제의 상속


Java의 상속은 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 객체 간에 is-a 관계가 있을 때 Java 상속이 사용됩니다. Java의 상속은 extends 키워드를 사용하여 구현됩니다.

자바의 상속

Java에서 상속은 다른 클래스로부터 상속하여 클래스 간의 계층 구조를 만드는 방법입니다.

Java 상속은 전이적이므로 Sedan이 Car를 확장하고 Car가 Vehicle을 확장하면 Sedan도 Vehicle 클래스에서 상속됩니다. Vehicle은 Car와 Sedan의 슈퍼클래스가 됩니다.

상속은 Java 응용 프로그램에서 널리 사용됩니다. 예를 들어 Exception 클래스를 확장하여 오류 코드와 같은 추가 정보를 포함하는 응용 프로그램별 Exception 클래스를 생성합니다. 예를 들어 NullPointerException.

Java 상속 예제

Java의 모든 클래스는 암시적으로 java.lang.Object 클래스를 확장합니다. 따라서 Object 클래스는 Java에서 상속 계층 구조의 최상위 수준에 있습니다.

간단한 예제를 통해 Java에서 상속을 구현하는 방법을 살펴보겠습니다.

슈퍼클래스: 동물

package com.journaldev.inheritance;

public class Animal {

	private boolean vegetarian;

	private String eats;

	private int noOfLegs;

	public Animal(){}

	public Animal(boolean veg, String food, int legs){
		this.vegetarian = veg;
		this.eats = food;
		this.noOfLegs = legs;
	}

	public boolean isVegetarian() {
		return vegetarian;
	}

	public void setVegetarian(boolean vegetarian) {
		this.vegetarian = vegetarian;
	}

	public String getEats() {
		return eats;
	}

	public void setEats(String eats) {
		this.eats = eats;
	}

	public int getNoOfLegs() {
		return noOfLegs;
	}

	public void setNoOfLegs(int noOfLegs) {
		this.noOfLegs = noOfLegs;
	}

}

여기서 Animal은 기본 클래스입니다. Animal 클래스를 상속받은 Cat 클래스를 만들어 봅시다.

하위 클래스: 고양이

package com.journaldev.inheritance;

public class Cat extends Animal{

	private String color;

	public Cat(boolean veg, String food, int legs) {
		super(veg, food, legs);
		this.color="White";
	}

	public Cat(boolean veg, String food, int legs, String color){
		super(veg, food, legs);
		this.color=color;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

}

Java에서 상속을 구현하기 위해 extends 키워드를 사용하고 있음에 유의하십시오.

Java 상속 테스트 프로그램

간단한 테스트 클래스를 작성하여 Cat 개체를 만들고 그 메서드 중 일부를 사용해 봅시다.

package com.journaldev.inheritance;

public class AnimalInheritanceTest {

	public static void main(String[] args) {
		Cat cat = new Cat(false, "milk", 4, "black");

		System.out.println("Cat is Vegetarian?" + cat.isVegetarian());
		System.out.println("Cat eats " + cat.getEats());
		System.out.println("Cat has " + cat.getNoOfLegs() + " legs.");
		System.out.println("Cat color is " + cat.getColor());
	}

}

산출:

Cat 클래스에는 getEats() 메서드가 없지만 여전히 Animal 클래스에서 상속되었기 때문에 프로그램이 작동합니다.

중요 사항

  1. Code reuse is the most important benefit of inheritance because subclasses inherits the variables and methods of superclass.

  2. Private members of superclass are not directly accessible to subclass. As in this example, Animal variable noOfLegs is not accessible to Cat class but it can be indirectly accessible via getter and setter methods.

  3. Superclass members with default access is accessible to subclass ONLY if they are in same package.

  4. Superclass constructors are not inherited by subclass.

  5. If superclass doesn’t have default constructor, then subclass also needs to have an explicit constructor defined. Else it will throw compile time exception. In the subclass constructor, call to superclass constructor is mandatory in this case and it should be the first statement in the subclass constructor.

  6. Java doesn’t support multiple inheritance, a subclass can extends only one class. Animal class is implicitly extending Object class and Cat is extending Animal class but due to java inheritance transitive nature, Cat class also extends Object class.

  7. We can create an instance of subclass and then assign it to superclass variable, this is called upcasting. Below is a simple example of upcasting:

    Cat c = new Cat(); //subclass instance
    Animal a = c; //upcasting, it's fine since Cat is also an Animal
    
  8. When an instance of Superclass is assigned to a Subclass variable, then it’s called downcasting. We need to explicitly cast this to Subclass. For example;

    Cat c = new Cat();
    Animal a = c;
    Cat c1 = (Cat) a; //explicit casting, works fine because "c" is actually of type Cat
    

    Note that Compiler won’t complain even if we are doing it wrong, because of explicit casting. Below are some of the cases where it will throw ClassCastException at runtime.

    Dog d = new Dog();
    Animal a = d;
    Cat c1 = (Cat) a; //ClassCastException at runtime
    
    Animal a1 = new Animal();
    Cat c2 = (Cat) a1; //ClassCastException because a1 is actually of type Animal at runtime
    
  9. We can override the method of Superclass in the Subclass. However we should always annotate overridden method with @Override annotation. The compiler will know that we are overriding a method and if something changes in the superclass method, we will get a compile-time error rather than getting unwanted results at the runtime.

  10. We can call the superclass methods and access superclass variables using super keyword. It comes handy when we have the same name variable/method in the subclass but we want to access the superclass variable/method. This is also used when Constructors are defined in the superclass and subclass and we have to explicitly call the superclass constructor.

  11. We can use instanceof instruction to check the inheritance between objects, let’s see this with below example.

```
Cat c = new Cat();
Dog d = new Dog();
Animal an = c;

boolean flag = c instanceof Cat; //normal case, returns true

flag = c instanceof Animal; // returns true since c is-an Animal too

flag = an instanceof Cat; //returns true because a is of type Cat at runtime

flag = an instanceof Dog; //returns false for obvious reasons.
```

  1. Java에서는 Final 클래스를 확장할 수 없습니다.
  2. 코드에서 슈퍼클래스를 사용하지 않으려는 경우, 즉 슈퍼클래스가 재사용 가능한 코드를 유지하기 위한 기반일 뿐이라면 클라이언트 클래스에 의한 불필요한 인스턴스화를 피하기 위해 추상 클래스로 유지할 수 있습니다. 또한 기본 클래스의 인스턴스 생성을 제한합니다.

Java 상속 비디오 자습서

저는 최근에 샘플 프로그램과 함께 상속에 대해 자세히 설명하는 두 개의 비디오를 YouTube에 게시했습니다. 아래에서 시청해야 합니다.

GitHub 리포지토리에서 더 많은 상속 예제를 확인할 수 있습니다.

참조: 오라클 문서