Bài tập tính kế thừa trong java có lời giải

Kế thừa giúp làm giảm code dư thừa, nâng cao và giúp dễ dàng mở rộng chương trình. Trong bài viết này, chúng ta sẽ tìm hiểu về bài tập kế thừa trong java có lời giải và áp dụng vào thực hành xây dựng lớp sinh viên kế thừa từ lớp người.

Xem thêm:

1. Khái niệm về tính kế thừa java

Kế thừa trong Java là mối quan hệ mà trong đó các class có liên kết chặt chẽ với nhau. Cụ thể hơn là class cha (superclass) và class con (subclass). Quan hệ kế thừa này là class con được hưởng toàn bộ các phương thức và thuộc tính mà class cha đã định nghĩa.

Tóm lại, kế thừa chính là tạo một class mới dựa trên cấu trúc của các class đã tồn tại.

Phạm vi truy cập:

Thừa kế trong Java cũng phải tuân thủ nghiêm ngặt các quy định về phạm vi truy cập. Class con có thể truy cập vào các phương thức publicprotected của class cha. Nhưng các phương thức chế độ private của class cha sẽ bị giới hạn truy cập, tức là class con không có quyền truy cập đến chúng.

Các thuật ngữ:

  • Lớp cha (Superclass):Lớp mà các thuộc tính và phương thức được kế thừa bởi lớp con.
  • Lớp con (Subclass): Lớp kế thừa các thuộc tính và phương thức từ lớp cha.
  • extends: Từ khóa dùng để chỉ rõ lớp con kế thừa từ lớp cha.
  • super: Từ khóa dùng để truy cập các thuộc tính và phương thức của lớp cha từ lớp con.

2. Cú pháp kế thừa trong java

Để kế thừa một class trong Java, ta sử dụng từ khoá “extends”. Class được kế thừa được gọi là class cha và class kế thừa được gọi là class con.

class TenClassCon extends TenClassCha{
}

3. Ví dụ kế thừa trong java

Ví dụ:

  • Lớp Animal là lớp cha có một thuộc tính name và một phương thức makeSound.
  • Lớp Dog là lớp con của Animal, kế thừa thuộc tính name và phương thức makeSound từ lớp cha, và mở rộng phương thức makeSound bằng cách ghi đè (override) để thêm hành vi mới.
  • Lớp Dog cũng có một phương thức riêng là wagTail.
  • Trong phần main, chúng ta tạo một đối tượng của lớp Animal và một đối tượng của lớp Dog, và gọi các phương thức của chúng. Phương thức makeSound sẽ hoạt động khác nhau vì phương thức này được ghi đè trong lớp con Dog.
// Lớp cha (superclass)
class Animal {
    String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    public void makeSound() {
        System.out.println("Animal sound");
    }
}

// Lớp con (subclass) kế thừa từ lớp cha Animal
class Dog extends Animal {
    public Dog(String name) {
        super(name); // Gọi constructor của lớp cha
    }
    
    // Phương thức này được mở rộng từ lớp cha
    @Override
    public void makeSound() {
        System.out.println("Bark");
    }
    
    // Phương thức riêng của lớp con Dog
    public void wagTail() {
        System.out.println(name + " is wagging tail");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal("Generic Animal");
        animal.makeSound(); // In ra "Animal sound"
        
        Dog dog = new Dog("Buddy");
        dog.makeSound(); // In ra "Bark"
        dog.wagTail();   // In ra "Buddy is wagging tail"
    }
}

4. Bài tập xây dựng lớp sinh viên kế thừa từ lớp người

4.1 Mô tả bài toán

Bài 12: Xây dựng lớp Nguoi với các thuộc tính Hoten, Gioitinh và phương thức: Nhap(), Hien().

– Xây dựng lớp học sinh thừa kế từ lớp Người với thuộc tính: TenLop và phương thức Nhap(), Hien().

– Viết chương trình:

+ Nhập vào N học sinh của các lớp khác nhau.

+ Sắp xếp danh sách học sinh theo tên lớp, hiện danh sách ra màn hình

4.2. Code

  • Class Nguoi
package bai12;

import java.util.Scanner;


public class Nguoi {
    String hoTen, gioiTinh;

    public Nguoi(){
        
    }
    
    public Nguoi(String hoTen, String gioiTinh){
        this.hoTen=hoTen;
        this.gioiTinh=gioiTinh;
    }
    
    public String getHoTen() {
        return hoTen;
    }

    public void setHoTen(String hoTen) {
        this.hoTen = hoTen;
    }

    public String getGioiTinh() {
        return gioiTinh;
    }

    public void setGioiTinh(String gioiTinh) {
        this.gioiTinh = gioiTinh;
    }
    
    public void nhap(){
        Scanner sc = new Scanner(System.in);
        System.out.println("Nhap ho va ten: ");
        hoTen= sc.nextLine();
        System.out.println("Nhap gioi tinh: ");
        gioiTinh = sc.nextLine();
    }
    
    public void hien(){
        System.out.printf("%-25s %-15s",getHoTen(),getGioiTinh());
    }
    
}
  • Class HocSinh
package bai12;

import java.util.Scanner;

public class HocSinh extends Nguoi{
    String tenLop;
    
    public HocSinh(){
        
    }
    
    public HocSinh(String hoTen, String gioiTinh,String tenLop){
        super(hoTen, gioiTinh);
        this.tenLop=tenLop;
    }

    public String getTenLop() {
        return tenLop;
    }

    public void setTenLop(String tenLop) {
        this.tenLop = tenLop;
    }
    
    public void nhapHS(){
        super.nhap();
        Scanner sc = new Scanner(System.in);
        System.out.println("Nhap ten lop: ");
        tenLop= sc. nextLine();
    }
    
    public void xuatHS(){
        super.hien();
        System.out.printf("%-10s",getTenLop());
    }
}
  • Class DanhSachHocSinh
package bai12;

import java.util.ArrayList;
import java.util.Scanner;

public class DanhSachHocSinh {
    ArrayList<HocSinh> ds = new ArrayList<>();
    int n;
    Scanner sc = new Scanner(System.in);
    
    public void nhapDS(){
        System.out.println("Nhap so luong hoc sinh: ");
        n=sc.nextInt();
        for(int i=0;i<n;i++){
            HocSinh x= new HocSinh();
            System.out.println("Nhap hoc sinh thu"+ (i+1));
            x.nhapHS();
            ds.add(x);
        }
    }
    
    public void hienDS(){
        System.out.println("Danh sach hoc sinh: ");
        System.out.printf("%-25s%-15s%-10s","Ho ten","Gioi tinh","Lop");
        for(int i=0;i<n;i++){
            System.out.println("");
            ds.get(i).xuatHS();
        }
        System.out.println("");
    }
    
    public void sapXep(){
        HocSinh tg;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(ds.get(i).getTenLop().compareTo(ds.get(j).getTenLop())>0){
                    tg= ds.get(i);
                    ds.set(i, ds.get(j));
                    ds.set(j, tg);
                }
            }
        }
        
        System.out.println("Danh sach hoc sinh theo ten lop la: ");
        hienDS();
    }
    
}
  • Class main
package bai12;

import java.util.Scanner;

public class Bai12 {

    static void menu(){
        System.out.println("1. Nhap danh sach hoc sinh");
        System.out.println("2. Xuat danh sach hoc sinh");
        System.out.println("3. Sap xep danh sach hoc sinh theo lop");
        System.out.println("0. Thoat");
    }
    public static void main(String[] args) {
        int chon;
        Scanner sc = new Scanner(System.in);
        DanhSachHocSinh dshs= new DanhSachHocSinh();
        do {            
            menu();
            System.out.println("Lua chon: ");
            chon= sc.nextInt();
            switch(chon){
                case 1: dshs.nhapDS(); break;
                case 2: dshs.hienDS(); break;
                case 3: dshs.sapXep(); break;
                case 0: System.exit(0); break;
                default: break;
            }
        } while (chon!=0);
    }
    
}

4.3 Kết quả chạy chương trình

Source code:

5. Các kiểu kế thừa trong java

Các kiểu kế thừa java

6. Phân Biệt Tính Kế Thừa Và Tính Đa Hình Trong Java

6.1 Tính kế thừa trong Java

Như đã giải thích ở trên, tính kế thừa là khả năng của một class kế thừa các thuộc tính, phương thức của một class khác. Mục tiêu chính của tính kế thừa là tạo ra một cấu trúc phân cấp giữa các lớp và cho phép code được tái sử dụng, giúp giảm bớt công sức viết code từ đầu.

6.2 Tính đa hình trong Java

Trong khi đó, tính đa hình là khả năng của một đối tượng thuộc một class nhất định có thể được xem như của một class khác. Điều này cho phép lập trình viên sử dụng một loạt các đối tượng thuộc các lớp khác nhau nhưng có cùng một giao diện chung.

6.3 Tương quan giữa tính kế thừa và tính đa hình

Tính kế thừa và tính đa hình có mối quan hệ chặt chẽ. Trên thực tế, không thể có đa hình mà không có kế thừa, vì đa hình yêu cầu một class con có thể được coi như một class cha. Hơn nữa, cả hai đều là cơ sở quan trọng của việc lập trình hướng đối tượng, giúp code trở nên linh hoạt, dễ mở rộng và bảo trì hơn.

7. Ưu nhược điểm của tính kế thừa

7.1 Ưu điểm của kế thừa trong Java

  • Tái sử dụng code: Kế thừa cho phép sử dụng lại mã nguồn từ các lớp hiện có để tạo ra các lớp mới, giúp giảm thiểu việc lặp lại viết mã và tăng tính tái sử dụng của mã.
  • Dễ dàng bảo trì: Kế thừa giúp tách biệt các tính năng khác nhau của một chương trình thành các lớp khác nhau, giúp cho việc bảo trì và phát triển chương trình dễ dàng hơn.
  • Mở rộng tính năng: Kế thừa cho phép mở rộng tính năng của một lớp hiện có bằng cách thêm các tính năng mới vào lớp con.
  • Tăng tính linh hoạt: Kế thừa giúp tăng tính linh hoạt của chương trình, cho phép thay đổi hoặc bổ sung các tính năng của chương trình một cách dễ dàng hơn.

7.2 Nhược điểm của kế thừa trong Java

  • Nếu không được thiết kế đúng cách, kế thừa có thể dẫn đến mối quan hệ phức tạp giữa các lớp và tăng độ phức tạp của mã.
  • Kế thừa có thể dẫn đến việc đồng bộ hóa các lớp con với các lớp cha, khiến cho việc thay đổi một lớp có thể dẫn đến các thay đổi phức tạp trong các lớp con.
  • Kế thừa cũng có thể dẫn đến việc tạo ra các lớp con không cần thiết, khiến cho chương trình trở nên khó hiểu và khó bảo trì.
  • Kế thừa cũng có thể giới hạn tính đa hình của chương trình, khiến cho chương trình trở nên khó mở rộng và khó bảo trì.

Câu hỏi liên quan

1. Tính kế thừa trong Java là gì?

Tính kế thừa trong Java là một khái niệm hướng đối tượng cho phép một class kế thừa thuộc tính và phương thức của class cha, cho phép tái sử dụng code và tạo cấu trúc class phân cấp.

2. Class con có thể kế thừa từ nhiều class cha không?

Không, trong Java một class chỉ có thể kế thừa từ một class cha duy nhất. Điều này nghĩa là Java không hỗ trợ đa kế thừa nhiều lớp.

3. Các thuộc tính private trong class cha có được kế thừa không?

Không, các thuộc tính và phương thức định là private trong class cha không được class con kế thừa. Chỉ những thuộc tính và phương thức định là public hoặc protected mới được class con kế thừa và truy cập.

4. Tính kế thừa có liên quan gì đến tính đa hình không?

Có, tính kế thừa và tính đa hình có mối quan hệ chặt chẽ. Để thực hiện được tính đa hình (một đối tượng có thể được xem như đối tượng của class khác), chúng ta cần sự hỗ trợ của tính kế thừa.

5. java có đa kế thừa không?

Java không hỗ trợ đa kế thừa trực tiếp thông qua các lớp (classes) như một số ngôn ngữ khác (ví dụ như C++). Điều này có nghĩa là trong Java, một lớp chỉ có thể kế thừa từ một lớp cha duy nhất.

Ví dụ: Giả sử có các lớp sau:

  • Lớp A có một phương thức display().
  • Lớp B và lớp C đều kế thừa từ lớp A và cũng ghi đè (override) phương thức display().
  • Lớp D kế thừa từ cả lớp B và lớp C.

Khi gọi phương thức display() trong lớp D, chương trình sẽ không biết nên dùng phiên bản nào của phương thức từ lớp A. Điều này gây ra sự mơ hồ và lỗi tiềm ẩn.

Cách Java xử lý đa kế thừa bằng Interfaces:

interface A {
    void display();
}

interface B {
    void display();
}

class C implements A, B {
    @Override
    public void display() {
        System.out.println("Implementing display method");
    }
}

Cảm ơn bạn đã theo dõi bài viết này trên ttnguyen.net. Hy vọng rằng nó đã giúp bạn hiểu rõ hơn về cách sử dụng kế thừa trong Java qua bài tập lập trình hướng đối tượng java có lời giải.

Bài viết liên quan:

Nguyễn Tiến Trường

Mình viết về những điều nhỏ nhặt trong cuộc sống, Viết về câu chuyện những ngày không có em