接口中的內部類
??在我們實際開發(fā)過程中,如果想要創(chuàng)建某些公共代碼,使得他們可以被某個接口的所有不同實現(xiàn)所共用,那么接口內部的嵌套類會顯得很方便.也就是說在接口中可以含有內部類.在這里,向大家展示接口中放置普通成員內部類和抽象成員內部類的情況.
?
1.首先創(chuàng)建接口,接口中定義了普通內部類InnerClass和抽象內部類AbInnerClass
package com.diandian.inter;
// 接口IOuterInterface
public interface IOuterInterface{
int TEMP = 100; // 常量
void abMethod();// 抽象方法
public default void deMethod(){ // jdk1.8后可添加
System.out.println("接口中默認方法");
}
public static void stMethod() {
System.out.println("接口中靜態(tài)方法");
}
// 普通內部類
public class InnerClass{
public void show(){
System.out.println("接口中可定義普通成員內部類");
}
}
// 抽象內部類
public abstract class AbInnerClass{
public abstract void abInfo();
public void info(){
System.out.println("接口中可定義抽象成員內部類");
}
}
}
2.普通成員內部類的實例化
// 創(chuàng)建接口的實現(xiàn)類ClassDemo
package com.diandian.inter;
// 實現(xiàn)類ClassDemo
public class ClassDemo implements IOuterInterface{
@Override
public void abMethod(){
System.out.println("實現(xiàn)類");
}
// 獲取接口中內部類方法
public InnerClass getInner(){
return new InnerClass();
}
}
// 獲取普通內部類對象,調用方法
package com.diandian.test;
import com.diandian.inter.ClassDemo;
import com.diandian.inter.IOuterInterface;
import.com.diandian.inter.IOuterInterface.InnerClass;
// 測試類:普通成員內部類
public class Test{
public static void main(String[] args){
/**第一種實例化對象方式:
通過接口名.類名 進行實例化
*/
IOuterInterface.InnerClass inner = new IOuterInterface.InnerClass();
inner.show();
/**第二種實例化對象方式:
通過在實現(xiàn)類中創(chuàng)建接口中內部類獲取方法
用實現(xiàn)對象調用獲取方法
*/
ClassDemo demo = new ClassDemo();
demo.getInner().show();
/**第三種實例化對象方式:
將內部類導入后,直接實例化
*/
InnerClass innerTwo = new InnerClass();
innerTwo.show();
}
}
運行結果:
接口中可定義普通成員內部類
接口中可定義普通成員內部類
接口中可定義普通成員內部類
3.抽象成員內部類的實例化
// 創(chuàng)建接口的實現(xiàn)類AbClassDemo
package com.diandian.inter;
// 實現(xiàn)類AbClassDemo
public class AbClassDemo implements IOuterInterface{
@Override
public void abMethod(){
}
// 繼承抽象類AbInnerClass
public class AbDemo extends AbInnerClass{
@Override
public void abInfo(){
System.out.println("重寫接口中抽象內部類中的抽象方法");
}
}
}
獲取抽象內部類對象,調用方法
package com.diandian.test;
import com.diandian.inter.AbClassDemo;
import com.diandian.inter.IOuterInterface;
// 測試類:抽象成員內部類
public class TestOne{
public static void main(String[] args){
/*第一種實例化對象方式:
通過接口名.類名 進行實例化
但是對于抽象類而言,不能直接實例化,所以這里可使用匿名內部類的方式
*/
IOuterInterface.AbInnerClass abInner = new IOuterInterface.AbInnerClass(){
public void abInfo(){
System.out.println("重寫抽象類中的抽象方法");
}
};
abInner.abInfo();
abInner.info();
System.out.println("=====================");
/*第二種實例化方法:
在實現(xiàn)類中定義內部類繼承接口中的抽象內部類
*/
IOuterInterface.AbInnerClass abInnerOne = new AbClassDemo().new AbDemo();
abInnerOne.abInfo();
abInnerOne.info();
}
}
運行結果:
重寫抽象類中的抽象方法
接口中可定義抽象成員內部類
========================
重寫接口中抽象類中的抽象方法
接口中可以定義抽象成員內部類
匿名內部類
概念
匿名內部類也及時沒有名字的內部類
正因為沒有名字,所以匿名內部類只能使用一次,它通常用來簡化代碼編寫但使用匿名內部類還有個前提條件:必須繼承一個父類或者一個接口
注意事項:
- 編譯后的文件名:外部類$數(shù)字.class
- 無法使用publick,private,abstract,static修飾,匿名內部類不能出現(xiàn)抽象方法
- 無法編寫構造方法,但可以添加構造代碼塊
- 不能出現(xiàn)靜態(tài)成員
- 匿名內部類可實現(xiàn)接口也可以繼承類,但是不可兼得
- 匿名內部類不能是抽象類的,它必須要實現(xiàn)繼承的類或者實現(xiàn)接口的所有抽象方法
?
匿名內部類初始化
??我們一般都是利用構造器來完成某個實例的初始化工作,但是匿名內部類是沒有構造器的,那怎么來初始化匿名內部類呢?使用構造代碼塊!利用構造代碼塊能夠達到為匿名內部類創(chuàng)建一個構造器的效果.
實例:
先定義一個接口,然后定義該接口的匿名內部類.
public interface InnerClass{
public String getName();
public int getAge();
}
public class OutClass{
public InnerClass getInnerClass(final int age,final String name){
return new InnerClass(){
int age_;
String name_;
// 構造代碼塊完成初始化工作
{
if(0 < age && age < 200){
age_ = age;
name_ = name;
}
}
public String getName(){
return age_;
}
};
}
public static void main(String[] args){
OutClass out = new OutClass();
InnerClass inner_1 = out.getInnerClass(201,"chenssy");
System.out.println(inner_1.getName());
InnerClass inner_2 = out.getInnerClass(23,"chenssy");
System.out.println(inner_2.getName());
}
}
實例
匿名內部類可以有不同的表現(xiàn)形式,下面用實例向大家展示一下:
繼承式的匿名內部類:
abstract class Car{
public abstract void drive();
}
class Test{
public static void main(String[] args){
Car car = new Car(){
public void drive(){
System.out.println("Driving another car!");
}
};
car.drive();
}
}
輸出結果:
Driving another Car!
引用變量不是應用Car對象,而是Car匿名子類的對象
??建立匿名內部類的關鍵點事重寫父類的一個或多個方法.再強調一下,是重寫的方法,而不是創(chuàng)建新的方法.因為用父類的引用不可能調用父類本身沒有的方法,創(chuàng)建新的方法時多余的.
?
接口式的匿名內部類:
interface Vehicle{
public void drive();
}
class Test{
public static void main(String[] args){
Vehicle vehicle = new Vehicle(){
public void drive(){
System.out.println("Driving a car!");
}
}
vehicle.drive();
}
}
輸出結果:
Driving a car!
上面的代碼很怪,好像是在實例化一個接口.事實并非如此,接口式的匿名內部類是實現(xiàn)了一個接口的匿名類.而且只能實現(xiàn)一個接口.
//參數(shù)是的匿名內部類:
abstract class Bar{
void doStuff(Foo f){}
}
class BarOne extends Bar{
void doStuff(Foo f){}
}
interface Foo{
void foo();
}
class Test{
static void go(){
Bar b = new BarOne();
b.doStuff(new Foo(){
public void foo(){
System.out.println("foofy");
}
})
}
}
?由上面的三個例子可以看出,只要一個類是抽象的或是一個接口,那么其子類中的方法都可以使用匿名內部類來實現(xiàn).最常用的情況就是多線程的實現(xiàn)上,因為要實現(xiàn)多線程必須繼承Thread類或是實現(xiàn)Runnable接口
Thread類的匿名內部類實現(xiàn):
public class Demo{
public static void main(String[] args){
Thread t = new Thread(){
public void run(){
for(int i = 1; i <= 5; i++){
System.out.print(i +" ");
}
}
};
t.start();
}
}
Runnable接口的匿名內部類實現(xiàn):
public class Demo{
public static void main(String[] args){
Runnable r = new Runnable(){
public void run(){
for(int i = 1; i <= 5; i++){
System.out.print(i + " ");
}
}
};
Thread t = new Thread(r);
t.start();
}
}