Java教程

19.Java 抽象方法和抽象类/接口/普通方法/静态方法/接口多继承

本文主要是介绍19.Java 抽象方法和抽象类/接口/普通方法/静态方法/接口多继承,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

抽象方法和抽象类

简述

抽象方法:

使用 abstract 修饰的方法,没有方法体,只有声明。
定义的是一种 “规范”,就是告诉子类必须要给抽象方法提供具体的实现。

抽象类:

包含抽象方法的类就是抽象类。
通过 abstract 方法定义规范,然后要求子类必须定义具体实现。
通过抽象类,可以做到严格限制子类的设计,使得子类之间更加通用。

抽象类使用要点

  1. 有抽象方法的类只能定义成抽象类。
  2. 抽象类不能实例化,即不能用 new 来实例化抽象类。
  3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用 new 来实例,只能用来被子类调用
  4. 抽象类只能用来被继承,不能被直接调用进行实例化。。
  5. 抽象方法必须被子类实现。

代码示例:测试抽象类和抽象方法的基本用法

package cn.jungle.polymophism;

// 定义抽象类
abstract class Animal1{
    // 定义抽象方法,规定子类必须实现的方法
    abstract public void shout();
}
class Dog1 extends Animal1{
    // 子类必须实现父类的抽象方法,否则编译错误
    public void shout(){
        System.out.println("子类必须实现父类的抽象方法,否则编译错误");
        System.out.println("听到有狗的警告叫声!");
    }
    public void seeDog(){
        System.out.println("发现一只狼狗正在看门!");
    }
}
public class TestAbstract {
    public static void main(String[] args) {
        Dog1 a = new Dog1();
        a.shout();
        a.seeDog();
    }
}

接口 interface

简述

接口:将设计与实现彻底分开。
接口即是规范,定义的是一组规则。思想为:“如果你是……则必须能……”,比如你是飞机,则必须能飞。
接口的本质是契约,如同国家规定的法律,必须去遵守。
面向对象的精髓,是对对象的抽象,接口最能体现这一点。

接口的作用

(1)为何需要接口?

接口是比 “抽象类” 还要 “抽象” 的 “抽象类”,可以更加规范的对子类进行约束。
全面且专业地实现了:规范和具体实现的分离。

(2)接口与抽象类的区别?

抽象类会提供某些具体的实现,接口不提供任何实现,接口中所有方法都是抽象方法。
接口是完全面向规范的,规定了一批类具有的公共方法规范。
从接口的实现者角度看,接口定义了可以向外部提供的服务。
从接口的调用者角度看,接口定义了实现者能够提供哪些服务。
接口是两个模块之间通信的标准,通信的规范。
接口和实现类不是父子关系,是实现规则的关系。

(3)本质区别

  • 普通类:具体实现
  • 抽象类:具体实现,规范(抽象方法)
  • 接口:规范

声明格式:

接口中只能定义方法和常量

[访问修饰符] interface 接口名  [extends 父接口1,父接口2……] {
    常量定义:
    方法定义
}

接口定义详细说明

  • 访问修饰符:只能是 public 或默认。
  • 接口名:和类名采用相同命名机制。
  • extends:接口可以多继承。
  • 常量:接口中的属性只能是常量,总是:public static final 修饰,不写也是如此。
  • 方法:接口中的方法只能是:public abstract 。如果省略不写的话,默认也是 public abstract 。

使用要点

  • 子类通过 implements 来实现接口中的规范。
  • 接口不能创建实例,但是可用于声明变量类型。
  • 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是 public 的。
  • JDK1.8(不含8)之前,接口中只能包含静态常量,抽象方法,不能有普通属性、普通方法、构造方法。
  • JDK1.8(含8)后,接口中可以包含普通的静态方法、默认方法。

代码示例:接口定义测试

两个文件:Volant.java(接口定义文件)、SuperMan.java(主文件)
(1)Volant.java

package cn.jungle.test.TestInterface;

/**
 * 这里是一个飞行器的接口。
 *
 * */
public interface Volant {
    /**
     * 接口中定义一个 FLY_HEIGHT 常量。
     * 这里表示飞行器在地球上的飞行最高高度,单位:公里。
     */
    /* public static final 这里可写可不写*/ int FLY_HEIGHT = 1000;
    /**
     * 接口中定义一个 fly() 抽象方法。
     * 定义飞行方法,表示飞行器可以起飞。
     */
    /* public abstract */ void fly();
    /**
     * 接口中定义一个 stop() 抽象方法。
     * 定义停止方法,表示可以让飞行器停止。如果在空中就是飞行,在地面就是静止。
     */
    /* public static final */ void stop();
}

/**
 * 一个行为接口,帮助他人
 */
interface Honest{
    void helperOther();
}

(2)SuperMan.java

package cn.jungle.test.TestInterface;

// 定义超人的飞行类和行为类
public class SuperMan implements Volant,Honest {
    // 重写父类方法
    @Override
    public void fly() {
        System.out.println("从天而降");
    }
    // 重写父类方法
    @Override
    public void stop() {
        System.out.println("空中悬停");
    }
    // 重写父类方法
    @Override
    public void helperOther() {
        System.out.println("哪里需要帮助,哪里就有我马丁超人!");
    }

    // main 方法入口,可以定义在这里,也可以单独创建一个 java 文件来存放 main 方法
    public static void main(String[] args) {
        // 定义类对象
        SuperMan m1 = new SuperMan();
        // 类对象调用方法
        m1.fly();
        m1.helperOther();
        m1.stop();
        /**
         * 另一种调用方式,定义一个多态对象,然后通过强转去调用方法,但是比较麻烦
         */
    }
}

接口中定义静态方法和默认方法(JDK8 以后)

Java8 之前,接口里的方法要求全部是抽象方法。
Java8(含8) 之后,允许在接口里使用默认方法和类方法。

默认方法

Java8 及以上旧版本,允许给接口添加一个非抽象的方法实现,只需要使用 default 关键字即可,这个特征又叫做默认方法(也称为扩展方法)。
默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法并不是。
作为替代方式,接口可以提供默认方法的实现,所有这个接口的实现类都会通过继承得到这个方法。
调用接口的默认方法需要实现类的对象来调用。

代码示例:接口中默认方法的定义、重写与调用

package cn.jungle.test.TestInterface;
/**
 * 测试接口中定义默认方法
 */
public class Test01 {
    public static void main(String[] args) {
        // 父类引用指向子类对象。调用接口的默认方法需要实现类的对象来调用。
        A a = new Test_A();
        a.moren();
    }
}
// 定义接口
interface A{
    // 用 default 关键字来定义默认方法
    default void moren(){
        System.out.println("这里是接口 A 中的默认方法。");
        System.out.println("如果默认方法没有被重写,调用时则会执行默认方法中的语句。");
    }
}
// 定义普通类
class Test_A implements A{
    // moren 方法的重写
    @Override
    public void moren() {
        System.out.println("接口中的默认方法重写以后,调用时会被执行,不会再去执行接口中的默认方法语句。");
    }
}

静态方法

Java8 以后,可以在接口中直接定义静态方法的实现。
这个静态方法直接从属于接口(接口也是类,一种特殊的类),可以通过接口名调用。
如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直接从属于子类。可以通过子类名直接调用。
如果调用静态方法,是用 “类名.静态方法名” 去调用。静态方法从属于类。
静态方法中不能调普通方法,普通方法中可以调静态方法。

接口多继承

接口完全支持多继承。接口可以有多个父类接口
和类的继承类似,子继承扩展某个父接口,将会获得父接口中定义的一切。

代码示例

package cn.jungle.test.TestInterface;

/**
 * 测试接口的多继承
 */
public class Test02{
    public static void main(String[] args) {
        Test t = new Test();
        t.testB(); 
        t.testC();
        t.testD();
    }
}
interface B{
    void testB();
}
interface C{
    void testC();
}
/* 接口可以多继承,接口 D 继承 B 和 C*/
interface D extends B,C{
    void testD();
}
// Test 类作为 C 的实现类。实现类需要实现各个接口中的方法,即重写
class Test implements D{
    // 实现类中重写和实现接口的方法
    @Override
    public void testB() {
        System.out.println("testB() 方法");
    }
    // 实现类中重写和实现接口的方法
    @Override
    public void testC() {
        System.out.println("testC() 方法");
    }
    // 实现类中重写和实现接口的方法
    @Override
    public void testD() {
        System.out.println("testD() 方法");
    }
}
这篇关于19.Java 抽象方法和抽象类/接口/普通方法/静态方法/接口多继承的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!