JAVA抽象类语法中 默认方法 和 普通方法(Concrete Method) 有什么区别?

本文详细介绍了Java中抽象类的概念,包括抽象方法和默认方法的区别,以及它们在类结构中的使用场景。还通过实例展示了如何在实际项目中运用这些概念,以及黑马程序员的Java教程涉及的相关内容。
摘要由CSDN通过智能技术生成

在Java中,抽象类是一种特殊的类,不能被实例化,通常用于定义具有某种通用行为但又需要子类来具体实现的类。抽象类中可以包含抽象方法和具体方法(也称为默认方法或者具体实现方法),两者在语法和功能上有一些区别。

抽象类概述

首先,让我们来看看抽象类的基本概念。抽象类是一种不能实例化的类,它用于定义一种抽象的概念或者行为,并且可能包含具体的方法和抽象方法。抽象方法是一种没有具体实现的方法,而是由具体的子类来实现。一个类如果包含抽象方法,那么这个类必须被声明为抽象类。

abstract class Animal {
    abstract void makeSound(); // 抽象方法
    void eat() {
        System.out.println("Animal is eating"); // 具体方法
    }
}

在上面的例子中,Animal 是一个抽象类,它包含了一个抽象方法 makeSound() 和一个具体方法 eat()

抽象类中的默认方法

从Java 8开始,Java引入了接口默认方法(default methods),允许在接口中定义具有默认实现的方法。而在Java 9中,这个特性也被引入到了抽象类中,允许在抽象类中定义具有默认实现的方法,这些方法被称为默认方法。

abstract class Animal {
    abstract void makeSound(); // 抽象方法
    
    // 默认方法
    default void eat() {
        System.out.println("Animal is eating");
    }
}

在这个例子中,eat() 方法被声明为默认方法,它提供了一个默认的实现。子类可以选择重写它,也可以直接继承默认实现。

区别分析

现在让我们来看看默认方法和普通方法之间的区别:

1、方法实现

  • 默认方法在抽象类中有默认的实现,而普通方法则需要在抽象类中提供具体的实现。

2、覆盖(Override)

  • 默认方法可以被子类覆盖,子类可以选择是否重写默认方法;而普通方法必须被子类覆盖,否则子类就必须声明为抽象类。

3、继承

  • 默认方法可以被子类直接继承,而普通方法必须被子类实现或者覆盖。

4、多继承冲突

  • 当一个类实现多个接口,而这些接口中有相同签名的默认方法时,编译器会报错,需要手动解决冲突;而抽象类中的默认方法不存在这样的问题。

5、版本支持

  • 默认方法在Java 8及之后版本中引入;而普通方法在Java的早期版本中就已经存在。

6、使用场景

  • 默认方法通常用于接口,用于为接口添加新的方法而不影响已有的实现;而抽象类中的默认方法通常用于为子类提供通用的实现,子类可以选择性地覆盖它们。

示例

abstract class Animal {
    abstract void makeSound(); // 抽象方法
    
    // 默认方法
    default void eat() {
        System.out.println("Animal is eating");
    }
    
    // 普通方法
    void sleep() {
        System.out.println("Animal is sleeping");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog is barking");
    }
    
    // 可以选择性地覆盖默认方法
    @Override
    void eat() {
        System.out.println("Dog is eating");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Cat is meowing");
    }
    
    // 可以选择性地继承默认方法
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.makeSound(); // 输出:Dog is barking
        dog.eat();       // 输出:Dog is eating
        dog.sleep();     // 输出:Animal is sleeping
        
        Animal cat = new Cat();
        cat.makeSound(); // 输出:Cat is meowing
        cat.eat();       // 输出:Animal is eating
        cat.sleep();     // 输出:Animal is sleeping
    }
}

在上面的示例中,Animal 是一个抽象类,它包含了一个抽象方法 makeSound()、一个默认方法 eat() 和一个普通方法 sleep()DogCatAnimal 的子类,它们分别实现了 makeSound() 方法,并选择性地覆盖了 eat() 方法。在 Main 类中,我们可以看到如何使用抽象类中的默认方法和普通方法。

总的来说,抽象类中的默认方法和普通方法都是为了提供一种通用的实现,但它们在语法和功能上有一些区别,开发者可以根据具体的需求来选择使用哪种方法。

黑马程序员Java零基础视频教程_上部(Java入门,含斯坦福大学练习题+力扣算法题和大厂java面试题)

黑马程序员Java零基础视频教程_下部(Java入门,含斯坦福大学练习题+力扣算法题和大厂java面试题)

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值