——- 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为不可识别的符号。