`
wangminshe89
  • 浏览: 668668 次
文章分类
社区版块
存档分类
最新评论

面向对象之接口

 
阅读更多

接口(interface)

定义:接口是一种特殊的抽象类Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

作用:Java只支持单继承,要想实现多继承,运用接口。

实例理解:1)接口感觉就是一些类似的事物共有的域或方法,就像有一个接口animal,里面有个方法eat,然后你每一个动物的类,都去实现这个接口,因为每个动物都有各自的饮食方法,这样就增加了代码的复用性,不要再每一动物类里都要重新想一个名字来定义eat。
2)我们有鸭子和鸡这两个类,鸭子有家鸭和野鸭,有吃与叫的方法,鸡有家鸡和野鸡,也有吃与叫的方法。但是野鸭和野鸡都有飞的方法,所以家鸭与野鸭继承鸭子这个类,家鸡与野鸡继承鸡这个类,我们还要定义一个能飞的接口,然后让野鸭和野鸡实现这个接口。
因此,我们可以大致这样讲:相同类的共同方法和属性,提炼到父类(抽象类),不同类的公共方法,提炼到接口
深入理解:
接口实际上相当于一个父类,实现了一个接口就证明这个类肯定会有某些行为。这样我只要知道这个类实现了某个接口,却不用关心这个类如何实现,也不用关心这个类还实现了其他什么功能。
例如:
接口A 包含方法public void print1(){};和public void print(){};
接口B 包含方法public void print2(){};和public void print(){};
我有个类C实现了A和B
那么 我用 A去声明C的时候
A a = new C();
我们不必关心C能做什么,却能保证可以调用
a.print();
a.print1();
同理
B b = new C();
b.print();
b.print2(); 
这往往在模块化开发中,例如3个人每人负责一个模块,模块互相调用的都是接口。那么一个模块完全不用关心其他模块的接口是如何实现的,只需要专注自己的代码即可。现代的测试环境可以为接口模拟返回值,使模块开发更方便,更不依赖于其他模块。

注意:

1、接口的地位(层级结构)等同于class,接口中的所有方法都是抽象方法,并且方法都是public的。Public interface MyInterface{ },

2、在声明接口方法的时候,可以使用abstract关键字,也可以省略掉abstract关键字。

Eg:Public(abstract) void output();

3、接口可以看成是一种特殊的抽象类,这种抽象类中只包含常量和抽象方法的定义,而没有变量和方法的实现。(抽象类中可以有具体的方法,也可以有抽象的方法,而接口里只能有抽象方法,实现时必须被重写)。所以属性都是final变量,不能改变。

Eg:publicinterface Runner{

public staticfinal int id=10;

public void start();

public void run();

public void stop();

}

4、类可以实现接口,实现使用关键字implements,代表某个类实现了某个接口。

5、如果某个类实现了一个接口,并且这个类不是抽象类,那么这个类必须实现这个接口中所有的方法(接口里都是抽象方法)。如果这个类是抽象类,那么就无需实现接口中的方法了。

6、Java是单继承的,也就是说一个某一个类只能有唯一的一个父类。但一个类可以实现多个接口,多个接口间使用逗号分隔。

Eg :Class A implementsB1,B2{}

7、某一个类可以同时继承一个类和实现多个接口(多重实现),多个无关的类可以实现同一个接口。接口和实现类之间存在多态性

Eg:Class A extends B implements C1,C2

8、接口中所声明的方法都是抽象方法,接口中的方法都是public的。

9、接口中也可以定义声明属性,但是必须初始化。接口中的属性都是也只能是public、final、static的。都是常量(避免实现的多个接口之间的相同成员变量)

例如:class interface Interface{

public final static int=3;

}

10、不能通过new来生成接口的对象的实例。

11、接口还可以继承其他的接口,并添加新的属性和抽象方法。

12、类和类之间、接口和接口之间可以互相继承,而类和接口之间只能实现。

13、接口可以多重继承:即

interface A{

public void printA();

}

interface B{

public void printB();

}

interface C extends A,B{

public void printC();

}

例如:

public interface Singer

{

public void sing();//定义一个唱歌的方法,能唱歌的东西,具体怎么唱不知道,人有人的唱法,动物有动物的唱法。

public void sleeping();

}

class Student implements Singer{

//实现接口,必须实现其中所有的方法。

public void sing()

{

}

public void sleeping()

{

}

}

代码详解:

public classimplementszzj {

/**

* 接口的定义:由于c++有多继承,java只能单继承, 所以增加了接口来实现多继承 接口是一种特殊的抽象类, 也就是final类。

* 这种抽象类中,只包含常量,也就是final定义的静态static变量和方法定义,

* 也就是只有定义函数,不在里面写实现的内容在抽象类中定义常量的好处是, 由于该量只能存放到data segment静态字符常量保存地方,

* 不放在变量栈内存和类方法的堆内存中,所以,避免了c++中, 多继承的时候, 定义的变量名一样,导致调用困难。data segment好处,

* 也就是不管多少个相同的定义名,在里面都默认为一个。 好了复习下四大存放区域: heap 定义new方法的资料存放地 stack 局部变量

* 主函数变量存放地 data segment 静态变量字符常量存放地code segment 代码存放

*

*@param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

s1 ss1 = new set1("set1的名字");

ss1.ss1();

ss1.ss2(); // 注意,接口类只能调用自己的接口方法

s2 ss2 = new set2(12);

ss2.sss1();

ss2.sss2();

// //

// 由于set包含了set1和set2。所以s1只能访问s1,s2只能访问s2;

// 表明每一个接口对应自己的方法。所以用什么接口在set3上,就调用该接口方法

// s1 ss3=new set3();

s2 ss3 = new set3();

ss3.sss1();

}

}

// 定义了s1的接口以及方法

interface s1 {

public void ss1();

public void ss2();

}

// 定义了接口的实现过程,注意,定义接口必须要对应实现过程

class set1implements s1 {

private String name;

set1(final String name) {

this.name = name;

System.out.println("定义构造方法来传递姓名");

}

public void sett1() {

System.out.println("这个是自己定义 的方法");

}

public void ss1() {

//TODO Auto-generated method stub

System.out.println("这个是接口ss1的实现过程");

}

public void ss2() {

// TODO Auto-generated method stub

System.out.println("这个是接口ss2的实现过程");

}

}

// 定义了s2的接口以及方法

interface s2 {

public void sss1();

public void sss2();

}

// 定义了接口的实现过程,注意,定义接口必须要对应实现过程

class set2implements s2 {

private int age;

set2(final int age) {

this.age = age;

System.out.println("定义构造方法来传递年龄");

}

public void sss1() {

// TODO Auto-generated method stub

System.out.println("这个是接口sss1的实现过程");

}

public void sss2() {

// TODO Auto-generated method stub

System.out.println("这个是接口sss2的实现过程");

}

}

// 定义了多个接口的实现过程,注意,定义接口必须要对应实现过程

class set3 implements s1, s2 {

public void ss1() {

// TODO Auto-generated method stub

System.out.println("这个是接口ss1的实现过程");

}

public void ss2() {

// TODO Auto-generated method stub

System.out.println("这个是接口ss2的实现过程");

}

public void sss1() {

// TODO Auto-generated method stub

System.out.println("这个是接口sss1的实现过程");

}

public void sss2() {

// TODO Auto-generated method stub

System.out.println("这个是接口sss2的实现过程");

}

}

//定义一个类并且 定义了一个方法并实现

class set4 {

void sett() {

System.out.println("这个是set4的方法");

}

}

//定义一个类并且继承了 set4的类和 继承了 s1 s2的接口

class set5 extendsset4 implements s1, s2 {

//定义接口必须要对应实现过程

public void ss1() {

// TODO Auto-generated method stub

}

public void ss2() {

// TODO Auto-generated method stub

}

public void sss1() {

// TODO Auto-generated method stub

}

public void sss2() {

// TODO Auto-generated method stub

}

}

//定义了一个类,继承了set2的类,由于里面有自己定义的构造方法,所以

//继承下来必须也重写自己的构造方法并且通过super方法来传递给父类set2

class set6 extendsset2

{

set6(int age) {

super(age);

// TODO Auto-generated constructorstub

}

}

class set7 extendsset1

{

set7(String name) {

super(name);

// TODO Auto-generated constructorstub

}

}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics