接口,内部类
1.接口的概念
接口是一种引用数据类型,使用interface声明接口
定义接口:public interface 接口名称{ }
2.接口的特性
1)接口声明属性。——接口中定义的变量都是静态常量,用static final 修饰,这种声明方式不常用。
1 publicinterfaceMyInterface { 2 publicstaticfinal String version = "1.0"; 3 publicintcount = 10; // 默认是static final类型 4 }
2)接口声明方法。——接口中的方法都是公共抽象方法,方法没有方法体。
1 publicinterfaceMyInterface { 2 publicabstractvoidshowInfo(); 3 void showInfo3(); 4 5 // 推荐写法 6 publicvoidshowInfo2(); 7 }
3)接口不能拥有构造方法,不能用于创建对象
4)接口可以多继承。一个接口可以继承多个其他接口
5)一个类可以实现一个或者多个接口,该类称为接口的实现类(implement class).
实现类必须实现接口中的所有(抽象)方法, 实现类 implements 接口
1 publicclassImplClassAimplementsAInterface,BInterface{ 2 3 @Override 4 publicvoidshowInfoA() { 5 System.out.println("实现接口中的showInfoA"); 6 } 7 8 @Override 9 publicvoidshowInfoB() { 10 System.out.println("实现接口中的showInfoB"); 11 } 12 }
注:一个类只能继承一个父类,但可以同时实现多个接口。继承写在前,接口在后。如下
1 publicclass ImplClass3 extendsAbsClassimplementsAInterface,BInterface{ 2 3 @Override 4 publicvoidshowInfoA() { 5 // TODO Auto-generated method stub 6 7 } 8 9 @Override 10 publicvoidshowInfoB() { 11 // TODO Auto-generated method stub 12 13 } 14 15 @Override 16 publicvoidshowInfoC() { 17 // TODO Auto-generated method stub 18 19 } 20 21 }
如果一个抽象父类定义了一个和接口同名的抽象方法,实现类实现的是抽象父类的抽象方法。
1 packagecn.interface02; 2 3 publicclassImplClass4extendsAbsClassimplementsCInterface{ 4 5 @Override 6 publicvoidshowInfoA() { 7 // TODO Auto-generated method stub 8 9 } 10 11 @Override 12 publicvoidshowInfoB() { 13 // TODO Auto-generated method stub 14 15 } 16 17 @Override 18 publicvoidshowInfoC() { 19 // TODO Auto-generated method stub 20 21 } 22 23 }
总结:实现类实现接口必须实现接口定义的所有抽象方法。
方法也可以为行为,表示一种能力,实现了方法,就说明得到了一种能力,
也就说明了实现类的能力得到了拓展
3.接口的应用
1)接口表示一种能力
接口中的抽象方法即一种种的能力,实现了方法就相当于实现类的能力得到了拓展和升级。
实现类会根据自身的特性来实现接口中的抽象方法
如:
实现类Student具备了驾驶能力,实现类Teacher也具备了驾驶能力,
原因是都实现了DriveInterface,两个实现类的能力得到了增强。
2)接口实现多态
1 packagecn.sxt.interface4; 2 3 publicclass Test01 { 4 publicstaticvoid main(String[] args) { 5 6 // 同一引用类型 7 USBInterfaceusbInterface = null; 8 9 // 实例不同 10 usbInterface = newUSBFan(); 11 // 对同一方法的执行结果不同 12 usbInterface.connect(); 13 14 usbInterface = newUSBMouse(); 15 usbInterface.connect(); 16 17 usbInterface = newUSBDisk(); 18 usbInterface.connect(); 19 } 20 }
比较:
接口实现多态:接口类型引用实现类对象
继承实现多态:父类类型引用子类对象
接口定义的方法被实现类实现,通过接口引用实现类时,调用接口中的方法时,执行的是实现类实现的方法。(接口不能声明对象)
实现类对象具备接口中定义的能力是一种has a 关系;子类对象是一种父类类型是一种is a 关系
4.面向接口编程
定义: 接口表示一种约定(协议),约定(规范)了实现类应该具备(has a)的能力。
理解:
实现类必须实现接口中所有的方法,所以接口规范了实现类的行为
接口约定了实现类应该具备的行为。
面向接口编程:
所谓面向接口编程,在程序设计时,只关心实现类具备什么能力,而不关心实现类如何实现这个能力。面向接口编程时,面向接口的约定而不考虑接口的具体实现。
也就是说,面向接口编程时,接口的定义方只关系实现类是否具备接口所定义的能力,而实现类如何被的该能力接口定义方一点都不关心。
1 packagecn.sxt.interface06; 2 3 publicclass Writer { 4 5 // 预留墨盒接口 6 privateInkBoxInterfaceinkBoxInterface; 7 8 // 预留纸张接口 9 privatePaperInterfacepaperInterface; 10 11 publicInkBoxInterfacegetInkBoxInterface() { 12 returninkBoxInterface; 13 } 14 15 publicvoidsetInkBoxInterface(InkBoxInterfaceinkBoxInterface) { 16 this.inkBoxInterface = inkBoxInterface; 17 } 18 19 publicPaperInterfacegetPaperInterface() { 20 returnpaperInterface; 21 } 22 23 publicvoidsetPaperInterface(PaperInterfacepaperInterface) { 24 this.paperInterface = paperInterface; 25 } 26 27 publicWriter(InkBoxInterfaceinkBoxInterface, PaperInterfacepaperInterface) { 28 super(); 29 this.inkBoxInterface = inkBoxInterface; 30 this.paperInterface = paperInterface; 31 } 32 33 publicWriter() { 34 super(); 35 } 36 37 publicvoidprint(String content) { 38 System.out.println("打印机正在使用"+this.inkBoxInterface.getColor()+"颜色打印"+this.paperInterface.getSize()+"打印"+content); 39 } 40 }
5.接口和抽象类的异同
—抽象类和接口都是引用数据类型,所以他们都不能创建对象。
—他们都可以定义抽象方法,并且可以实现多态,抽象类可以定义非抽象类方法,但接口只能定义抽象方法。
—他们都具有传递性。抽象类是单根性(继承觉定),接口是多继承的。
—他们都可以重写抽象方法。子类重写抽象类,实现类实现接口。
—抽象类和子类解决的是模块内的问题(代码重用,重写,多态)而接口解决的是模块间的问题 =>高内聚,低耦合。接口可以用解耦模块。
6.object
定义:object是所有类的父类,即是所有类的根类。
得知:如果一个类没有继承另外一个类,那么他就继承于object,是object的子类。
object的常规用法:
1)toString() 返回对象的字符串表示形式
1 publicclass Test01 { 2 publicstaticvoid main(String[] args) { 3 Object obj = newObject(); 4 // 输出对象时,默认调用toString方法 5 System.out.println(obj); 6 // 类型@内存地址 7 System.out.println(obj.toString()); 8 9 10 Student s1 = new Student("二狗",20); 11 System.out.println(s1); 12 } 13 }
可以再软件的代码生成器快速生成toString方法。
2)equals(Object obj) 用于判断两个对象是否相等。
== 比较两个对象的内存地址是否相等或者判断基本数据类型,object默认equals实现比较内存地址。
如果两个对象的地址不同,那么判断两个对象的属性是否相等。
equals:用于比较两个对象的内容(属性)是否相等。
当自定义对象时,要比较自定义对象是否相等,就必须通过equals方法比较两个对象属性值是否相等,那就必须重写Object的equals方法。(
1 publicbooleanequals(Object obj) { 2 if(this == obj) { 3 returntrue; 4 } 5 6 Student s = (Student) obj; 7 if(this.sid.equals(s.sid) &&this.name.equals(s.name) &&this.age == s.age) { 8 returntrue; 9 }else { 10 returnfalse; 11 } 12 }
软件中的快捷方式如下:
7.内部类
1)内部类的定义:
在java中,一个文件可以定义多个类,文件名必须和public 类型的类的类名保持一致。这两个类是平行关系。
在java中,一个类也可以定义在一个类的内部,定义在内部的类称为内部类(inner class),定义在外部的类称为外部类(out class).
内部类,外部类如下:
1 public class Outer { 2 3 [修饰符] class Inner{ 4 5 } 6 }
编译后的结果(外部类和内部类是平行关系,运行时就不是平行关系,外部类属于内部类的成员)
内部类根据具体的修饰符和具体位置分为很多情况。
2)内部类成员
一个内部类作为一个外部类的成员而存在,此时该内部类称为外部类的成员内部类。
publicclass Outer { classInner{ //内部类一般使用默认修饰符 } }
[1].内部类如何创建对象
1 publicclass Test01 { 2 publicstaticvoid main(String[] args) { 3 4 // 【1】创建外部类对象 5 Outer outer = newOuter(); 6 // 【2】创建内部类对象 7 Inner inner = outer.newInner(); 8 inner.showInfo(); 9 } 10 }
[2].内部类中可以访问外部类的私有变量(作用域可以解释)
1 public class Outer { 2 3 private String name = "Outer"; 4 5 classInner{ 6 7 public void showInfo() { 8 System.out.println(name); 9 } 10 11 } 12 }
特殊情况:外部类和内部类的变量同名
publicclass Outer { private String name = "Outer"; classInner{ private String name = "Inner"; publicvoidshowInfo() { // String name = "show info"; // 访问内部类的私有成员 System.out.println(this.name); // 访问外部类的私有成员 System.out.println(Outer.this.name); } } }
8.方法内部类
如果一个类定义到一个方法中,那么这个类是方法内部类
代码形式:
1 public class Outer { 2 3 4 public void print() { 5 6 class Inner{ 7 8 public void showInfo() { 9 System.out.println("show info"); 10 } 11 } 12 13 Inner inner = new Inner(); 14 inner.showInfo(); 15 } 16 }
方法的局部变量被方法内部类使用时,这个变量要被final修饰,但出了这个内部类后,final被去掉。
public class Outer { public voidprint(int b) { int a = 10; class Inner{ public void showInfo() { System.out.println("show info"); System.out.println("print()->a:"+10); // 在方法内部类中不能修改方法的局部变量(final) // a = 20; // b = 20; } } a = 20; Inner inner = new Inner(); inner.showInfo(); } }
9.匿名内部类
1).概念:如果一个类只使用一次,那么他可以声明为匿名类,匿名类多与内部类结合使用,形成匿名内部类。
注:匿名内部类一定要实现 /重写,一般是用于实现接口
1 packagecn.sxt01.inner04; 2 3 public class Outer { 4 5 public void print() { 6 7 // 方法内部类 8 /*class Inner implements MyInterface{ 9 10 @Override 11 public void showInfo() { 12 System.out.println("Inner:showInfo"); 13 } 14 15 }*/ 16 17 /*Inner inner = new Inner(); 18 inner.showInfo();*/ 19 20 // new Inner().showInfo(); 21 22 23 24 //匿名内部类变化前 25 class Inner implements Interface(){ 26 public void showInfo(){ 27 System.out.println("Inner:showInfo"); 28 } 29 } 30 new Inner().showInfo(); 31 // 匿名内部类(变化后) 32 new MyInterface(){ 33 publicvoidshowInfo() { 34 System.out.println("Inner:showInfo"); 35 } 36 }.showInfo(); 37 38 } 39 } 40