黑马程序员 第六篇 接口 interface (Foundation; completed)

——- android培训java培训、期待与您交流! ———-

1. 什么是接口

接口(interface)是一个完成某些特定功能的类,是一个功能的集合。

这里写图片描述

1.1 接口的定义

描述接口的例子,汽车的移动就好比一个接口,在以后制造的汽车中都遵循这个接口的标准进行生产。
而接口中只定义了汽车的移动的形式,没有具体定义汽车是怎么进行移动的,所以接口就好比是一个规定(准则),用来描述所实现的类能够做什么,可以充当一个什么样的角色。

(ps: 描述这个类所能实现的功能,但不具备这个类的具体代码)

语法

接口修饰符 interface 接口名称
{
    //成员变量和方法的声明
}

 - 接口修饰符和类的修饰符是一样的,也可以是public或者不写修饰符。
 - interface是定义接口的关键字,用来说明定义的是接口,和class说明定义类一样。
 - **接口里的成员变量默认为public static final类型的。**
 - **接口不能声明为final的,因为final类型的必须要实现。**

定义一个接口

public interface car
{
}
public interface Toyota
{
}

接口的定义遵循类的定义原则,接口同样可以继承,下面演示Toyota继承与car

public interface car
{
}
interface Toyota extends car
{
}

Tips
1.类不能多继承,但可以通过接口来实现多层继承
2.接口既可以多层继承,也可以多继承

下面演示一段接口的多继承

public interface car
{
}
public interface suv
{
}
public interface aircondition
{
}

//**定义一个Toyota丰田汽车的接口,它继承了car和aircondition
**
public interface Toyota enxtends car aricondition
{
}

下面一段代码演示 接口的定义

package a;

//创建一个接口 名字为aaa
public interface aaa
{
    int i = 2;
    //创建一个接口方法getMax
    public int getMax();
    //穿件一个接口方法getMes
    public String getMes();
}


代码解析: 在定义接口的时候,接口里的方法是没有方法体的,接口里定义的方
法需要在其子类去实现,接口的变量默认被修饰为public static final类型。

1.2 访问接口里的常量

在接口里定义的成员变量为常量,因为接口为每个成员变量默认的修饰是public static final类型,即便是不使用这些修饰符进行修饰,也会在编译的时候自动为其加上。

演示例子

package a;
public interface aaa
{
    int i=2;
}

import a.aaa;
public class test
{
    public static void main(String[] args)
    {
        aaa.i = aaa.i + 1;
        System.out.println(aaa.i);
    }
}


运行结果:
程序出现异常

代码解析:
因为aaa.i为接口的成员变量,其默认修饰格式为public static final类
型,所以aaa.i是不能够改变的,也不能进行赋值。

tips: 可以通过创建一个新的变量用以赋值

import a.aaa;
public class test
{
    public static void main(String[] args)
    {
        int n = aaa.i + 1;
        System.out.println(n);
    }
}

Tips

1. final 关键字修饰的成员变量的值不能改变其值,如果改变其值将出现编译错误。

2. static关键字修饰的成员变量的值是属于类的,不基于对象的存在而存在,在test类中没有创建对象就直接调用了接口中的成员变量。

2. 接口的使用

接口就是一个特殊的抽象类,抽象类里面有抽象的方法和普通的方法,而接口里方法全为抽象的,需要在其子类进行具体的方法实现。

类就是一个产品的详细功能说明,而接口就是这些功能的简要说明。

2.1 接口里的方法如何创建

在接口里创建方法和一个类里的方法很相似,不同点就是接口里的方法没有具体的方法体,而类里的方法必须实现其方法体。

定义一个接口需要注意以下几个规则

  • 所有的接口方法隐含都是公有和抽象的。
  • 接口中的方法不可以是final和static的,只能使用public修饰

下面代码演示在接口里如何定义方法

public interface aaa
{
    public int getMax();
    String getMes();
}

Tip:
接口里的方法是不能被默认修饰为static final类型的,因为接口里的方法需要继承实现,如果加上这些关键字在编译时将提示错误。

以下演示一个使用错误修饰符的接口方法

public interface aaa
{
    public int getMax();
    //这里用static final修饰getMes,使程序编译错误 
    static final String getMes();
}

总结一下接口的方法和类里的方法的区别。

定义接口里的方法和类里的方法都是有一定规则的,但是它们之间的定义也有一定区别,分别如下:

  • 接口里的方法默认被修饰为public, abstract类型
  • 类里的方法如果修饰为abstract类型,将提示错误
  • 接口里的方法不能是static,final类型,只能为public,abstract类型
  • 类里的方法不能为final,abstract类型

2.2 接口引用怎么使用

前面几节里介绍了接口创建及其注意事项,创建接口就是为了使用。下面介绍如何使用接口,以及使用接口的注意事项。接口的实现语法如下:

类的修饰符 class 类名称 implements 接口的名称

通过上面的语法结构可以看出和类的继承很相似。
下面通过一段代码来演示接口是如何实现的。

package a;

//创建一个接口,名字为aaa
public interface aaa
{
    public int getMax();
    String getMes();
}

import a.aaa;
public class test implements aaa
{
    //实现接口的方法
    public int getMax()
    {
        //具体的方法体
        return 0;
    }
    //实现接口的方法
    public String getMes()
    {
        //具体的方法体
        return null;
    }
}

以下通过一个完整的例子来演示接口的方法是怎么使用的

package a;
//创建一个接口 名为aaa
public interface aaa
{
    //创建一个接口方法getMax
    public int getMax();
    //创建一个接口方法getMes
    String getMes();
}


//接下来开发使用该接口的类

import a.aaa

public class test implements aaa
{

    //实现接口里的方法
    public int getMax()
    {
        int i = 123;
        return i;
    }
    //实现接口里的方法
    public String getMes()
    {
        String s= "实现接口里的方法";
        return s;
    }
    //主程序入口方法
    public static void main(String args[])
    {
        //创建test类的对象实例 引用为t
        test t = new test();
        //实现接口里的方法并进行调用
        int i = t.getMax();
        String s = t.getMes();

        //打印并显示结果
        System.out.println("i");
        System.out.println("s");
    }

}
运行结果:
 打印   123
       实现接口里的方法

代码解析:
接口里的方法通过implements关键字实现后,有了具体的方法体,就和正常的
方法使用没任何区别了。实现的方法是随着类的创建而存在,因此需要将对象实
例后在使用。

3. 什么是抽象类

这里写图片描述

抽象类和接口有些类似,抽象类需要其他类继承来实现抽象类中的方法,以及给出更多的方法。在日常生活中,一个产品的简要介绍和详细介绍结合,说明了产品具有什么功能和这个功能都完成了什么。在Java中也是类似的,接口是抽象类的特殊版本接口里的方法必须都是为抽象的,而抽象类里可以为抽象的也可以有其他形式的存在。

3.1 抽象类的使用和特点
抽象类和一般的类很相似,只是在类里存在一些没有方法体的方法,即抽象方法。

//创建一个包,名字为a
package a;


//创建一个接口 名为aaa
public abstract class aaa
{

    //抽象类里的抽象方法
    abstract public void show();

    //抽象类里的方法
    public int getMax()
    {
        int i = 123;
        return i;
    }

}

//导入抽象类的包
import a.aaa


public class test extends aaa
{
    //主程序的入口
    public static void main(String args[])
    {
        //创建test类的对象实例,引用为t
        test t = new test();
        //实现了抽象类的方法并调用
        t.show();
    }

    //实现了抽象类的方法
    public coid show()
    {
         System.out.println("实现了抽象类里的方法");
    }
}


运行结果:
打印  实现了抽象类里的方法


代码解析:    *****
test类继承了aaa类, 创建test类的对象实例,用t.show()调用了抽象类里的方法show()


Tip

抽象类和接口一样,没有实现的方法必须在其子类去实现,如果不去实现就必须把类声明为abstract抽象类型的。抽象类里的方法的使用和一般类里的方法使用没有区别。

下面代码演示抽象类不能被实例化。


首先定义一个抽象类

package a;

public abstract class aaa
{
    //抽象类里的抽象方法
    abstract public void show();

    //抽象类里的方法
    public int getMax()
    {
        int i = 123;
        return i;
    }
}

再定义使用该抽象类的类
import a.aaa;

public class test extends aaa
{
    public static void main(String args[])
    {
        //创建test类的对象实例,引用为t
        test t = new test();
        //实现抽象类的方法
        t.show();

        aaa a = new aaa();
    }

    //实现抽象类的具体方法 
    public void show()
    {
        System.out.println("实现了抽象类里的方法");
    }

}

代码解析:

问题出在`aaa a = new aaa();`出现异常
**因为抽象类不能够实例化,抽象类和接口一样是继承用的。**

总结抽象类的特点

  • 抽象类一般在父类中使用,而它的子类实现父类中的抽象方法
  • 如果父类有一个或多个抽象方法,那么父类必须为抽象类
  • 抽象类里的抽象方法没有任何方法体,子类要实现父类的所有抽象方法。如果没实现抽象方法,其子类即为抽象类
  • 抽象类是用来继承的,不能被实例化
  • 所有的抽象方法都必须声明在抽象类中
  • 抽象类里的抽象方法,只有在子类实现了才能使用
  • 抽象类里允许有抽象方法和普通方法
  • 抽象类里的普通方法可以被子类调用

3.2 抽象类与接口区别

抽象类特性

  • 抽象类中有一个抽象方法或多个抽象方法
  • 如果抽象类的子类里有一个没有实现的抽象方法,那么这个类也是抽象类。
  • 实现抽象类里的方法可以实现部分方法,也可以实现所有方法
  • 抽象类里可以有成员变量
  • 抽象类里可以有私有的方法和私有的成员变量

接口特性

  • 接口中的方法全部都被修饰为抽象方法
  • 接口里的方法都被默认修饰为public abstract类型的
  • 接口里的变量都被默认修饰为public static final类型的,即常量
  • 一个类可以实现一个接口,也可以实现多个接口
  • 接口里的方法必须要全部实现
  • 接口里没有成员变量
  • 接口里的方法全部都是public,即公共类型的

4. 接口的多态

多态,就好比日常生活中的苹果和鸡肉都是食物的一种,而苹果又是水果的一种,鸡肉是肉类的一种,苹果和鸡肉是两种不同的食物,但是食物可以同时指向这两种物品。这就是日常生活中多态的形式。
在java中也是如此,食物的对象可以指向苹果和鸡肉对象,这给编写代码提供了很大的灵活性。

下面演示接口是如何实现多态的。

首先创建一个food接口

interface food
{
    public void getname();
    public void eat();
}

再来编写一个继承food接口的fruit接口和meat接口


//创建一个fruit接口,继承于food接口
interface fruit extends food
{
    //此接口继承了父接口的方法
}
//
interface meat extends food
{
    //此接口继承了父接口的方法
}

接下来定义一个实现fruit接口的apple类

class apple implements fruit
{
    public void eat()
    {
        System.out.println("此方法是吃苹果的方法");
    }

    public void getname()
    {
        System.out.println("吃的水果名称为苹果");
    }
}

同时创建一个实现meat接口的chicken类

class chicken implements meat
{
    public void eat()
    {
        System.out.println("此方法是吃鸡肉的方法");
    }

    public void getname()
    {
        System.out.println("吃的肉名称为鸡肉");
    }
}

最后编写一个总类

public class test
{
    public static void main(String args[])
    {
        //多态, 创建苹果的实例
        food f1 = new apple();
        f1.eat();
        f1.getname();
        //多态,创建鸡肉的实例
        food f2 = new chicken();
        f2.eat();
        f2.getname();
    }
}
代码解析:
读者可以看到一个对象有两种不同的状态,这就是多态的好处。它可以使代码更加简单,更灵活。

5. 判断类型

instanceof一般使用于多态的时候,在代码中判断对象的引用类型具体为哪一种类型。根据不同的对象类型来执行不同对象中的方法。

5.1 什么是instanceof

所谓instanceof在字面上可以理解为检查实例。instanceof在Java中是一个二元操作符,也是Java所保留的关键字。
instanceof的语法结构如下:

对象的引用 instanceof 类或接口

instanceof语句的返回结果是boolean类型的。如果返回true,说明对象的引用是该对象所指的类或接口;如果返回false,说明对象的引用不是该对象所指的类或接口

下面通过一段代码演示如何使用instanceof


//创建一个fruit接口
interface fruit
{
    //获得食物的名称的方法
    public void getname();
    //吃食物的方法
    public void eat();
}


//apple类描述的是苹果,继承于fruit接口
class apple implements fruit
{
    //实现了接口里的方法
    public void eat()
    {
        System.out.println("此方法是吃苹果的方法");
    }

    //实现了接口里的方法
    public void getname()
    {
        System.out.println("吃的水果名称为苹果");
    }
}




//blueberry类描述的是蓝莓类
class blueberry
{
    String name;
}




//test类描述的是测试instanceof
public class test
{
    //main方法为Java程序的主入口方法
    public static void main(String args[])
    {
        apple a = new apple();

        if(a instanceof apple)
        {
            System.out.println("对象引用 a 指向的类为apple");
        }
        if(a instanceof fruit)
        {
            System.out.println("对象引用 a 指向的接口为fruit");
        }


        blueberry bb = new blueberry();

        if(bb instanceof fruit)
        {
            System.out.println("对象引用 bb 指向的接口为fruit");
        }
        else
        {
            System.out.println("对象引用 bb 没有指向任何类或对象");
        }
    }
}


输出结果:
对象引用 a 指向的类为apple
对象应用 a 指向的接口为fruit
对象引用 bb 没有志向任何类或对象


代码解析
因为blueberry并没有继承于fruit,所以对象blueberry不是fruit接口的子类,所以说多态是基于继承。

下面的程序讲解如何使用instanceof测试对象是否已经创建成功


//test类描述的是测试instanceof判断对象创建
public class test
{

//**被static关键字修饰的成员变量是随着类的创建而创建的**

    //创建test类的对象引用t1
    static test t1;
    //创建test类的对象引用t2
    static test t2;


    //Java主程序入口
    public static void main(String args[])
    {
        //创建test类的对象实例
        t1 = new test();

        if(t1 instanceof test)
        {
            System.out.println("对象引用t1指向的类为test");
        }
        else
        {
            System.out.println("对象引用t1不指向的类为test");
        }

        if(t2 instanceof test)
        {
            System.out.println("对象引用t2指向的类为test");
        }
        else
        {
            System.out.println("对象引用t2不指向的类为test");
        }

    }
}


输出结果:

     对象引用t1指向的类为test
     对象引用t2不指向的类为test


代码解析:

被static关键字修饰的成员变量是随着类的创建而创建的。 在类的生命周期中
只存在着一份。
1.对象引用t1在main方法里进行了实例引用,指向了具体的对象。
2.对象引用t2没有指向任何对象,所以被系统赋予默认值,即null。

因此t2没有指向任何对象,所以第二个if语句的输出结果为false

5.2 使用instanceof的注意事项

在使用instanceof进行对象类型判断的时候也是有规则要遵循的,下面总结使用instanceof有哪些规则。

  • instanceof关键字不能比较基本类型的数据
  • instanceof关键字可以对对象和接口使用
  • instanceof关键字的比较是基于多态的
  • 不推荐使用instanceof关键字,要多应用多态
  • instanceof关键字右边比较的类型只能为类和接口

下面是一个例子,通过它来说明比较对象时提示的错误

public class test
{
    public static void main(String args[])
    {
        test t1 = new test();
        test t2 = new test();

        if(t1 instanceof test)
        {
            System.out.println("对象引用t1指向的类为test");
        }
        else 
        {
            System.out.println("对象引用t1不指向的类为test");
        }

        if(t2 instanceof test)
        {
            System.out.println("对象引用t2指向的类为test");
        }
        else
        {
            System.out.println("对象引用t2不指向的类为test");
        }
    }
}


输出结果:
        出现异常


代码分析:

在第二个if语句中`if(t1 instanceof t2)`发生异常,因为instanceof关键字的右边只能是类和接口,t2为不可识别的符号。

——- android培训java培训、期待与您交流! ———-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值