Java接口的一些知识点
接口(interface)特点:
1. 用关键词interface表示
interface 接口名{}
2.类实现接口用implements表示
class 类名 implements 接口名{}
3.接口不能实例化
按照多态方式来实例化。
4.接口的子类
可以是抽象类,但意义不大。(因为抽象类只能定义空体方法,抽象方法不能有主体,且抽象类也必须有子类才能实例化,抽象方法本身不能实例化,所以意义不大)
可以是具体类,但要重写接口方法(推荐方案)
由此可见多态有三种方式:
具体类多态(开发中几乎没有用过)
抽象类多态(常用)
接口类多态(最常用)
5.接口是一个抽象类。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //错误示例 2 3 interface PersonTrain{ 4 public abstract static void fly(); 5 public PersonTrain(){} 6 } 7 8 class Boss implements PersonTrain{ 9 public void fly(){ 10 System.out.println("Boss fly"); 11 } 12 } 13 14 public class jiekou_yufa { 15 public static void main(String[] args) { 16 PersonTrain pt = new PersonTrain() ; 17 } 18 }
这段代码中一共有三处错误:
分别是:
第一,接口中不能声明实例方法,声明抽象方法时,不能使用static关键字修饰;
第二,接口中不能有构造方法。
第三,接口不能直接实例化(可以通过多态来实例化)。
这段代码的正确示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 interface PersonTrain{ 2 public abstract void fly(); 3 4 } 5 6 class Boss implements PersonTrain{ 7 public void fly(){ 8 System.out.println("Boss fly"); 9 } 10 } 11 12 public class jiekou_yufa { 13 public static void main(String[] args) { 14 PersonTrain pt = new Boss() ; 15 pt.fly(); 16 } 17 }
运行结果:
6.接口中定义的成员变量是常量。默认为(public static final)
举例如下:
Inter.interface
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public interface Inter { 2 public int num = 10; 3 public final int num2 = 100; 4 }
InterImpl.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class InterImpl implements Inter{ 2 3 }
InterfaceDemo2.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class InterfaceDemo2 { 2 public static void main(String[] args) { 3 Inter i = new InterImpl(); 4 System.out.println(i.num); 5 System.out.println(i.num2); 6 System.out.println("-----------------"); 7 i.num=20; 8 i.num2=200; 9 System.out.println(i.num); 10 System.out.println(i.num2); 11 } 12 }
报错如下:
这在我们学习final时知道,有final修饰的变量是常量,不能再进行第二次赋值。
而且,当前两个文件不变,把InterfaceDemo2.class文件改写之后我们会发现,接口中的变量还是静态的,新文件如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class InterfaceDemo2 { 2 public static void main(String[] args) { 3 Inter i = new InterImpl(); 4 System.out.println(i.num); 5 System.out.println(i.num2); 6 System.out.println("-----------------"); 7 // i.num=20; 8 // i.num2=200; 9 // System.out.println(i.num); 10 // System.out.println(i.num2); 11 System.out.println(Inter.num); 12 System.out.println(Inter.num2); 13 } 14 }
运行结果为:
我们知道当一个类由static修饰时,它可以通过类名来调用。所以由此可知,.接口中定义的成员变量是常量。默认为(public static final)。
7.在interimple.class 文件中,因为此类没有父类,所以此类的构造方法中的 super();语句默认父类为Object类,object类是所有类的父类。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class InterImpl implements Inter{ 2 public InterImpl(){ //无参有实体构造方法 3 super(); //默认以object类为父类。 4 } 5 }
此语法有官方提供的API提供:
又因为object类中只提供了无参构造方法,所以所有子类都默认调用父类的无参构造方法。所以即使接口没有构造方法也不影响子类调用父类无参构造,因为访问的是object类。
8.声明接口语句中,默认含有abstract关键字,抽象方法中也默认含有abstract关键字;
示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public interface Inter { 2 public int num = 10; 3 public final int num2 = 100; 4 public void show(){}//带有主体的方法 5 }
结果:
所以此时我们想到了抽象方法,因为抽象方法也没有主体。
代码如下:
Inter.interface
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public interface Inter { 2 public int num = 10; 3 public final int num2 = 100; 4 public void show(); 5 6 }
InterImpl.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public interface Inter { 2 public int num = 10; 3 public final int num2 = 100; 4 public void show(); 5 6 }
InterfaceDemo2.class
public class InterfaceDemo2 { public static void main(String[] args) { Inter i = new InterImpl(); // System.out.println(i.num); // System.out.println(i.num2); // System.out.println("-----------------"); // i.num=20; // i.num2=200; // System.out.println(i.num); // System.out.println(i.num2); // System.out.println(Inter.num); // System.out.println(Inter.num2); i.show(); } }
运行结果:
9.类与类,类与接口,接口与接口的关系
类与类:
继承关系,只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
在继承一个类的时候同时实现多继承。
接口与接口:
接口与接口之间 是继承关系,可以单继承,也可以多继承。
说明:A ,B,C为类,D,E,F为接口,且B,C为A的父类。
即 interface A extends B{} interface A extends B,C{}都正确。
类与接口示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 interface Father { 2 // public abstract void show(); 此形式也可以 3 public void show(); 4 } 5 6 interface Mother{ 7 // public abstract void show2(); 此形式也可以 8 public void show2(); 9 } 10 11 class Son extends Object implements Father,Mother{ 12 public void show(){ 13 System.out.println("show son"); 14 } 15 16 public void show2(){ 17 System.out.println("show son2"); 18 } 19 } 20 21 public class InterfaceDemo23 { 22 public static void main(String[] args) { 23 Son s = new Son(); 24 s.show(); 25 s.show2(); 26 } 27 }
运行结果:
运行后我们可以看到,可以同时实现多个接口,但不能同时继承多个类。
说明:A ,B,C为类,D,E为接口,且B,C为A的父类。
即 class A extends B implements D,E{.....} 此方式是正确的但class A extends B,C{}是错误的。
10.抽象类与接口的区别:
A:成员的区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以常量
构造方法:无
成员方法:只可以抽象
B:关系的区别
类与类:
继承,单继承,多层继承
类与接口:
实现,单实现,多实现
接口与接口:
继承,单继承,多继承
C:设计理念不同
抽象类:被继承体现的是:”is a“的关系。抽象类中定义的的是共性功能。
接口: 被实现的体现的是:"like a"的关系。接口中定义的是该继承体系的扩展功能。
下面是一套完整的抽象函数和接口的实现代码!
InterfaceTest.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class InterfaceTest { 2 public static void main(String[] args) { 3 JumpCat jc = new JumpCat(); 4 jc.setName("哆啦A梦"); 5 jc.setAge(11); 6 System.out.println(jc.getName()+"已经"+jc.getAge()+"了。"); 7 jc.jump(); 8 jc.eat(); 9 jc.sleep(); 10 System.out.println("--------------------"); 11 Cat c = new Cat(); 12 c.setName("哆啦B梦"); 13 c.setAge(10); 14 System.out.println("我是"+c.getName()+",我是"+jc.getName()+"的弟弟,我已经"+c.getAge()+"了,我不会跳高。"); 15 c.eat(); 16 c.sleep(); 17 18 19 } 20 }
Animal.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public abstract class Animal { 2 private String name; 3 private int age; 4 5 public Animal() { 6 7 } 8 9 public Animal(String name, int age) { 10 this.name = name; 11 this.age = age; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 public int getAge() { 23 return age; 24 } 25 26 public void setAge(int age) { 27 this.age = age; 28 } 29 30 public void eat(){ 31 32 } 33 public void sleep(){ 34 System.out.println("伦家要睡觉觉"); //小撒娇,嘻嘻 35 } 36 }
Jumping.interface
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public interface Jumping { 2 public abstract void jump(); 3 }
Dog.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Dog extends Animal{ 2 public Dog(){} 3 public Dog (String name,int age){ 4 super(name, age); 5 } 6 7 @Override 8 public void eat() { 9 System.out.println("狗吃肉"); 10 } 11 }
Cat.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Cat extends Animal{ 2 public Cat(){} 3 public Cat(String name,int age){ 4 super(name, age); 5 } 6 7 @Override 8 public void eat() { 9 System.out.println("猫吃鱼"); 10 } 11 }
JumpDog.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class JumpDog extends Animal implements Jumping { 2 public JumpDog(){} //无参构造 3 4 public JumpDog(String name,int age){ //有参构造 5 super(name, age); 6 } 7 8 @Override 9 public void jump() { 10 System.out.println("会挑高的狗"); 11 } 12 }
JumpCat.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class JumpCat extends Cat implements Jumping{ 2 public JumpCat(){} //无参 3 4 public JumpCat(String name,int age){ //有参 5 super(name, age); 6 } 7 8 @Override 9 public void jump() { 10 System.out.println("会挑高的猫"); 11 } 12 }
运行结果:
小结:在学习接口时应系统的学习,不应该一知半解的,囫囵吞枣,当一件事情我们觉得有难度时,我们更应该沉下心来,静心梳理知识体系,例如,为什么要熟悉接口,难道抽象类不行吗?
我么们应该知道,例如,猫,狗都有睡觉,吃饭,年龄等特征,如果猫和狗都定义这些方法,代码就会显得太多臃肿,如果此时,我们定义一个类在这个类中实现这些公共方法,那就简单了许多,而且还提高了代码的维护性,此时如果定义一个Animal类,它能实现猫狗的公共方法,那就很爽了,而且我们发现,其实我们并不需要实例化Animal,因为Animal是一类总成,猫,是动物,狗也是动物,但他们又有不同,此时我们发现了抽象类,抽象类除了不能实例化,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样,由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类,所以我们就可以把猫狗的睡觉,吃饭,年龄等特征写在Animal类中,此我们发现,猫和狗得吃饭方法可能不一样,那就需要在子类中重写方法,这样就可以提高代码的维护性,和代码的复用性。同时,我们又发现猫中有一部分猫具有跳高功能,但不是每个猫都具有跳高功能,所以我们不能用抽象类来定义,那么我们就想到了用接口(interface),如果我们不定义接口,那么我们实现一个跳高猫就会写一次跳高方法,如果我们定义在接口(interface)中,那么我就可以通过JumpCat来调用Jumping方法,此时我们如果发现JumpCat中有一部分猫不仅会跳高,还会游泳,那么,我们只需要在定义一个Swimming接口,在调用接口时直接:class JumpSwimingcat extends JumpCat implements Jumping,Swiming{},就可以直接调用游泳这个方法。
所以当我们遇到一件困难的事,我们静下心来,慢慢梳理,切忌浮躁,肯定会茅塞顿开,加油呦。
最后送给自己和大家一句话:Don't be shy,just try.Fighting!!!