浅谈java接口和抽象类的区别和使用


前言

继承是面向对象编程(OOP)的一个重要性质。它是Java中的一种机制,允许一个类继承另一个类的特性(字段和方法)。有两个主要的关键字,“extends”和“implements”,它们在Java中用于继承。


提示:以下是本篇文章正文内容,下面案例可供参考

一、接口和抽象类定义

接口(implements)

在Java中,implements关键字用于实现接口。接口是一种特殊类型的类,它实现了一个完整的抽象,只包含抽象方法。要访问接口方法,接口必须由另一个具有implements关键字的类“实现”,并且方法需要在继承接口属性的类中实现。由于接口没有方法的实现,所以类可以一次实现任意数量的接口。、
例子:

// Defining an interface 
interface One {
    
     
    public void methodOne(); 
} 
  
// Defining the second interface 
interface Two {
    
     
    public void methodTwo(); 
} 
  
// Implementing the two interfaces 
class Three implements One, Two {
    
     
    public void methodOne() 
    {
    
     
  
        // Implementation of the method 
    } 
  
    public void methodTwo() 
    {
    
     
  
        // Implementation of the method 
    } 
} 

多实现例子:


brightness_4
// Defining the interface One 
interface One { 
    void methodOne(); 
} 
  
// Defining the interface Two 
interface Two { 
    void methodTwo(); 
} 
  
// Interface extending both the 
// defined interfaces 
interface Three extends One, Two { 
} 

抽象(extends)

在Java中,extends关键字用于表示正在定义的类是使用继承从基类派生的。所以基本上,extends关键字用于将父类的功能扩展到子类。在Java中,不允许多重继承。因此,一个类只能扩展一个类以避免歧义。
例子:


class One {
    
     
    public void methodOne() 
    {
    
     
  
        // Some Functionality 
    } 
} 
  
class Two extends One {
    
     
  
    public static void main(String args[]) 
    {
    
     
        Two t = new Two(); 
  
        // Calls the method one 
        // of the above class 
        t.methodOne(); 
    } 
} 

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、对比接口和抽象

序号\类 接口 (implements) 抽象(extends)
1 通过使用“implements”关键字,类可以实现接口 通过使用“extends”关键字,一个类可以继承另一个类,或者一个接口可以继承其他接口
2 实现接口的类必须实现该接口的所有方法 扩展超类的子类不一定要覆盖超类中的所有方法
3 一个类一次可以实现任意数量的接口 一个类只能扩展一个超类
3 一个接口永远不能实现任何其他接口 可以通过接口扩展任意数量的接口

三、使用场景

四、扩展

Java 8 以后,接口也是可以有方法实现的

从 Java 8 开始,interface 增加了对 default method 的支持。Java 9 以后,甚至可以定义 private default method。Default method 提供了一种二进制兼容的扩展已有接口的办法。比如,我们熟知的 java.util.Collection,它是 collection 体系的 root interface,在 Java 8 中添加了一系列 default method,主要是增加 Lambda、Stream 相关的功能。我在专栏前面提到的类似 Collections 之类的工具类,很多方法都适合作为 default method 实现在基础接口里面。

public interface Collection<E> extends Iterable<E> {
     /**
     * Returns a sequential Stream with this collection as its source 
     * ...
     **/
     default Stream<E> stream() {
         return StreamSupport.stream(spliterator(), false);
     }
  }


总结

1 要对面向对象三特性:封装,继承,多态要有较深的理解,修炼内功时时刻刻都要做的事情。
2 了解最基本的设计原则在日常开发中是必须的,SOLID 设计模式的六大原则要掌握(后续我会在博客里添加相关内容)。
单一职责(Single Responsibility),类或者对象最好是只有单一职责,在程序设计中如果发现某个类承担着多种义务,可以考虑进行拆分。

开关原则(Open-Close, Open for extension, close for modification),设计要对扩展开放,对修改关闭。换句话说,程序设计应保证平滑的扩展性,尽量避免因为新增同类功能而修改已有实现,这样可以少产出些回归(regression)问题。

扫描二维码关注公众号,回复: 12098868 查看本文章

里氏替换(Liskov Substitution),这是面向对象的基本要素之一,进行继承关系抽象时,凡是可以用父类或者基类的地方,都可以用子类替换。

接口分离(Interface Segregation),我们在进行类和接口设计时,如果在一个接口里定义了太多方法,其子类很可能面临两难,就是只有部分方法对它是有意义的,这就破坏了程序的内聚性。
对于这种情况,可以通过拆分成功能单一的多个接口,将行为进行解耦。在未来维护中,如果某个接口设计有变,不会对使用其他接口的子类构成影响。

依赖反转(Dependency Inversion),实体应该依赖于抽象而不是实现。也就是说高层次模块,不应该依赖于低层次模块,而是应该基于抽象。实践这一原则是保证产品代码之间适当耦合度的法宝。

猜你喜欢

转载自blog.csdn.net/aa327056812/article/details/109600518