匿名内部类
程序引例
/*
匿名内部类:
就是内部类的一个简化写法。
存在匿名内部类的前提:
要存在一个类或者是一个接口,类可以是具体的类也可以是抽象类
定义格式:
new 类名或者接口名(){重写方法};
本质上:
是一个继承了这个类或者实现了这个接口的子类匿名对象
//接口A
interface A{
b();
c();
}
//类B实现接口A
class B implements A{
b(){..}
c(){..}
}
//接口多态
A a = new B();
//匿名内部类
A a = new A(){
b(){..}
c(){..}
};
*/
interface Inter{
public abstract void show();
public abstract void show2();
}
class Outer7{
public void fun(){
new Inter(){
@Override
public void show() {
System.out.println("这是第一个匿名内部类的show方法");
}
@Override
public void show2() {
System.out.println("这是第一个匿名内部类的show2方法");
}
}.show();
new Inter(){
@Override
public void show() {
System.out.println("这是第二个匿名内部类的show方法");
}
@Override
public void show2() {
System.out.println("这是第二个匿名内部类的show2方法");
}
}.show2();
//想一想,如果接口中的方法很多的时候,每次调用一个方法,
//都需要new一下,要写的内容都重复了。怎么改进?
System.out.println("====================================");
//多态的形式,这里叫做接口多态//因为 new Inter(){...}相当于一个实现接口的类的对象
//把这个对象用Inter类型的变量i接收一下,这样多次调用方法就不用重复的去写了
Inter i = new Inter(){
@Override
public void show() {
System.out.println("这是第二个匿名内部类的show方法");
}
@Override
public void show2() {
System.out.println("这是第二个匿名内部类的show2方法");
}
};
i.show();
i.show2();
}
}
public class InnerClassDemo7 {
public static void main(String[] args) {
Outer7 outer7 = new Outer7();
outer7.fun();
}
}
匿名内部类在开发中的使用
程序示例
/*
匿名内部类在开发中的使用
*/
interface Person{
public abstract void study();
}
class PersonDemo{
//定义一个接口类型的成员变量
Person person;
//当我把下方的方法注释掉改用有参构造方法,实现让接口作为方法的参数传递
//需要传入的是实现该接口的类的对象的地址值
PersonDemo(Person person){
this.person = person;
}
//当接口作为方法的参数的时候,实际上需要的是实现该接口的类的对象
// public void fun(Person person){
// person.study();
// }
}
//以前的方式,创建一个类实现接口
class Student implements Person{
@Override
public void study() {
System.out.println("好好学习天天向上");
}
}
public class InnerClassDemo8 {
public static void main(String[] args) {
//以前的方式,先创建PersonDemo类的对象
//然后再创建Student对象
// PersonDemo pd = new PersonDemo();
// Student student = new Student();
//再把Student对象当作参数传递
// pd.fun(student);
//或者直接匿名对象
// pd.fun(new Student());
//使用匿名内部类的形式//好处:省略了创建一个类实现接口的步骤
// pd.fun(new Person() {
// @Override
// public void study() {
// System.out.println("好好学习匿名内部类");
// }
// });
//当我把fun()方法注释掉后,用PersonDemo的有参构造方法创建对象实现让接口作为方法的参数传递
//此时需要的是实现该接口的类的对象
// PersonDemo personDemo = new PersonDemo(new Student());
//使用匿名内部类的形式创建对象
PersonDemo pd = new PersonDemo(new Person() {
@Override
public void study() {
System.out.println("好好学习使用匿名内部类创建对象");
}
});
//pd.person是实现了该接口的类的对象的地址值
Person person = pd.person;
//调用实现了该接口的类的对象的study()方法
person.study();
//上面的写法还可以改成:
// new PersonDemo(new Person() {
// @Override
// public void study() {
// System.out.println("好好学习使用匿名内部类创建对象");
// }
// }).person.study();
}
}
匿名内部类面试题
/*
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
分析:
1、method()方法可以通过类名直接调用➡说明method()方法是静态的
2、调用完method()方法之后又可以去 .show() 方法,而show()方法恰好是接口Inter中的方法
➡说明method()方法是有返回值的,而且返回值类型是Inter类型
*/
interface Inter2 {
void show();
}
class Outer8 {
//1、推出第一个结论:method方法是静态的
//2、推出第二个结论:由于main方法中调用完method方法之后还能继续调用方法
//所以得出method方法是有返回值的,由于show方法恰好是接口Inter2中的方法,所以返回值类型
//是接口Inter2类型
public static Inter2 method(){
//使用匿名内部类的形式
return new Inter2() {
@Override
public void show() {
System.out.println("HelloWorld");
}
};
}
}
public class InnerClassDemo9 {
public static void main(String[] args) {
Outer8.method().show();
}
}