解析JavaSe的抽象类和接口

目录
  • 1. 抽象类和抽象方法
  • 2. 相关面试题
    • 1、抽象类必须要有抽象方法吗?
    • 2、普通类和抽象类有哪些区别?
    • 3、抽象类能使用 final 修饰吗?
  • 3. 接口
    • 3.1 接口中的常量
    • 3.2 接口中的方法
      • 3.2.1 接口中的普通方法
      • 3.2.2 接口中的静态方法
      • 3.2.3 接口中的默认方法
    • 3.3 接口中的接口和枚举类
    • 3.4 接口和抽象类
  • 总结

1. 抽象类和抽象方法

抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。抽象方法和抽象类的规则如下:

(1) 抽象类和抽象方法必须使用abstract修饰符来修饰,抽象方法不能有方法体。

(2) 抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。

(3) 抽象类可以包含Field、方法、构造器、初始化块、内部类、枚举类6种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。

(4) 含有抽象方法的类只能被定义成抽象类。

(5) abstract不能用于修饰Field,不能用于修饰局部变量,即没有抽象变量、没有抽象Field等说法;abstract也不能用于修饰构造器,没有抽象构造器,抽象类里定义的构造器只能是普通构造器。

定义抽象方法只需在普通方法上增加abstract修饰符,并把普通方法的方法体(也就是方法后花括号括起来的部分)全部去掉,并在方法后增加分号即可。

public abstract class Person {
    // 初始化块
    {
        System.out.println("执行Person类的初始化块");
    }
    private int age;
    // 该构造器并不是为了创建对象,而是为了子类调用
    public Person(){
    }
    public Person(int age){
        this.age = age;
    }
    // 抽象方法,没有方法体
    public abstract void show();
    public void test(){
        System.out.println("非抽象方法");
    }
}

抽象类不能用于创建实例,只能当作父类被其他子类继承。

public class Student extends Person {
    public Student(int age){
        super(age);
    }
    @Override
    public void show() {
        System.out.println("重写抽象类中的抽象方法");
    }
}

注意:

(1) 当使用abstract修饰类时,表明这个类只能被继承;当使用abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。而final修饰的类不能被继承,final修饰的方法不能被重写。因此final和abstract永远不能同时使用。

(2) 当使用static修饰一个方法时,表明这个方法属于该类本身,即通过类就可调用该方法,但如果该方法被定义成抽象方法,则将导致通过该类来调用该方法时出现错误(调用了一个没有方法体的方法肯定会引起错误)。因此static和abstract不能同时修饰某个方法,即没有所谓的类抽象方法。

(3) 抽象类不能创建实例,只能当成父类来被继承。从语义的角度来看,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。

2. 相关面试题

1、抽象类必须要有抽象方法吗?

抽象类不一定非要有抽象方法,抽象类中可以含有抽象方法和非抽象方法,可以只含有抽象方法,也可以只含有非抽象方法

public abstract class Person {
    public void test(){
        System.out.println("非抽象方法");
    }
}

2、普通类和抽象类有哪些区别?

(1) 普通类不能包含抽象方法,抽象类可以包含抽象方法。

(2) 抽象类不能直接实例化,只能当作父类被其他子类继承,普通类可以直接实例化。

public abstract class Person {
    // 抽象方法
    public abstract void show();
    // 非抽象方法
    public void test(){
        System.out.println("非抽象方法");
    }
}

外部类的形式继承抽象类Person

public class Student extends Person {
    @Override
    public void show() {
        System.out.println("重写抽象类中的抽象方法");
    }
}

内部类的形式继承抽象类Person

public class Teacher {
    public static void main(String[] args) {
        Person person = new Person() {
            @Override
            public void show() {
                System.out.println("重写抽象类的抽象方法");
            }
        };
        person.show();
    }
}

3、抽象类能使用 final 修饰吗?

当使用abstract修饰类时,表明这个类只能被继承;当使用abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。而final修饰的类不能被继承,final修饰的方法不能被重写。因此final和abstract永远不能同时使用。

3. 接口

接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现implements)开放,接口是对开闭原则的一种体现。

接口体:

interface 接口名{  常量    抽象方法    静态方法    默认方法}interface 接口名
{
  	常量
    抽象方法
    静态方法
    默认方法
}

3.1 接口中的常量

接口中的所有成员变量都默认是由public static final修饰的,且由于接口里没有构造器和初始化块,因此需要在定义Field时就指定初始值;

接口中的Field都是常量,经常用来被定义常量的集合:

public interface FieldInterface {
    /**
     * 一年的天数
     */
    int DAY = 365;
    /**
     * 一年的星期数
     */
    int WEEK = 52;
    /**
     * 一年的月数
     */
    int MONTH = 12;
}
public class Main {
    public static void main(String[] args) {
        /**
         * 接口中定义的Field都是public static final修饰的常量,因此需要使用接口名来访问
         */
        System.out.println(FieldInterface.DAY);
    }
}

一个类实现某个接口时,该类将会获得接口中定义的Field :

public class FieldImpl implements FieldInterface {
    // 将会继承FieldInterface中定义的所有Field
}
public class Main {
    public static void main(String[] args) {
        System.out.println(FieldInterface.DAY);
        // 使用实现类调用接口中的常量
        System.out.println(FieldImpl.DAY);
    }
}

3.2 接口中的方法

接口中的三种方法:

(1) 接口中的普通方法,默认都是public abstract修饰的抽象方法,没有方法体;

(2) 接口中的静态方法,静态方法必须要有实现,且这个静态方法只能用public修饰或不写;

(3) 接口中的默认方法,默认方法必须要有实现,用default修饰且不可省略,用来供子类继承或重写,二选一,但只能在实现类中使用或者实现类对象中使用;

分别展开举例说明:

3.2.1 接口中的普通方法

接口中的普通方法,默认都是public abstract修饰的抽象方法,没有方法体;

  • 接口的实现类如果是普通类,那么必须重写接口中的所有抽象方法
  • 接口的实现类如果是抽象类,那么可以不用重写接口中的抽象方法
public interface BaseMethod {
    /**
     * 接口中的普通方法
     * 以下方法默认都是public abstract修饰的抽象方法,没有方法体
     */
    public abstract void show1();
    abstract void show2();
    public void show3();
    void show4();
}

① 接口的实现类如果是普通类,那么必须重写接口中的所有抽象方法:

public class BaseMethodImpl implements BaseMethod {
    /**
     * 当一个类实现BaseMethod接口后,需要实现BaseMethod接口中的所有抽象方法
     */
    @Override
    public void show1() { }
    @Override
    public void show2() { }
    @Override
    public void show3() { }
    @Override
    public void show4() { }
}

② 接口的实现类如果是抽象类,那么可以不用重写接口中的抽象方法:

public abstract class BaseMethodImpl2 implements BaseMethod {
    /**
     * 抽象类会继承接口中定义的所有抽象方法和field
     * 这个类仍然是抽象类,可以不用实现接口中所有的抽象方法
     */
    @Override
    public void show1() { }
}

3.2.2 接口中的静态方法

  • 调用形式:接口名.静态方法名
  • 接口中定义的静态方法,不能被子接口继承
  • 接口中定义的静态方法,不能被实现该接口的类继承
public interface StaticMethod {
    /**
     * 接口中的静态方法
     * 接口中是可以定义静态方法的,静态方法必须要有实现。且这个静态方法只能用public修饰或不写。
     */
    public static void test1(){
        System.out.println("接口中定义静态方法");
    }
}
public class Main {
    public static void main(String[] args) {
        /**
         * 接口中的静态方法,只能通过接口名来调用,就像类的静态方法一样
         */
        StaticMethod.test1();
    }
}

① 接口中定义的静态方法不能被子接口继承:

public interface StaticMethod1 extends StaticMethod {
}
public class Main {
    public static void main(String[] args) {
        /**
         * 编译报错,说明接口中定义的静态方法不能被子接口继承
         */
        StaticMethod1.test1();
    }
}

② 接口中定义的静态方法不能被实现类继承:

public class StaticMethodImpl implements StaticMethod {
}
public class Main {
    public static void main(String[] args) {
        /**
         * 编译报错,说明接口中定义的静态方法不能被实现类继承
         */
        StaticMethodImpl.test1();
    }
}

3.2.3 接口中的默认方法

  • 接口中的默认方法,不能通过接口名调用,需要通过接口实现类的实例进行访问,即对象名.默认方法名()
  • 接口中的默认方法,可以被实现类继承,也可以在实现类中重写
  • 接口中的默认方法,可以被子接口继承,也可以在子接口中重写
public interface DefaultMethod {
    /**
     * 接口中的默认方法
     * 用default修饰,不可省略,供子类继承或重写,二选一,但只能在实现类中使用或者实现类对象中使用
     */
    public default void test2(){
        System.out.println("接口中定义默认方法");
    }
}

① 接口中的默认方法,可以被实现类继承,也可以在实现类中重写

public class DefaultMethodImpl implements DefaultMethod {
    // 继承接口中的方法
}
public class DefaultMethodImpl implements DefaultMethod {
    // 重写接口中的方法
    @Override
    public void test2() {
        System.out.println("实现类重写接口中的方法");
    }
}
public class DefaultMethodImpl implements DefaultMethod {
    // 重写接口中的方法
    @Override
    public void test2() {
        System.out.println("实现类重写接口中的方法");
    }
}

② 接口中的默认方法,可以被子接口继承,也可以在子接口中重写

public interface DefaultMethod1 extends DefaultMethod {
    // 继承父接口中的方法
}
public interface DefaultMethod1 extends DefaultMethod {
    // 重写父接口中的方法
    @Override
    default void test2() {
        System.out.println("子接口中重写父接口中的方法");
    }
}

3.3 接口中的接口和枚举类

public interface Base {
    /**
     * 在接口中定义接口
     */
    interface CommonConstant{
        /**
         * 一年的天数
         */
        int DAY = 365;
        /**
         * 一年的星期数
         */
        int WEEK = 52;
        /**
         * 一年的月数
         */
        int MONTH = 12;
        /**
         * 在接口中定义静态方法
         */
        static void show() {
            System.out.println("在接口中定义接口");
        }
    }
    /**
     * 在接口中定义枚举类
     */
    @AllArgsConstructor
    enum WhiteStatusEnum {
        /**
         * 未加白
         */
        NO_WHITE("未加白", "未加白"),
        /**
         * 部分加白
         */
        PART_WHITE("部分加白", "部分加白"),
        /**
         * 全部加白
         */
        ALL_WHITE("全部加白", "全部加白");
        @Getter
        private final String label;
        @Getter
        private final String value;
    }
}

3.4 接口和抽象类

共同点:

(1) 接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承;

(2) 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法;

(3) 接口和抽象类中都可以包括抽象方法和非抽象方法;

不同点:

(1) 接口里只能定义静态常量Field,不能定义普通Field;抽象类里则既可以定义普通Field,也可以定义静态常量Field。

(2) 接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。

(3) 接口里不能包含初始化块;但抽象类则完全可以包含初始化块。

(4) 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。

public class MethodImpl implements FieldInterface, MethodInterface {
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java中的抽象类和接口你了解吗

    目录 抽象类 什么是抽象类? 抽象类属于什么类型? 抽象类怎么定义? 抽象类是干什么的? 什么是抽象方法? 非抽象类继承抽象类 抽象类总结 接口 接口的基础语法 接口的实现 接口和多态联合使用 继承和实现同时出现 接口在开发中的作用 类型和类型之间的关系 总结 抽象类 什么是抽象类? 类和类之间有共同特征,将这些共同特征提取出来进一步抽象,就形成了抽象类.由于类是不存在的,所以抽象类无法创建对象. 抽象类属于什么类型? 抽象类也属于引用数据类型. 抽象类怎么定义? [修饰符列表] abstrac

  • Java抽象类和接口使用梳理

    目录 抽象类 抽象方法 抽象类三大原则 接口 接口使用原则 JDK两大内置接口 java.lang.Comparable 比较接口 java.lang.Cloneable 克隆接口 对象的深浅拷贝 抽象类和接口的区别 抽象类 什么是抽象类呢?在现实生活中,我们说“人类”,我们无法对应到具体某个人,同样的,“动物类”.“图形类”这些无法映射到具体的对象的类就是抽象类. 抽象类是普通类的超集,意思就是普通类有的抽象类也有,只是它比普通类多了一些抽象方法而已.这些抽象方法可以有一个,也可以有多个. 它

  • 浅析Java中接口和抽象类的七大区别

    目录 接口 抽象类 区别1:定义关键字不同 区别2:继承或实现的关键字不同 区别3:子类扩展的数量不同 区别4:属性访问控制符不同 区别5:方法控制符不同 区别6:方法实现不同 区别7:静态代码块使用不同 总结 Java 是一门面向对象的编程语言,面向对象的编程语言有四大特征:抽象.封装.继承和多态. 而本文介绍的接口和抽象类就是面向对象编程中"抽象"的具体实现,也就是说接口和抽象类都是用来定义实体类的公共行为的,它们是对实体类(对象)更高层次的抽象. ​说明:本文以下内容基于 JDK

  • Java入门基础之抽象类与接口

    目录 一.抽象类 1.什么是抽象类 2.语法规则 3.抽象类的作用 二.接口 1.什么是接口 2.语法规则 3.实现多个接口 4.接口之间的继承 三.接口的使用实例 1. Comparable 接口 2.Comparator接口 3.Clonable接口 四.总结 一.抽象类 1.什么是抽象类 首先我们来回顾一下上一篇文章提到的一个例子:打印图形 class Shape { public void draw() { // 啥都不用干 } } class Cycle extends Shape {

  • Java中比较抽象类与接口的异同

    目录 一.抽象类 (一)概念 (二)抽象类和抽象方法 (三)使用抽象类的意义 二.接口 (一)概念 (二)语法 三.比较抽象类与接口 Q: 为什么有了抽象类还要接口?  Q: 如何确定在什么情况下应该使用接口,什么情况下应该使用类呢? 一.抽象类 (一)概念       在继承的层次结构中,每个新的子类都使类变得更加明确和具体.如果从一个子类向父类追溯,类就会变得更通用.更加不明确.类的设计应该确保父类包含它的子类的共同特征.有时候,一个父类设计得非常抽象,以至于它都没有任何具体的实例.这样的类

  • Java中抽象类和接口介绍

    目录 1.抽象类 1.1 什么是抽象类? 1.2 抽象类属于什么类型? 1.3 抽象类怎么定义? 1.4 抽象方法 2.接口 2.1 关于接口 2.2 接口怎么定义? 2.3 接口基础语法 总结 1.抽象类 1.1 什么是抽象类? 1.1.1 对抽象类的理解 1.1.2 关于抽象类 类与类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类: 类本身是不存在的,属于抽象类无法创建对象[无法实例化]: 抽象类是用来被子类继承的: finial关键字和abstract关键字不能同时出现: 抽象

  • Java 超详细讲解抽象类与接口的使用

    目录 一.抽象类 1.抽象类的语法 2.抽象类的特性 3.抽象类的作用 二.接口 1.接口的概念 2.接口使用 3.接口特性 4.实现多个接口 5.接口间的继承 6.常用的接口 (1)Comparable接口 (2)Cloneable接口 三.Object类 一.抽象类 在Java中,如果一个类被abstract修饰称为抽象类,抽象类中被abstract修饰的方法称为抽象方法,抽象方法不用给出方法体. 1.抽象类的语法 //抽象类:被abstract修饰的类 public abstract cl

  • Java 深入浅出解析面向对象之抽象类和接口

    目录 抽象类 声明抽象类 声明抽象方法 案例 使用规则 接口 声明接口 案例 接口特性 抽象类和接口的区别 抽象类 java语言,声明类时 abstract class Db{} 说明Db类为抽象类. java语言中,抽象方法是说没有方法的实现(方法体)此方法为抽象方法,只有抽象类和接口中才可以有抽象方法. 声明抽象类 声明抽象类很简单,加个abstract关节字就行. public abstract class AA { } 声明抽象方法 在抽象类中声明一个抽象方法,抽象方法没有方法体,就是说

  • java中抽象类和接口的相同和不同点介绍

    目录 前言 一.抽象类是什么? 二.接口是什么? 三.抽象类和接口的异同点 总结 前言 本文简单介绍抽象类,接口以及它们的异同点,另附简单的代码举例. 一.抽象类是什么? 在 Java 语言中使用 abstract class 来定义抽象类.抽象类是不能被实例化的,即不能用new关键字来实例化对象.包含抽象方法的一定是抽象类,但抽象类不一定包含抽象方法.如果一个子类实现了父类(抽象类)的所有抽象方法,那么该子类可以不必是抽象类,否则就是抽象类.抽象类中的抽象方法的修饰符只能为public或者pr

  • 解析JavaSe的抽象类和接口

    目录 1. 抽象类和抽象方法 2. 相关面试题 1.抽象类必须要有抽象方法吗? 2.普通类和抽象类有哪些区别? 3.抽象类能使用 final 修饰吗? 3. 接口 3.1 接口中的常量 3.2 接口中的方法 3.2.1 接口中的普通方法 3.2.2 接口中的静态方法 3.2.3 接口中的默认方法 3.3 接口中的接口和枚举类 3.4 接口和抽象类 总结 1. 抽象类和抽象方法 抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法.抽象方

  • 详解JavaSE中抽象类与接口的定义及使用

    目录 一.抽象类 1.抽象类定义 2.抽象方法 二.接口 1.接口定义 2.类实现接口 3.接口与多态联合 4.extends和implements 5.接口在开发当中的作用 6.is has like 7.抽象类与接口 一.抽象类 1.抽象类定义 1.什么是抽象类? 类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类. 类到对象是实例化,对象到类是抽象. 抽象类无法实例化,无法创建对象.抽象类是类和类之间有共同特征,将这些具有共同特征的类再进一步抽象,就形成了抽象类.由于类本身是

  • 详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进 行抽象类定义时对于abstract class和interface的选择显得比较随意.其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对 于问题领域本质的理解.对于设计意图的理解是否正确.合理

  • C#中抽象类与接口的区别详解

    1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分.或者说,它是面向对象编程体系中的思想精髓之一. 2.接口的本质 接口,在表面上是由几个没有主体代码的方法定义组成的集合体,有唯一的名称,可以被类或其他接口所实现(或者也可以说继承).它在形式上可能是如下的样子: interface InterfaceName { void Method1(); void Method2

  • IDEA调试源码小技巧之辨别抽象类或接口多种实现类的正确路径

    1. 打断点 直接在抽象类或者接口前打断点,直接debug模式就能自动跳入正确的实现类,如图: 这个document的解析,有5种可能,哪个才是正确的?直接在前面打断点,就能跳入正确的了 2. 发现正确实现类 到此这篇关于IDEA调试源码小技巧之辨别抽象类或接口多种实现类的正确路径的文章就介绍到这了,更多相关IDEA调试源码内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • Java语法之 Java 的多态、抽象类和接口

    目录 一.多态 1. 向上转型 2. 动态绑定 3. 方法重写 4. 向下转型 5. 关键字 super 6. 在构造方法中调用重写方法(坑) 7. 理解多态 8. 小结 二.抽象类 1. 概念 2. 注意事项 3. 抽象类的意义 3. 抽象类的作用 三.接口 1. 语法规则 2. 实现多个接口 3. 接口的继承 4. Comparable 接口 4. Comparator 接口 5. Cloneable 接口和深拷贝 上一篇文章:Java 基础语法之解析 Java 的包和继承 今天这章主要介绍

  • Java中抽象类和接口的区别_动力节点Java学院整理

    接口 1 因为java不支持多重继承,所以有了接口,一个类只能继承一个父类,但可以实现多个接口,接口本身也可以继承多个接口. 2 接口里面的成员变量默认都是public static final类型的.必须被显示的初始化. 3 接口里面的方法默认都是public abstract类型的.隐式声明. 4 接口没有构造方法,不能被实例化. 5 接口不能实现另一个接口,但可以继承多个接口. 6 类如果实现了一个接口,那么必须实现接口里面的所有抽象方法,否则类要被定义为抽象类. 抽象类 1 如果将一个类

  • JAVA 继承基本类、抽象类、接口介绍

    封装:就是把一些属性和方法封装到一个类里. 继承:就如子类继承父类的一些属性和方法. 多态:就如一个父类有多个不同特色的子类. 这里我就不多讲解,下面我主要说明一个继承.继承是OOP(面向对象)的一个特色,java只支持单继承(如果继承两个有同样方法的父类,那么就不知道继承到那个父类的,所以java只支持单继承).继承是java的一个特色,我们用的所以类都继承Objict类,所以就要Object类的方法,如toString().getClass().wait()--所以我们建立的类都有父类. J

  • C#抽象类和接口的区别分析

    很多C#的初学者在编程时都容易把抽象类和接口搞混,本文就为大家从概念上讲解抽象类和接口的区别: 一.抽象类: 含有abstract修饰符的class即为抽象类,抽象类是特殊的类,只是不能被实例化,可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖. 二.接口: 接口是

随机推荐