接口中的内部类
在我们实际开发过程中,如果想要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用,那么接口内部的嵌套类会显得很方便.也就是说在接口中可以含有内部类.在这里,向大家展示接口中放置普通成员内部类和抽象成员内部类的情况.
1.首先创建接口,接口中定义了普通内部类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("接口中静态方法");
}
// 普通内部类
public class InnerClass{
public void show(){
System.out.println("接口中可定义普通成员内部类");
}
}
// 抽象内部类
public abstract class AbInnerClass{
public abstract void abInfo();
public void info(){
System.out.println("接口中可定义抽象成员内部类");
}
}
}
2.普通成员内部类的实例化
// 创建接口的实现类ClassDemo
package com.diandian.inter;
// 实现类ClassDemo
public class ClassDemo implements IOuterInterface{
@Override
public void abMethod(){
System.out.println("实现类");
}
// 获取接口中内部类方法
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();
/**第二种实例化对象方式:
通过在实现类中创建接口中内部类获取方法
用实现对象调用获取方法
*/
ClassDemo demo = new ClassDemo();
demo.getInner().show();
/**第三种实例化对象方式:
将内部类导入后,直接实例化
*/
InnerClass innerTwo = new InnerClass();
innerTwo.show();
}
}
运行结果:
接口中可定义普通成员内部类
接口中可定义普通成员内部类
接口中可定义普通成员内部类
3.抽象成员内部类的实例化
// 创建接口的实现类AbClassDemo
package com.diandian.inter;
// 实现类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("=====================");
/*第二种实例化方法:
在实现类中定义内部类继承接口中的抽象内部类
*/
IOuterInterface.AbInnerClass abInnerOne = new AbClassDemo().new AbDemo();
abInnerOne.abInfo();
abInnerOne.info();
}
}
运行结果:
重写抽象类中的抽象方法
接口中可定义抽象成员内部类
========================
重写接口中抽象类中的抽象方法
接口中可以定义抽象成员内部类
匿名内部类
概念
匿名内部类也及时没有名字的内部类
正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写但使用匿名内部类还有个前提条件:必须继承一个父类或者一个接口
注意事项:
- 编译后的文件名:外部类$数字.class
- 无法使用publick,private,abstract,static修饰,匿名内部类不能出现抽象方法
- 无法编写构造方法,但可以添加构造代码块
- 不能出现静态成员
- 匿名内部类可实现接口也可以继承类,但是不可兼得
- 匿名内部类不能是抽象类的,它必须要实现继承的类或者实现接口的所有抽象方法
匿名内部类初始化
我们一般都是利用构造器来完成某个实例的初始化工作,但是匿名内部类是没有构造器的,那怎么来初始化匿名内部类呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果.
实例:
先定义一个接口,然后定义该接口的匿名内部类.
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());
}
}
实例
匿名内部类可以有不同的表现形式,下面用实例向大家展示一下:
继承式的匿名内部类:
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匿名子类的对象
建立匿名内部类的关键点事重写父类的一个或多个方法.再强调一下,是重写的方法,而不是创建新的方法.因为用父类的引用不可能调用父类本身没有的方法,创建新的方法时多余的.
接口式的匿名内部类:
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!
上面的代码很怪,好像是在实例化一个接口.事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类.而且只能实现一个接口.
//参数是的匿名内部类:
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");
}
})
}
}
由上面的三个例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现.最常用的情况就是多线程的实现上,因为要实现多线程必须继承Thread类或是实现Runnable接口
Thread类的匿名内部类实现:
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接口的匿名内部类实现:
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();
}
}