内部类
Java中的类有两种重要的成员,即成员变量和方法。其实Java还允许类有一种成员,即在一个类中声明另一个类,这就是内部类,而包含内部类的类叫做外嵌类。
内部类和外嵌类之间的关系如下:
1.内部类可以使用其外嵌类的成员变量和方法。
2.内部类中不可以声明类变量和类方法。
3.外嵌类可以使用内部类声明对象作为外嵌类的成员。
4.内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象。
具体示例:
class RedCowFarm{ //外嵌类
static String farmName;
class RedCow{ //内部类开始
String cowName="红牛";
int height,weight;
RedCow(int h,int w){
height=h;
weight=w;
}
void speak(){
System.out.println("我是"+cowName+",身高:"+height+"cm,体重:"+weight+"kg,生活在"+farmName);
}
} // 内部类结束
RedCow cow=new RedCow(150,112);
RedCowFarm(String s){
farmName=s;
}
}
public class Test {
public static void main(String[] args) {
RedCowFarm redCowFarm=new RedCowFarm("红牛农场");
redCowFarm.cow.speak();
}
}
内部类可以被修饰为static内部类,即上面的示例中可以将内部类声明为static class RedCow,类是一种数据类型,那么static内部类就是外嵌类中的一种静态数据类型,这样其它类就可以使用static内部类来声明创建对象了。
注意:static内部类不能操作外嵌类中的实例成员变量。
假如上面示例中内部类是static class RedCow的话,则可以作如下变动:
1.删除掉外嵌类的 RedCow cow=new RedCow(150,112); 对象声明和创建;
删除掉Test类main方法中的redCowFarm.cow.speak();
2.直接在Test类的main方法中添加以下代码也可以达到同样的运行效果:
RedCowFarm.RedCow redCow=new RedCowFarm.RedCow(150,112);
redCow.speak();
匿名类
一、和类有关的匿名类
1.我们可以直接使用一个类的子类的类体创建一个对象。在创建子类对象时,使用的是父类的构造方法和类体,这个类体被认为是子类去掉类声明之后的类体,称作匿名类。
2.匿名类主要是为了实现,要执行的任务或者方法需要一个对象,但是又不值得创建一个全新的对象。
3.匿名类可以继承,重写父类的方法,使用匿名类的时候,必然是在某个类当中直接使用匿名类创建对象,因此,匿名类一定是内部类。
4.由于匿名类是一个子类,但是没有类名,所以在使用匿名类创建对象时必须使用父类的构造方法。
5.匿名对象的引用可以传递给一个匹配的参数,匿名类常用的方式是向方法的参数传值。
具体示例:
abstract class Speak{
public abstract void speakHello();
}
class Student {
void f(Speak sp){
sp.speakHello();
}
}
public class Test {
public static void main(String[] args) {
Speak speak;
speak=new Speak() { //使用匿名类创建匿名对象,并且将匿名对象的引用传给父类声明的对象speak,可以理解为对象的上转型
@Override
public void speakHello() {
System.out.println("嗨喽");
}
};
speak.speakHello();
Student student=new Student();
student.f(new Speak() { //使用匿名类创建匿名对象,并且将匿名对象的引用传递给匹配的参数
@Override
public void speakHello() {
System.out.println("hello");
}
});
}
}
二、和接口有关的匿名类
1.我们可以直接使用接口名和一个类体创建一个匿名对象,这个类体被称为是实现了这个接口的类去掉类声明后的类体,称为匿名类。
2.如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给这个方法的参数,但类体必须重写接口中的所有方法。
具体示例:
interface Cubic{
double getCubic(double x);
}
class A{
void f(Cubic cu){
double result=cu.getCubic(3);
System.out.println("result="+result);
}
}
public class Test {
public static void main(String[] args) {
Cubic cubic=new Cubic() { //使用实现了接口的匿名类创建匿名对象,并且将对象的引用赋值给接口变量。
@Override
public double getCubic(double x) {
return x*x*x;
}
};
System.out.println(cubic.getCubic(5)); // 接口回调
A a=new A();
a.f(new Cubic() { //使用实现了接口的匿名类创建匿名对象,并且将对象的引用传递给匹配的参数
@Override
public double getCubic(double x) {
return x*x*x;
}
});
}
}