抽象类、接口

Java知识点总结:想看的可以从这里进入

目录

    • 4、 抽象类和接口
      • 4.1、 抽象类
      • 4.2、接口
      • 4.3、区别

4、 抽象类和接口


4.1、 抽象类

用 abstract 关键字修饰的类就是抽象类,用 abstract 关键字修饰的方法就是抽象方法(不能用abstract修饰变量、代码块、构造器)

抽象方法只定义结构,而没有具体的实现,其实现是交给子孙类去实现的。有抽象方法的类必定是抽象类,但抽象类并一定有抽象方法(抽象类可以有普通方法也可以用抽象方法)。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。所以抽象类需要有子孙类去继承实现其全部抽象方法,继承抽象类的子类必须实现父类全部抽象方法,否则自身也要设置为抽象类。因为抽象方法本身没有任何意义,所以抽象方法必须要被重写去具体实现的(类的所有抽象方法都要实现)。

抽象类存在的意义在于其设计性、复用性与扩展性。从开发的实际要求来讲,普通类尽量不要去继承另外一个普通类,而是去继承抽象类。

抽象类、接口_第1张图片

抽象类、接口_第2张图片

abstract修饰的抽象方法和某些关键字是有冲突的:

1、final修饰方法时表示方法不能被子类重写,抽象方法必定要被子类重写,所以不能在一起使用。

2、static是静态方法,属于类,而抽象方法需要被子类继承和实现,所以不能同用。

3、native表示该方法要使用另一种依赖平台的编程语言实现,不存在子类继承的问题,所以不能使用。

4、synchronized是线程同步,而abstract抽象方法只声明没有实现,所以不存在同步,不能同用。(可以在实现该方法的子类内使用)

5、private的含义是私有,即不让自己外的其他类所知晓,只在自身内部调用,而抽象方法本身就是需要子类去实现的且是一个空方法,所以这两者是不能同用的

4.2、接口

我们知道,在Java中一个类只能去继承一个父类,那么这在某些时候就有很大的局限性了。所以就出现了接口(interface)这个概念,它和类是并列的两种结构,在Java 中规定一个类可以去实现多个接口(单继承多实现)。

接口是对行为的抽象,内部不能有具体的方法(jdk7及以前版本由全局常量和公共的抽象方法所组成,jdk8后可以有default默认方法和静态方法),接口也无法被实例化,类一旦实现接口就要实现接口内的所有方法。

接口和抽象类不同,抽象了是为了方便代码复用和扩展,而接口更多的是为了提供服务和规范(本质上接口也可以看成是特殊的抽象类)。打个比喻:

  1. 接口:就类似家中的插座,它有两个插口和三个插口,但是插座是不关心电器种类的,只要电器只要符合插口,就可以使用插座,接通电源。
  2. 抽象类:就像手机,最早大哥大只有通话功能,后来出现了带有操作界面的手机,最后又演变成现在的智能手机,它的功能是继承了原有手机的功能后,再此基础上再增加新功能。

接口通常用来定义规范,很大程度上就是运用了向上转型的概念。类使用 implements 关键字实现接口,如果类还继承了其他类,写在extend之后:public class Test extends ClassA implements InterfaceA,InterfaceB{ }。

抽象类、接口_第3张图片
  • 接口不能用于实例化对象,内部没有构造方法。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。

  • JDK 1.8 以后,接口里可以有静态方法和方法体,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。

    • 其中静态方法其实现类和对象不能使用,只能通过接口来调用

    • 而默认的 default 方法可以由实现类的对象来调用,也可以被实现类重写(重写后的default就是一个普通的方法),重写后调用的是实现类重写后的方法。

      • 一个接口中定义了一个默认方法,而其实现类的父类中也定义了一个同名同参数的非抽象方法,不会出现冲突问题,因为接口中具有相同名称和参数的默认方法会被忽略。这就是:类优先原则。

      • 如果类实现了多个接口,而这些接口中存在同名同参的默认方法,在实现类没有重写该方法的情况下,会出现接口冲突的错误,所以实现类必须重写该默认方法。

      public interface InterfaceTest {
          //抽象方法
          void test();
          //默认方法
          default void interfaceTest(){
              System.out.println("JDK8增加的默认方法,非抽象");
          }
          //静态方法
          static void staticTest(){
              System.out.println("接口中的静态方法,不能被实现类重写");
          }
      }
      
      class ImplementsInterfaceTest implements InterfaceTest{
          @Test
          public void mainTest(){
              //静态方法由接口调用
              InterfaceTest.staticTest();
              ImplementsInterfaceTest test = new ImplementsInterfaceTest();
              //可有实现类的对象来调用默认的方法
              test.interfaceTest();
          }
      
          @Override
          public void test() {
          }
          //原来是默认的方法,可以实现也可以不实现,实现的默认方法为普通类
          @Override
          public void interfaceTest() {
              InterfaceTest.super.interfaceTest();
          }
      }
      

      抽象类、接口_第4张图片

  • 接口中可以有变量和方法,并且接口中的变量会被隐式的被public static final来修饰,并且只能用public static final来修饰,方法会隐式的被 public abstract来修饰,并且只能用来public abstract来修饰。

  • 接口和接口之间也可以继承,接口之间是可以多继承的

  • 接口不是被类继承了,而是要被类实现。一个类可以实现多个接口

//接口的声明
[public] interface 接口名 [extends 其他接口]{
	//变量
    int ID = 1;    //实际上就是:public static final int ID = 1;
    //方法
    void test();  //实际上就是:public abstract void test();
}

拿电脑来说,电脑上有很多的接口,其中有USB接口。而键盘、鼠标、耳机等,只要符合USB接口的规范就可以连接到电脑上。对比来说接口的功能就类似于USB,定义好后就只要符合了接口的规范,就可以使用

  • 定义一个电脑

    public class Computer{
        //电脑定义一个USB的接口,只要符合USB接口就能在电脑上工作
        private USB usb;
        public void setUsb(USB usb){
            this.usb = usb;
        }
        public void work(){
            if(usb != null){
                System.out.println("USB设备正在工作");
                usb.write();
            }
        }
    }
    
  • 定义USB接口

    public interface USB {
        void read();	//定义了读写的方法
        void write();
    }
    
  • 定义键盘鼠标,实现USB接口

    //定义一个键盘一个鼠标,符合USB接口的规范
    public class Keyboard implements USB {
        public void Knock(){
            System.out.println("敲击键盘");
        }
        @Override
        public void read() {}
        @Override
        public void write() {
            this.Knock();
        }
    }
    
    public class Mouse implements USB {
        public  void rClick(){
            System.out.println("点击右键");
        }
        public void lClick(){
            System.out.println("点击左键");
        }
        @Override
        public void read() {
        }
        @Override
        public void write() {
            this.rClick();
            this.lClick();
        }
    }
    
  • 键盘鼠标通过电脑进行工作

    抽象类、接口_第5张图片

4.3、区别

接口与类的区别:

1、接口不能用于实例化对象。
2、接口没有构造方法。
3、接口中所有的方法必须是抽象方法。
4、接口不能包含成员变量,除了 static 和 final 变量。
5、接口不是被类继承了,而是要被类实现。
6、接口支持多继承。

接口和抽象类的区别

1、一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2、接口中的成员变量只能是 public、static、final类型的,抽象类中可以定义各种类型的实例变量和静态变量
3、抽象类可以有构造方法,接口中不能有构造方法。
4、抽象类中可以包含非抽象的方法,而接口在jdk7之前只能有抽象方法,在jdk8中增加了default 方法、静态方法等。jdk9中又支持私有方法、私有静态方法。
4、接口主要在系统架构设计上发挥作用,用于定义模块间的通信契约。抽象类主要在代码实现上使用。可以实现代码的重用。
5、抽象类中的方法类型可以是任意修饰符,Java 8 之前接口中的方法只能是 public 类型,Java 9 支持 private 类型。

在设计思想上,

接口主要是对类的行为进行约束,它只约束类行为的有无,对行为的具体实现不做规定。接口只定义行为,类的主体怎么实现,接口不关心。是like a 的关系。所以接口主要用于架构的不同模块之间的通信契约。

抽象类主要是为了实现代码的复用,当两个以上的类的某些方法的一部分具有相同实现的情况下,通常会把这些相同的行为抽象出来,做成抽象类,在继承了这些功能后还能自己扩展属于自己的功能。抽象类是对本质进行抽象,子类至少是一个父类,is a。

你可能感兴趣的:(#,JavaSE,java,抽象类,接口)